diff --git a/include/myke/acpi/acpi.h b/include/myke/acpi/acpi.h index b4563a4..9f2581b 100644 --- a/include/myke/acpi/acpi.h +++ b/include/myke/acpi/acpi.h @@ -5,10 +5,6 @@ #ifndef NEW_KERNEL_ACPI_H #define NEW_KERNEL_ACPI_H -void acpi_parse(); - -void acpi_init(); - void* acpi_find_table_by_name(const char* name, int skip); #endif //NEW_KERNEL_ACPI_H diff --git a/include/myke/command.h b/include/myke/command.h index fd10cc7..791996c 100644 --- a/include/myke/command.h +++ b/include/myke/command.h @@ -9,6 +9,4 @@ void store_bootloader_info(multiboot_info_t *multiboot_info); -void main_loop(void *data); - #endif //NEW_KERNEL_COMMAND_H diff --git a/include/myke/cpu/pit.h b/include/myke/cpu/pit.h index 6d7081b..230ad8a 100644 --- a/include/myke/cpu/pit.h +++ b/include/myke/cpu/pit.h @@ -7,7 +7,7 @@ #include -int pit_init(uint32_t freq); +int pit_int_frequency(uint32_t freq); void print_current_tick(); diff --git a/include/myke/drivers/keyboard.h b/include/myke/drivers/keyboard.h index 937d3f7..6f33070 100644 --- a/include/myke/drivers/keyboard.h +++ b/include/myke/drivers/keyboard.h @@ -19,8 +19,6 @@ typedef struct KeyEvent_t { char getc(); -void init_keyboard(); - //const char *key_code_to_string(KeyCode key); KeyEvent *get_next_event(); diff --git a/include/myke/drivers/serial.h b/include/myke/drivers/serial.h deleted file mode 100644 index 9ba5577..0000000 --- a/include/myke/drivers/serial.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// Created by rick on 28-01-21. -// - -#ifndef NEW_KERNEL_SERIAL_H -#define NEW_KERNEL_SERIAL_H - -int serial_init(); - -void serial_kprint(const char *msg); - -#endif //NEW_KERNEL_SERIAL_H diff --git a/include/myke/drivers/vgascreen.h b/include/myke/drivers/vgascreen.h index 7940ec0..c7963b8 100644 --- a/include/myke/drivers/vgascreen.h +++ b/include/myke/drivers/vgascreen.h @@ -27,8 +27,4 @@ #define VGA_COL_MAX 80 #define VGA_ROW_MAX 25 -void vga_clear_screen(); - -void vga_kprint(const char *msg); - #endif //MY_KERNEL_VGASCREEN_H diff --git a/include/myke/libk/kprint.h b/include/myke/libk/kprint.h index e9f1cbd..7f9da15 100644 --- a/include/myke/libk/kprint.h +++ b/include/myke/libk/kprint.h @@ -17,6 +17,4 @@ void kprint(const char *msg); void kprint_sync(const char *msg); -void kprint_init(); - -void kprint_start_task(); \ No newline at end of file +void kprint_init(); \ No newline at end of file diff --git a/include/myke/util/init.h b/include/myke/util/init.h index a6ebb64..2f8a38b 100644 --- a/include/myke/util/init.h +++ b/include/myke/util/init.h @@ -8,13 +8,23 @@ #include #include +enum init_stage { + INIT_STAGE_EARLY_BOOT_0, // id mapped, high memory, no malloc + INIT_STAGE_EARLY_BOOT_1, // memory available, no tasking + INIT_STAGE_LATE_BOOT, // time source, memory, most basic hardware available + INIT_STAGE_PRE_TASKING, // just before tasking is ready + INIT_STAGE_AFTER_BOOT_PRE_INIT, // tasking just started + // todo define later stages +}; + struct init { const char *name; + enum init_stage stage; void (*init)(); }; #define INIT_FUNCTION(order) GENERIC_DRIVER(init, order) -void init_execute_all(); +void init_execute_all(enum init_stage stage); #endif //NEW_KERNEL_INIT_H diff --git a/include/myke/vfs/blockdev.h b/include/myke/vfs/blockdev.h index 7731733..b6d44bc 100644 --- a/include/myke/vfs/blockdev.h +++ b/include/myke/vfs/blockdev.h @@ -66,8 +66,6 @@ uint8_t block_dev_register(block_device_t *device); void block_dev_free(block_device_t *device); -void block_dev_start_task(); - void block_dev_print_info(); bool block_dev_mount(char *identifier, char *driver); diff --git a/kernel/acpi/acpi.c b/kernel/acpi/acpi.c index 41751a5..8ac216c 100644 --- a/kernel/acpi/acpi.c +++ b/kernel/acpi/acpi.c @@ -13,6 +13,7 @@ #include #include #include +#include void acpi_handle_facp(const struct acpi_sdt_header *addr); @@ -272,5 +273,12 @@ void acpi_parse() { } void acpi_init() { + acpi_parse(); lai_create_namespace(); -} \ No newline at end of file +} + +INIT_FUNCTION(100) = { + .name = "acpi", + .stage = INIT_STAGE_EARLY_BOOT_1, + .init = acpi_init, +}; \ No newline at end of file diff --git a/kernel/command.c b/kernel/command.c index 27d753e..77fe350 100644 --- a/kernel/command.c +++ b/kernel/command.c @@ -25,6 +25,7 @@ #include #include #include +#include #endif @@ -223,3 +224,15 @@ void att_noreturn main_loop(void *data) { free(msg); } } + +#ifdef K_SHELL +void main_loop_start() { + task_spawn(main_loop, NULL, "main"); +} + +INIT_FUNCTION(100) = { + .name = "main-task", + .stage = INIT_STAGE_PRE_TASKING, + .init = main_loop_start, +}; +#endif \ No newline at end of file diff --git a/kernel/cpu/pit.c b/kernel/cpu/pit.c index 1c84484..bf0c17a 100644 --- a/kernel/cpu/pit.c +++ b/kernel/cpu/pit.c @@ -78,7 +78,7 @@ void print_current_tick() { kprint("\n"); } -int pit_init(uint32_t freq) { +int pit_int_frequency(uint32_t freq) { register_interrupt_handler(IRQ0, pit_callback); uint32_t divisor = PIT_FREQUENCY / freq; diff --git a/kernel/drivers/keyboard.c b/kernel/drivers/keyboard.c index e9336a5..5c9ac7e 100644 --- a/kernel/drivers/keyboard.c +++ b/kernel/drivers/keyboard.c @@ -8,6 +8,7 @@ #include #include #include +#include const char scancode_map_lowercase[] = { @@ -131,7 +132,7 @@ static void keyboard_callback(isr_registers_t *regs) { publish_key_event(scancode); } -void init_keyboard() { +void keyboard_init() { register_interrupt_handler(IRQ1, keyboard_callback); keyboard_state.shift = 0; keyboard_state.ctrl = 0; @@ -139,3 +140,9 @@ void init_keyboard() { keyboard_state.extended = 0; keyboard_event_buffer = create_buffer(256, sizeof(KeyEvent)); } + +INIT_FUNCTION(100) = { + .name = "keyboard", + .stage = INIT_STAGE_LATE_BOOT, + .init = keyboard_init, +}; \ No newline at end of file diff --git a/kernel/drivers/serial.c b/kernel/drivers/serial.c index d05abc9..55b3722 100644 --- a/kernel/drivers/serial.c +++ b/kernel/drivers/serial.c @@ -2,9 +2,10 @@ // Created by rick on 28-01-21. // -#include #include #include +#include +#include #define SERIAL_INTERRUPT_DATA_AVAILABLE (1 << 0) #define SERIAL_INTERRUPT_TRANSMITTER_EMPTY (1 << 1) @@ -51,7 +52,7 @@ #define MODEM_CONTROL_LOOPBACK_MODE (1 << 4) #define MODEM_CONTROL_AUTOFLOW_CONTROL_ENABLED (1 << 5) -int serial_init() { +int serial_init_hw() { port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_INTERRUPT, 0); // Disable all interrupts port_byte_out(PORT_SERIAL_0 + PORT_SERIAL_LINE_CONTROL, LINE_CONTROL_DIVISOR); // Enable DLAB (set baud rate divisor) @@ -114,4 +115,17 @@ void serial_kprint(const char *msg) { write_serial(c); i++; } -} \ No newline at end of file +} + +void serial_init() { + if (serial_init_hw() != 0) { + return; + } + kprint_register(serial_kprint); +} + +INIT_FUNCTION(100) = { + .name = "serial", + .stage = INIT_STAGE_EARLY_BOOT_0, + .init = serial_init, +}; diff --git a/kernel/drivers/vgascreen.c b/kernel/drivers/vgascreen.c index 2c491c8..32de2f9 100644 --- a/kernel/drivers/vgascreen.c +++ b/kernel/drivers/vgascreen.c @@ -3,9 +3,11 @@ // #include -#include #include +#include +#include +#include char *_vga_character_memory = (char *) VGA_CHARACTER_MEMORY_LOCATION; @@ -136,3 +138,14 @@ int get_offset_row(int offset) { int get_offset_col(int offset) { return (offset - (get_offset_row(offset) * 2 * VGA_COL_MAX)) / 2; } + +void vga_init() { + vga_clear_screen(); + kprint_register(vga_kprint); +} + +INIT_FUNCTION(100) = { + .name = "vga", + .stage = INIT_STAGE_EARLY_BOOT_0, + .init = vga_init, +}; \ No newline at end of file diff --git a/kernel/kernel.c b/kernel/kernel.c index 79bd15a..d361391 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -4,18 +4,12 @@ #define DEBUG_INIT -#include #include -#include #include #include #include #include -#include #include -#include -#include -#include #include #include #include @@ -44,11 +38,8 @@ void init_pci_system() { void att_noreturn att_used kmain(multiboot_info_t *multiboot_info, uint32_t mb_name) { // early init isr_install(); - vga_clear_screen(); - vga_clear_screen(' ', VGA_WHITE | (VGA_GRAY << VGA_SHIFT_BG)); - kprint_register(vga_kprint); - serial_init(); - kprint_register(serial_kprint); + // initialize early modules (kprint etc.) + init_execute_all(INIT_STAGE_EARLY_BOOT_0); // parse multiboot if (mb_name != MULTIBOOT_BOOTLOADER_MAGIC) { @@ -59,41 +50,33 @@ void att_noreturn att_used kmain(multiboot_info_t *multiboot_info, uint32_t mb_n // initialize memory management init_mmap(multiboot_info); + // safe multiboot info for later use + debug_store_info(multiboot_info); gdt_init(); // initialize kprint functionality kprint_init(); - - // todo earlier in boot - acpi_parse(); - acpi_init(); - - debug_store_info(multiboot_info); - - // identify cpu - cpuidx_print_info(); + // initialize early driver code (ACPI, etc.) + init_execute_all(INIT_STAGE_EARLY_BOOT_1); // enable interrupts __asm__ __volatile__("sti"); // start the timer - pit_init(1000); - // initialize devices - init_keyboard(); + pit_int_frequency(1000); + + // initialize drivers that are not discovered in any other way + init_execute_all(INIT_STAGE_LATE_BOOT); + + // init PCI init_pci_system(); printf("Booted successfully v%d.%d.%d\n", version_major, version_minor, version_patch); - // initializing modules - init_execute_all(); - // initialize tasking task_init(); - kprint_start_task(); - block_dev_start_task(); -#ifdef K_SHELL - task_spawn(main_loop, NULL, "main"); -#endif + // let other system provide tasks (command, kprint, blockdev) + init_execute_all(INIT_STAGE_PRE_TASKING); // switch to tasking syscall_start_scheduler(); } diff --git a/kernel/libk/kprint.c b/kernel/libk/kprint.c index 9cf0516..813097e 100644 --- a/kernel/libk/kprint.c +++ b/kernel/libk/kprint.c @@ -9,12 +9,13 @@ #include #include #include +#include #define MAX_HANDLERS 8 #define STREAM_SIZE (32*1024) #define PRINT_BUFFER_SIZE 64 -stream_t *kprint_stream; +stream_t *kprint_stream = NULL; kprint_handler handlers[MAX_HANDLERS] = {0}; @@ -29,7 +30,11 @@ void kprint_register(kprint_handler handler) { } void kprint(const char *msg) { - stream_write(kprint_stream, (const uint8_t *) msg, strlen(msg)); + if (kprint_stream == NULL) { + kprint_sync(msg); + } else { + stream_write(kprint_stream, (const uint8_t *) msg, strlen(msg)); + } } void kprint_internal(const char *msg) { @@ -65,4 +70,10 @@ void att_noreturn kprint_task(void *_) { void kprint_start_task() { task_spawn(kprint_task, NULL, "kprint"); -} \ No newline at end of file +} + +INIT_FUNCTION(100) = { + .name = "kprint-task", + .stage = INIT_STAGE_PRE_TASKING, + .init = kprint_start_task, +}; diff --git a/kernel/mem/malloc.c b/kernel/mem/malloc.c index d59caaa..0fd0daf 100644 --- a/kernel/mem/malloc.c +++ b/kernel/mem/malloc.c @@ -725,7 +725,7 @@ void free(void *ptr) { void *calloc(size_t nobj, size_t size) { - int real_size; + size_t real_size; void *p; real_size = nobj * size; diff --git a/kernel/util/init.c b/kernel/util/init.c index a779088..6cebeb2 100644 --- a/kernel/util/init.c +++ b/kernel/util/init.c @@ -10,9 +10,12 @@ extern struct init __stop_init[]; #define NUM_DRIVERS ((size_t)(__stop_init - __start_init)) #define DRIVER(i) ((__start_init) + (i)) -void init_execute_all() { +void init_execute_all(enum init_stage stage) { for (size_t i = 0; i < NUM_DRIVERS; ++i) { - printf("init %s\n", DRIVER(i)->name); + if (DRIVER(i)->stage != stage) continue; + if (stage > INIT_STAGE_EARLY_BOOT_0) { + printf("init %s\n", DRIVER(i)->name); + } DRIVER(i)->init(); } } \ No newline at end of file diff --git a/kernel/vfs/blockdev.c b/kernel/vfs/blockdev.c index b4d4071..01a9582 100644 --- a/kernel/vfs/blockdev.c +++ b/kernel/vfs/blockdev.c @@ -11,6 +11,7 @@ #include #include #include +#include #define MAX_BLOCK_DEVS 64 @@ -142,4 +143,10 @@ void block_dev_print_info() { block_devices[i].identifier, block_devices[i].flags.driver_installed ? block_devices[i].driver->name : "n/a"); } -} \ No newline at end of file +} + +INIT_FUNCTION(100) = { + .name = "blockdev-task", + .stage = INIT_STAGE_PRE_TASKING, + .init = block_dev_start_task, +}; diff --git a/kernel/vfs/tmpfs.c b/kernel/vfs/tmpfs.c index e46746f..9c77b53 100644 --- a/kernel/vfs/tmpfs.c +++ b/kernel/vfs/tmpfs.c @@ -9,5 +9,6 @@ void tmpfs_init() { INIT_FUNCTION(100) = { .name = "tmpfs", + .stage = INIT_STAGE_AFTER_BOOT_PRE_INIT, .init = tmpfs_init, };