diff --git a/AUTHORS b/AUTHORS index 6489b6a..2af459b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1 @@ -Elias Löwe +Ilja Kartaschoff diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 6a40d7a..0000000 --- a/LICENSE +++ /dev/null @@ -1,2 +0,0 @@ -# Lion's Share License -> LSL -# Löwenware Software Distribution -> LSD diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..116f49b --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,39 @@ +# License + +Leos (the "Software") is an intellectual property of Löwenware s.r.o. +distributed under terms of [Attribution-NoDerivatives 4.0 International](https://creativecommons.org/licenses/by-nd/4.0/legalcode) +**(CC BY-ND 4.0)** license. + +## Highlights + +Information below highlights only key features and terms of the +[license](https://creativecommons.org/licenses/by-nd/4.0/legalcode). It is +recommended to read its full text before using licensed Software. + +### You are free to: + +**Share** — copy and redistribute the Software in any medium or format +for any purpose, even commercially. The licensor cannot revoke these freedoms +as long as you follow the license terms. + + +### Under the following terms: +**Attribution** — You must give appropriate credit, provide a link to the license, +and indicate if changes were made. You may do so in any reasonable manner, but +not in any way that suggests the licensor endorses you or your use. + +**NoDerivatives** — If you remix, transform, or build upon the Software, you may +not distribute the modified material. + +**No additional restrictions** — You may not apply legal terms or technological +measures that legally restrict others from doing anything the license permits. + +### Disclaimer +The Software is provided "AS IS" without warranty of any kind. In no +event shall the authors or copyright holders be liable for any claim, damages +or other liability, whether out of or in connection with the Software or its +usage. + +The license may not give you all of the permissions necessary for your +intended use. For example, other rights such as publicity, privacy, +or moral rights may limit how you use the material. diff --git a/README.md b/README.md index b262918..392c555 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,88 @@ -# Löwe OS -Operating System for ARMv8 (aarch64) architecture. +# Leos +Operating System for ARMv8 (aarch64) Architecture +* [The Idea](#The Idea) +* [Hardware](#Hardware) +* [Documentation](#Documentation) +* [Compilation](#Compilation) +* [Run](#Run) +* [Debug](#Debug) +* [Roadmap](#Roadmap) +* [Contribution](#Contribution) + +--- + +## The Idea + +Löwe OS is being developed to be a lightweight desktop operating system for +ARM-based computers, tablets, mobile phones etc. Here are some concepts behind +it: + +1. The OS is free with open source codes, distributed under terms of [CC BY-ND 4.0](LICENSE.md). +2. The OS will have POSIX-compliant API. +3. The OS will include graphical system, shell and generic utilities as a part +of it, being designed to work as a solid product. +4. The OS will respect user's privacy and will not track his/her actions and data. +5. The OS will stive to be secure and robust. + +## Hardware + +Early development is going for **Raspberry PI3** board and its emulation using +**QEMU**. + +## Documentation + +* [Project structure](docs/project-structure.md) +* [Naming convention](docs/naming-convention.md) +* [Task scheduling](docs/task-scheduling.md) +* [Memory management](docs/memory-management.md) + +## Compilation + +To compile Löwe OS run `make` from repository root, make sure +[Clang](https://clang.llvm.org/) compiler is installed on your system. + +``` +$ make +``` + +Output files will be stored inside newly created `build` folder. + +## Run + +To run Löwe OS on QEMU, execute `make run` command for the repository root. + +To run Löwe OS on Raspberry PI3, follow these steps: + +1. Compile project and copy `build/kernel8.img` and `config.txt` files to +Micro SD card +2. Make sure latest boot code is installed on the SD card +3. Insert SD card into your Raspberry PI3 and power it up + +## Debug + +If you have `gdb-multiarch` and **QEMU** installed, then debugging should be as +easy as `make debug`. + +## Roadmap + +1. Generic kernel features: + [x] Loadable Kernel file + [x] UART logging + [x] Memory pages avalability bitmap + [x] Interrupt vectors table + [x] Basic task scheduler + [ ] Context switching + [ ] Memory Mapping Unit +2. Input/output: + [ ] Graphical driver + [ ] USB driver + [ ] Keyboard input driver + [ ] Mouse input driver +3. Graphical system +4. Shell and utilities +5. Networking +6. Sound system + + +## Contribution diff --git a/docs/memory-management.md b/docs/memory-management.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/naming-convention.md b/docs/naming-convention.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/project-structure.md b/docs/project-structure.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/task-scheduling.md b/docs/task-scheduling.md new file mode 100644 index 0000000..e69de29 diff --git a/kernel/Makefile b/kernel/Makefile index c2b3e05..809ab0e 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -22,16 +22,19 @@ INCS += -I./ LD_SCRIPT = aarch64/aarch64.ld SOURCE_FILES = \ - aarch64/boot.S \ + aarch64/aarch64_boot.S \ aarch64/aarch64.S \ \ - core/main.c \ - core/irq.c \ - core/timer.c \ - core/log.c \ + leos/irq.c \ + leos/leos.c \ + leos/log.c \ + leos/memory.c \ + leos/scheduler.c \ + leos/task.c \ \ - device/uart/uart_mini.c \ - device/uart/uart_qemu.c \ + drivers/timer/timer.c \ + drivers/uart/uart_mini.c \ + drivers/uart/uart_qemu.c \ SOURCE_LIST := $(wildcard $(SOURCE_FILES)) OBJECT_FILES := $(addsuffix .o, $(addprefix $(BUILD_DIR), ${SOURCE_LIST})) diff --git a/kernel/aarch64/aarch64.S b/kernel/aarch64/aarch64.S index 7e90415..abd010f 100644 --- a/kernel/aarch64/aarch64.S +++ b/kernel/aarch64/aarch64.S @@ -1,53 +1,61 @@ -#include "aarch64_irq.h" +#include "AArch64_irq.h" -.globl aarch64_init -aarch64_init: +.globl AArch64_init +AArch64_init: /* set vector table */ - adr x0, aarch64_vectors + adr x0, AArch64_vectors msr vbar_el1, x0 mov x0, 0 ret -.globl aarch64_get_el -aarch64_get_el: +.globl AArch64_getEL +AArch64_getEL: mrs x0, CurrentEL lsr x0, x0, 0x02 ret -.globl aarch64_get32r -aarch64_get32r: +.globl AArch64_getReg32 +AArch64_get32r: ldr w0, [x0] ret -.globl aarch64_set32r -aarch64_set32r: +.globl AArch64_setReg32 +AArch64_set32r: str w1, [x0] ret -.globl aarch64_delay -aarch64_delay: +.globl AArch64_idle +AArch64_idle: subs x0, x0, 1 - bne aarch64_delay + bne AArch64_delay ret -.globl aarch64_irq_vector_init -irq_vector_init: +/* +.globl AArch64_initIRQVector +AArch64_initIRQVector: ret +*/ -.globl aarch64_irq_enable -aarch64_irq_enable: +.globl AArch64_enableIRQ +AArch64_enableIRQ: msr daifclr, 2 ret -.globl aarch64_irq_disable -aarch64_irq_disable: +.globl AArch64_disableIRQ +AArch64_disableIRQ: msr daifset, 2 ret +.globl AArch64_memzero +AArch64_memzero: + str xzr, [x0], 8 + subs x1, x1, 8 + b.gt AArch64_memzero + ret /* Exceptions Vector Table * */ - .macro KERNEL_ENTER + .macro SAVE_REGISTERS sub sp, sp, 256 stp x0, x1, [sp, 16 * 0] stp x2, x3, [sp, 16 * 1] @@ -64,26 +72,36 @@ aarch64_irq_disable: stp x24, x25, [sp, 16 * 12] stp x26, x27, [sp, 16 * 13] stp x28, x29, [sp, 16 * 14] - str x30, [sp, 16 * 15] + + mrs x22, elr_el1 + mrs x23, spsr_el1 + + stp x30, x22, [sp, 16 * 15] + str x23, [sp, 16 * 16] .endm - .macro KERNEL_LEAVE - ldp x0, x1, [sp, 16 * 0] - ldp x2, x3, [sp, 16 * 1] - ldp x4, x5, [sp, 16 * 2] - ldp x6, x7, [sp, 16 * 3] - ldp x8, x9, [sp, 16 * 4] - ldp x10, x11, [sp, 16 * 5] - ldp x12, x13, [sp, 16 * 6] - ldp x14, x15, [sp, 16 * 7] - ldp x16, x17, [sp, 16 * 8] - ldp x18, x19, [sp, 16 * 9] - ldp x20, x21, [sp, 16 * 10] - ldp x22, x23, [sp, 16 * 11] - ldp x24, x25, [sp, 16 * 12] - ldp x26, x27, [sp, 16 * 13] + .macro LOAD_REGISTERS + ldr x23, [sp, 16 * 16] + ldp x30, x22, [sp, 16 * 15] + + msr elr_el1, x22 + msr spsr_el1, x23 + ldp x28, x29, [sp, 16 * 14] - ldr x30, [sp, 16 * 15] + ldp x26, x27, [sp, 16 * 13] + ldp x24, x25, [sp, 16 * 12] + ldp x22, x23, [sp, 16 * 11] + ldp x20, x21, [sp, 16 * 10] + ldp x18, x19, [sp, 16 * 9] + ldp x16, x17, [sp, 16 * 8] + ldp x14, x15, [sp, 16 * 7] + ldp x12, x13, [sp, 16 * 6] + ldp x10, x11, [sp, 16 * 5] + ldp x8, x9, [sp, 16 * 4] + ldp x6, x7, [sp, 16 * 3] + ldp x4, x5, [sp, 16 * 2] + ldp x2, x3, [sp, 16 * 1] + ldp x0, x1, [sp, 16 * 0] add sp, sp, 256 .endm @@ -93,11 +111,11 @@ aarch64_irq_disable: .endm .macro EXCEPTION_FALLBACK EID - KERNEL_ENTER + SAVE_REGISTERS mov x0, \EID mrs x1, esr_el1 mrs x2, elr_el1 - bl k_irq_fallback + bl IRQ_fallback b die .endm @@ -105,8 +123,8 @@ die: b die .align 11 -.globl aarch64_vectors -aarch64_vectors: +.globl AArch64_vectors +AArch64_vectors: /* EL1t */ VECTOR_ENTRY el1t_sync VECTOR_ENTRY el1t_irq @@ -144,9 +162,12 @@ el1h_sync: EXCEPTION_FALLBACK EL1h_SYNC el1h_irq: - KERNEL_ENTER - bl k_irq_handler - KERNEL_LEAVE + SAVE_REGISTERS + bl IRQ_onInterrupt + cbz x0, load_regs + mov sp, x0 /* task context must be switched */ +load_regs: + LOAD_REGISTERS eret el1h_fiq: @@ -179,3 +200,4 @@ el0_32_fiq: el0_32_error: EXCEPTION_FALLBACK EL0_32_ERROR + diff --git a/kernel/aarch64/aarch64.h b/kernel/aarch64/aarch64.h index 4564249..21b90b6 100644 --- a/kernel/aarch64/aarch64.h +++ b/kernel/aarch64/aarch64.h @@ -20,24 +20,27 @@ #include "aarch64_irq.h" extern unsigned int -aarch64_init(void); +AArch64_init(void); extern unsigned int -aarch64_get_el(void); +AArch64_getEL(void); extern unsigned int -aarch64_get32r(unsigned long reg); +AArch64_getReg32(unsigned long reg); extern void -aarch64_set32r(unsigned long reg, unsigned int value); +AArch64_setReg32(unsigned long reg, unsigned int value); extern void -aarch64_delay(unsigned long cycles); +AArch64_idle(unsigned long cycles); extern void -aarch64_irq_enable(void); +AArch64_enableIRQ(void); extern void -aarch64_irq_disable(void); +AArch64_disableIRQ(void); + +extern void +AArch64_memzero(void *addr, unsigned long size); #endif /* !AARCH64_H */ diff --git a/kernel/aarch64/boot.S b/kernel/aarch64/aarch64_boot.S similarity index 100% rename from kernel/aarch64/boot.S rename to kernel/aarch64/aarch64_boot.S diff --git a/kernel/core/main.c b/kernel/core/main.c deleted file mode 100644 index a6c19f2..0000000 --- a/kernel/core/main.c +++ /dev/null @@ -1,65 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 2017-2019 by Löwenware Ltd - * Please, refer LICENSE file for legal information - * - ******************************************************************************/ - -/** - * @file main.c - * @author Ilja Kartašov - * @brief - * - * @see https://lowenware.com/ - */ - -#include -#include -#include -#include - - - -void -k_main(void); - - -void -k_main(void) -{ - k_log_init(); - - k_logs("Starting Lowe OS (EL"); - k_logi(aarch64_get_el(), 10); - k_logs(")\r\n"); - - if (k_arch_init()) - goto panic; - - k_timer_init(); - k_irq_enable_controller(); - k_irq_enable(); - - goto ok; - /* - k_logs("\tclock"); - if (k_clock_init()) - goto panic; - - k_logs(" - ok\n\tscheduler"); - if (k_scheduler_init()) - goto panic; - - k_logs(" - ok\n"); - - k_scheduler_run(); -*/ - -panic: - k_logs(" - ERROR\n"); -ok: - for (;;) { - __asm__("WFE"); - } -} - diff --git a/kernel/aarch64/bcm2837.h b/kernel/drivers/soc/bcm2837/bcm2837.h similarity index 91% rename from kernel/aarch64/bcm2837.h rename to kernel/drivers/soc/bcm2837/bcm2837.h index bfc1099..2dc5e5e 100644 --- a/kernel/aarch64/bcm2837.h +++ b/kernel/drivers/soc/bcm2837/bcm2837.h @@ -18,6 +18,17 @@ #define PERIPHERAL_BASE 0x3F000000 +/* Reserve 4 MB for the Kernel and its stack */ +#define MEMORY_LOW (4 * 1024 * 1024) + +#define MEMORY_HIGH PERIPHERAL_BASE + +#define MEMORY_SIZE (MEMORY_HIGH - MEMORY_LOW) + +#define MEMORY_PAGE_SIZE (4 * 1024) + +#define MEMORY_PAGE_COUNT (MEMORY_SIZE / MEMORY_PAGE_SIZE) + /* GPIO */ #define GPFSEL1 (PERIPHERAL_BASE + 0x00200004) #define GPSET0 (PERIPHERAL_BASE + 0x0020001C) diff --git a/kernel/core/timer.c b/kernel/drivers/timer/timer.c similarity index 100% rename from kernel/core/timer.c rename to kernel/drivers/timer/timer.c diff --git a/kernel/core/timer.h b/kernel/drivers/timer/timer.h similarity index 100% rename from kernel/core/timer.h rename to kernel/drivers/timer/timer.h diff --git a/kernel/device/uart/uart.h b/kernel/drivers/uart/uart.h similarity index 72% rename from kernel/device/uart/uart.h rename to kernel/drivers/uart/uart.h index 9e01f4d..5d29f99 100644 --- a/kernel/device/uart/uart.h +++ b/kernel/drivers/uart/uart.h @@ -28,19 +28,19 @@ #if UART_DEFAULT == UART_MINI -#define uart_init(...) uart_mini_init(__VA_ARGS__) -#define uart_read(...) uart_mini_read(__VA_ARGS__) -#define uart_write(...) uart_mini_write(__VA_ARGS__) +#define UART_init(...) UARTMini_init(__VA_ARGS__) +#define UART_get(...) UARTMini_get(__VA_ARGS__) +#define UART_put(...) UARTMini_put(__VA_ARGS__) #elif UART_DEFAULT == UART_QEMU -#define uart_init(...) -#define uart_read(...) -#define uart_write(...) uart_qemu_write(__VA_ARGS__) +#define UART_init(...) +#define UART_get(...) +#define UART_put(...) UARTQEMU_put(__VA_ARGS__) #else -#warning "Unsupported default UART" +#warning "Unsupported UART" #endif diff --git a/kernel/device/uart/uart_mini.c b/kernel/drivers/uart/uart_mini.c similarity index 52% rename from kernel/device/uart/uart_mini.c rename to kernel/drivers/uart/uart_mini.c index d23096a..673942f 100644 --- a/kernel/device/uart/uart_mini.c +++ b/kernel/drivers/uart/uart_mini.c @@ -6,7 +6,7 @@ ******************************************************************************/ /** - * @file uart_mini.c + * @file UARTMini.c * @author Ilja Kartašov * @brief * @@ -16,69 +16,69 @@ #include #include -#include "uart_mini.h" +#include "UARTMini.h" int -uart_mini_init(void) +UARTMini_init(void) { unsigned int sel; /* Enable UART Mini and its registers*/ - aarch64_set32r(AUX_ENABLES, 1); + AArch64_setReg32(AUX_ENABLES, 1); /* Disable TX and RX interrupts */ - aarch64_set32r(AUX_MU_IER_REG, 0); + AArch64_setReg32(AUX_MU_IER_REG, 0); /* Disable auto flow control, TX and RX */ - aarch64_set32r(AUX_MU_CNTL_REG, 0); + AArch64_setReg32(AUX_MU_CNTL_REG, 0); /* Set 8bit mode */ - aarch64_set32r(AUX_MU_LCR_REG, 3); + AArch64_setReg32(AUX_MU_LCR_REG, 3); /* Set RTS line HIGH */ - aarch64_set32r(AUX_MU_MCR_REG, 0); + AArch64_setReg32(AUX_MU_MCR_REG, 0); /* Set baud rate 115200 */ - aarch64_set32r(AUX_MU_IER_REG, 0); - aarch64_set32r(AUX_MU_IIR_REG, 0xC6); - aarch64_set32r(AUX_MU_BAUD_REG, 270); + AArch64_setReg32(AUX_MU_IER_REG, 0); + AArch64_setReg32(AUX_MU_IIR_REG, 0xC6); + AArch64_setReg32(AUX_MU_BAUD_REG, 270); - sel = aarch64_get32r(GPFSEL1); + sel = AArch64_getReg32(GPFSEL1); /* clean and set ALT5 for GPIO14 */ sel &= ~(7 << 12); sel |= (2 << 12); /* clean and set ALT5 for GPIO15 */ sel &= ~(7 << 15); sel |= (2 << 15); - aarch64_set32r(GPFSEL1, sel); + AArch64_setReg32(GPFSEL1, sel); - aarch64_set32r(GPPUD, 0); - aarch64_delay(150); - aarch64_set32r(GPPUDCLK0, (1 << 14) | (1 << 15)); - aarch64_delay(150); - aarch64_set32r(GPPUDCLK0, 0); + AArch64_setReg32(GPPUD, 0); + AArch64_delay(150); + AArch64_setReg32(GPPUDCLK0, (1 << 14) | (1 << 15)); + AArch64_delay(150); + AArch64_setReg32(GPPUDCLK0, 0); /* Enable TX and RX */ - aarch64_set32r(AUX_MU_CNTL_REG, 3); + AArch64_setReg32(AUX_MU_CNTL_REG, 3); return 0; } int -uart_mini_write(char c) +UARTMini_put(char c) { while (1) { - if (aarch64_get32r(AUX_MU_LSR_REG) & 0x20) + if (AArch64_getReg32(AUX_MU_LSR_REG) & 0x20) break; } - aarch64_set32r(AUX_MU_IO_REG, c); + AArch64_setReg32(AUX_MU_IO_REG, c); return 0; } int -uart_mini_read(char *pc) +UARTMini_get(char *pc) { while (1) { - if (aarch64_get32r(AUX_MU_LSR_REG) & 0x01) + if (AArch64_getReg32(AUX_MU_LSR_REG) & 0x01) break; } - *pc = aarch64_get32r(AUX_MU_IO_REG) & 0xFF; + *pc = AArch64_getReg32(AUX_MU_IO_REG) & 0xFF; return 0; } diff --git a/kernel/device/uart/uart_mini.h b/kernel/drivers/uart/uart_mini.h similarity index 85% rename from kernel/device/uart/uart_mini.h rename to kernel/drivers/uart/uart_mini.h index a801053..34d5a8d 100644 --- a/kernel/device/uart/uart_mini.h +++ b/kernel/drivers/uart/uart_mini.h @@ -6,7 +6,7 @@ ******************************************************************************/ /** - * @file uart_mini.h + * @file UARTMini.h * @author Ilja Kartašov * @brief * @@ -17,12 +17,12 @@ #define UART_MINI_H_B0DFA3CF_5B4F_4EB0_B393_391C0069A04F int -uart_mini_init(void); +UARTMini_init(void); int -uart_mini_write(char c); +UARTMini_put(char c); int -uart_mini_read(char *pc); +UARTMini_get(char *pc); #endif /* !UART_MINI_H */ diff --git a/kernel/device/uart/uart_qemu.c b/kernel/drivers/uart/uart_qemu.c similarity index 79% rename from kernel/device/uart/uart_qemu.c rename to kernel/drivers/uart/uart_qemu.c index 147207a..997e134 100644 --- a/kernel/device/uart/uart_qemu.c +++ b/kernel/drivers/uart/uart_qemu.c @@ -15,16 +15,14 @@ #include "uart_qemu.h" -#define UART_BASE 0x09000000; +#define UARTQEMU_BASE 0x09000000; -volatile unsigned int *UART0 = (unsigned int *)UART_BASE; +volatile unsigned int *UART0 = (unsigned int *)UARTQEMU_BASE; int -uart_qemu_write(unsigned char c) +UARTQEMU_put(unsigned char c) { *UART0 = (unsigned int) c; return 0; } - - diff --git a/kernel/device/uart/uart_qemu.h b/kernel/drivers/uart/uart_qemu.h similarity index 94% rename from kernel/device/uart/uart_qemu.h rename to kernel/drivers/uart/uart_qemu.h index 8f2fd81..03eff5a 100644 --- a/kernel/device/uart/uart_qemu.h +++ b/kernel/drivers/uart/uart_qemu.h @@ -17,6 +17,6 @@ #define UART_QEMU_H_EDB39A0E_9BED_4A47_91CD_E804A9B4E8ED int -uart_qemu_write(unsigned char c); +UARTQEMU_put(unsigned char c); #endif /* !UART_QEMU_H */ diff --git a/kernel/core/arch.h b/kernel/leos/arch.h similarity index 100% rename from kernel/core/arch.h rename to kernel/leos/arch.h diff --git a/kernel/core/irq.c b/kernel/leos/irq.c similarity index 57% rename from kernel/core/irq.c rename to kernel/leos/irq.c index 1103b30..6a38752 100644 --- a/kernel/core/irq.c +++ b/kernel/leos/irq.c @@ -16,6 +16,7 @@ #include #include "timer.h" #include "log.h" +#include "task.h" #include "irq.h" static const char *m_types[] = { @@ -37,35 +38,45 @@ static const char *m_types[] = { "EL0_32_ERROR" }; -void -k_irq_enable_controller() + +static unsigned long +IRQ_onTimerInterrupt(void) { - aarch64_set32r(ENABLE_IRQS_1, SYSTEM_TIMER_IRQ_1); + Timer_incFromISR(); + return Task_scheduleFromISR(); } + void -k_irq_handler(void) +IRQ_init() { - unsigned int irq = aarch64_get32r(IRQ_PENDING_1); + AArch64_setReg32(ENABLE_IRQS_1, SYSTEM_TIMER_IRQ_1); +} + +unsigned long +IRQ_onInterrupt(void) +{ + unsigned int irq = AArch64_getReg32(IRQ_PENDING_1); + switch(irq) { case SYSTEM_TIMER_IRQ_1: - k_timer_irq_handler(); - break; + return IRQ_onTimerInterrupt(); default: - k_logs("Unhandled irq: "); - k_logu(irq, 16); - k_logs("\n"); + Log_putS("Unhandled irq: "); + Log_putU(irq, 16); + Log_putS("\n"); } + return 0; /* do not change stack pointer */ } void -k_irq_fallback(int type, unsigned long esr, unsigned long address) +IRQ_fallback(int type, unsigned long esr, unsigned long address) { - k_logs(m_types[type]); - k_logs(" -> ESR: "); - k_logu(esr, 16); - k_logs(", address: "); - k_logu(address, 16); - k_logs("\r\n"); + Log_putS(m_types[type]); + Log_putS(" -> ESR: "); + Log_putU(esr, 16); + Log_putS(", address: "); + Log_putU(address, 16); + Log_putS("\r\n"); } diff --git a/kernel/core/irq.h b/kernel/leos/irq.h similarity index 70% rename from kernel/core/irq.h rename to kernel/leos/irq.h index 6302656..63febca 100644 --- a/kernel/core/irq.h +++ b/kernel/leos/irq.h @@ -19,16 +19,16 @@ #include void -k_irq_enable_controller(void); +IRQ_init(void); + +unsigned long +IRQ_onInterrupt(void); void -k_irq_handler(void); +IRQ_fallback(int type, unsigned long esr, unsigned long address); -void -k_irq_fallback(int type, unsigned long esr, unsigned long address); +#define IRQ_enable(...) AArch64_enableIRQ(__VA_ARGS__) -#define k_irq_enable(...) aarch64_irq_enable(__VA_ARGS__) - -#define k_irq_disable(...) aarch64_irq_disable(__VA_ARGS__) +#define IRQ_disable(...) AArch64_disableIRQ(__VA_ARGS__) #endif /* !IRQ_H */ diff --git a/kernel/leos/leos.c b/kernel/leos/leos.c new file mode 100644 index 0000000..a89d74c --- /dev/null +++ b/kernel/leos/leos.c @@ -0,0 +1,42 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file main.c + * @author Ilja Kartašov + * @brief + * + * @see https://lowenware.com/ + */ + +#include +#include +#include +#include +#include + + +void +Leos_run(void) +{ + Log_init(); + + Log_putS("Starting Lowe OS (EL"); + Log_putI(AArch64_getEL(), 10); + Log_putS(")\r\n"); + + Arch_init(); + + Timer_init(); + IRQ_init(); + IRQ_enable(); + + for (;;) { + __asm__("WFE"); + } +} + diff --git a/kernel/leos/leos.h b/kernel/leos/leos.h new file mode 100644 index 0000000..7ea552b --- /dev/null +++ b/kernel/leos/leos.h @@ -0,0 +1,22 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2020 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file leos.h + * @author Ilja Kartašov + * @brief + * + * @see https://lowenware.com/ + */ + +#ifndef LEOS_H_7087F58B_BDEB_433B_A013_5B5F854922AF +#define LEOS_H_7087F58B_BDEB_433B_A013_5B5F854922AF + +void +Leos_run(void); + +#endif /* !LEOS_H */ diff --git a/kernel/core/log.c b/kernel/leos/log.c similarity index 69% rename from kernel/core/log.c rename to kernel/leos/log.c index d1379e0..634f46a 100644 --- a/kernel/core/log.c +++ b/kernel/leos/log.c @@ -17,31 +17,31 @@ #include "log.h" void -k_log_init(void) +Log_init(void) { - uart_init(); + UART_init(); } -Ki32 -k_logs(const Ki8 *string) +int +Log_putS(const char *string) { - Ki8 c; - const Ki8 *p = string; + char c; + const char *p = string; while((c = *p) != 0) { - if (uart_write(c)) + if (UART_send(c)) return -1; p++; } - return (Ki32)(p - string); + return (int)(p - string); } -Ki32 -k_logi(Ki64 value, Ku8 base) +int +Log_putI(int64_t value, uint8_t base) { - Ki32 result; + int result; if (value < 0) { - if (uart_write('-')) + if (UART_send('-')) return -1; value = -value; result = 1; @@ -52,21 +52,22 @@ k_logi(Ki64 value, Ku8 base) return (result) ? result : -1; } -Ki32 -k_logu(Ku64 value, Ku8 base) +int +Log_putU(uint64_t value, uint8_t base) { - Ki32 i = 0, result; - Ku8 buffer[64]; + int i = 0, result; + char buffer[64]; if (!value) { - return (uart_write('0')) ? -1 : 1; + return (UART_send('0')) ? -1 : 1; } do { + uint64_t r; if (!(i < (sizeof(buffer) / sizeof(buffer[0])))) return -1; - Ku64 r = value % base; + r = value % base; buffer[i++] = (r < 0x0A) ? '0' + r : 'A' + r - 0x0A; value /= base; } while (value); @@ -74,7 +75,7 @@ k_logu(Ku64 value, Ku8 base) result = i; while (i--) { - if (uart_write(buffer[i])) + if (UART_send(buffer[i])) return -1; } return result; diff --git a/kernel/core/log.h b/kernel/leos/log.h similarity index 80% rename from kernel/core/log.h rename to kernel/leos/log.h index 6afdd29..22ca81a 100644 --- a/kernel/core/log.h +++ b/kernel/leos/log.h @@ -19,15 +19,15 @@ #include void -k_log_init(void); +Log_init(void); -Ki32 -k_logs(const Ki8 *string); +int +Log_putS(const char *string); -Ki32 -k_logi(Ki64 value, Ku8 base); +int +Log_putI(int64_t value, uint8_t base); -Ki32 -k_logu(Ku64 value, Ku8 base); +int +Log_putU(uint64_t value, uint8_t base); #endif /* !LOG_H */ diff --git a/kernel/leos/memory.c b/kernel/leos/memory.c new file mode 100644 index 0000000..5ce8b1e --- /dev/null +++ b/kernel/leos/memory.c @@ -0,0 +1,54 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2020 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + unsigned + * @file memory.c + * @author Ilja Kartašov + * @brief + * + * @see https://lowenware.com/ + */ + +#include +#include +#include "memory.h" + +static unsigned long m_map[MEMORY_PAGE_COUNT / sizeof(unsigned long) / 8] = {0,}; +static int m_ix = 0; + +void * +Memory_getPage(void) +{ + int i, j; + unsigned long map; + + + for (i = m_ix; i < sizeof(m_map) / sizeof(m_map[0]); i++) { + map = m_map[i]; + for (j = 0; j < 8 * sizeof(map); j++) { + if (!(map & (1 << j))) { + m_map[i] |= (1 << j); + return (void *) ((i * sizeof(map) * 8 + j) * MEMORY_PAGE_SIZE); + } + } + m_ix = i; + } + + return NULL; +} + +void +Memory_freePage(void *p_addr) +{ + int i, j, c; + + c = ((unsigned long) p_addr) / MEMORY_PAGE_SIZE; + i = c / sizeof(m_map[0]); + j = c % sizeof(m_map[0]); + m_map[i] &= ~(1 << j); +} diff --git a/kernel/leos/memory.h b/kernel/leos/memory.h new file mode 100644 index 0000000..9bfa554 --- /dev/null +++ b/kernel/leos/memory.h @@ -0,0 +1,26 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2020 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file memory.h + * @author Ilja Kartašov + * @brief + * + * @see https://lowenware.com/ + */ + +#ifndef MEMORY_H_C583E24E_55B0_49EF_99C9_5A36B04468AC +#define MEMORY_H_C583E24E_55B0_49EF_99C9_5A36B04468AC + +void * +Memory_getPage(void); + +void +Memory_freePage(void *p_addr); + + +#endif /* !MEMORY_H */ diff --git a/kernel/leos/scheduler.c b/kernel/leos/scheduler.c new file mode 100644 index 0000000..1ac3016 --- /dev/null +++ b/kernel/leos/scheduler.c @@ -0,0 +1,92 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2020 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file scheduler.c + * @author Ilja Kartašov + * @brief + * + * @see https://lowenware.com/ + */ + +#include "scheduler.h" + + +static struct KTask *m_first = NULL, *m_last, *m_current = NULL; +static KPid m_pid = 0; + +static void +_disable_preempt(void) +{ + m_current->preempt++; +} + +static void +_enable_preempt(void) +{ + m_current->preempt--; +} + +static void +_switch(void) +{ + struct KTask *i, *next; + long p = 0; + + _disable_preempt(); + + for (;;) { + /* check urgent tasks */ + for (i = m_first; i != NULL; i = i->next) { + if (!i->state && i->counter > p) { + p = i->counter; + next = i; + } + i = i->next; + } + + if (p) { + break; + } + + i = m_first; + for (i = m_first; i != NULL; i = i->next) { + i->counter = i->priority; + } + } + + aarch64_switch(m_current, next); + _enable_preempt(); +} + +void +scheduler_init(void) +{ + +} + +KPid +scheduler_add(struct KTask *task) +{ + KPid result = ++m_pid; + task->pid = result; + task->prev = m_last; + m_last->next = task; + return result; +} + +void +scheduler_switch(void) +{ + +} + +void +scheduler_switch_from_isr(void) +{ + +} diff --git a/kernel/leos/scheduler.h b/kernel/leos/scheduler.h new file mode 100644 index 0000000..0ba4628 --- /dev/null +++ b/kernel/leos/scheduler.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * + * Copyright (c) 2017-2019 by Löwenware Ltd + * Please, refer LICENSE file for legal information + * + ******************************************************************************/ + +/** + * @file scheduler.h + * @author Ilja Kartašov + * @brief + * + * @see https://lowenware.com/ + */ + +#ifndef SCHEDULER_H_AE39DBC8_E643_4857_B319_9732123728A4 +#define SCHEDULER_H_AE39DBC8_E643_4857_B319_9732123728A4 + +void +scheduler_init(void); + +void +scheduler_run(void); + +void +scheduler_switch(void); + +KPid +scheduler_add(struct KTask *task); + +KRetCode +scheduler_remove(struct KTask *task); + +KRetCode +scheduler_remove_pid(KPid pid); + + +#endif /* !SCHEDULER_H */ diff --git a/kernel/core/task.h b/kernel/leos/task.h similarity index 65% rename from kernel/core/task.h rename to kernel/leos/task.h index 66958e3..4145d62 100644 --- a/kernel/core/task.h +++ b/kernel/leos/task.h @@ -18,20 +18,19 @@ #include -typedef Ku32 KTaskId; -typedef void (*KTaskCallback)(void *p_ctx); +typedef void (*TaskCallback)(void *p_ctx); -struct k_task { - KByte name[K_CONFIG_TASK_MAX_NAME_LEN + 1]; - KTaskCallback callback; - Ku32 *stack; - Ku32 stack_size; - Ku32 priority; +struct Task { + char name[CONFIG_TASK_MAX_NAME_LEN + 1]; + TaskCallback callback; + uint64_t *stack; + uint32_t stack_size; + uint32_t priority; }; -KTaskId -k_task_create(struct k_task *p_task, KTaskCallback callback, Ku32 *stack - , Ku32 stack_size); +PID +Task_create(struct Task *pTask, TaskCallback callback, uint64_t *stack + , uint32_t stack_size); #endif /* !TASK_H */ diff --git a/kernel/core/types.h b/kernel/leos/types.h similarity index 74% rename from kernel/core/types.h rename to kernel/leos/types.h index bfa27c1..5fea9cb 100644 --- a/kernel/core/types.h +++ b/kernel/leos/types.h @@ -16,14 +16,10 @@ #ifndef TYPES_H_BC3DA9C0_C9EE_4853_B5F5_EAA4B801664C #define TYPES_H_BC3DA9C0_C9EE_4853_B5F5_EAA4B801664C -typedef int KRetCode; +#include +#include -typedef int Ki32; -typedef unsigned int Ku32; -typedef long long Ki64; -typedef unsigned long long Ku64; -typedef char Ki8; -typedef unsigned char Ku8; -typedef char KByte; +typedef int RetCode; +typedef unsigned int PID; #endif /* !TYPES_H */