diff --git a/kernelmq/Makefile b/kernelmq/Makefile index 222aef9..aeb53fd 100644 --- a/kernelmq/Makefile +++ b/kernelmq/Makefile @@ -11,7 +11,6 @@ CFLAGS = -std=gnu99 -ffreestanding -nostdinc -fno-builtin -fno-stack-protector - # Architecture-dependent OBJS = start.s.o OBJS += main.c.o -OBJS += init.c.o OBJS += multiboot.c.o OBJS += panic.c.o panic.asm.cpp.o OBJS += paging.c.o paging.asm.cpp.o diff --git a/kernelmq/info.c b/kernelmq/info.c index 4a29cf5..5c463db 100644 --- a/kernelmq/info.c +++ b/kernelmq/info.c @@ -2,54 +2,48 @@ static unsigned char cmdline_terminated(const char *s); -unsigned char kernelmq_info_validate_and_copy( - struct KernelMQ_Info *const dest, - const struct KernelMQ_Info *const src -) { - if (!src) { +unsigned char kernelmq_info_validate(const struct KernelMQ_Info *const kinfo) +{ + if (!kinfo) { return 0; } - if (!dest) { + if (!cmdline_terminated(kinfo->cmdline)) { return 0; } - if (!cmdline_terminated(src->cmdline)) { + if (kinfo->modules_count > KERNELMQ_INFO_MODULES_MAX) { return 0; } - if (src->modules_count > KERNELMQ_INFO_MODULES_MAX) { + if (kinfo->areas_count > KERNELMQ_INFO_AREAS_MAX) { return 0; } - if (src->areas_count > KERNELMQ_INFO_AREAS_MAX) { + if (kinfo->kernel_size == 0) { return 0; } - if (src->kernel_size == 0) { + if (kinfo->kernel_offset == 0) { return 0; } - if (src->kernel_offset == 0) { + if (kinfo->kernel_phys_base + kinfo->kernel_size != kinfo->kernel_phys_limit + 1) { return 0; } - if (src->kernel_phys_base + src->kernel_size != src->kernel_phys_limit + 1) { + if (kinfo->kernel_virt_base + kinfo->kernel_size != kinfo->kernel_virt_limit + 1) { return 0; } - if (src->kernel_virt_base + src->kernel_size != src->kernel_virt_limit + 1) { - return 0; - } - - if (src->kernel_virt_base - src->kernel_phys_base != src->kernel_offset) { + if (kinfo->kernel_virt_base - kinfo->kernel_phys_base != kinfo->kernel_offset) { return 0; } unsigned long modules_total_size = 0; - for (unsigned int i = 0; i < src->modules_count; ++i) { - const struct KernelMQ_Info_Module *const module = &src->modules[i]; + for (unsigned int i = 0; i < kinfo->modules_count; ++i) { + const struct KernelMQ_Info_Module *const module = &kinfo->modules[i]; modules_total_size += module->size; @@ -66,18 +60,18 @@ unsigned char kernelmq_info_validate_and_copy( } } - if (src->modules_total_size != modules_total_size) { + if (kinfo->modules_total_size != modules_total_size) { return 0; } - if (src->kernel_and_modules_total_size != src->kernel_size + src->modules_total_size) { + if (kinfo->kernel_and_modules_total_size != kinfo->kernel_size + kinfo->modules_total_size) { return 0; } unsigned long long last = 0; - for (unsigned int i = 0; i < src->areas_count; ++i) { - const struct KernelMQ_Info_Area *const area = &src->areas[i]; + for (unsigned int i = 0; i < kinfo->areas_count; ++i) { + const struct KernelMQ_Info_Area *const area = &kinfo->areas[i]; if (last > area->base) { return 0; } @@ -93,18 +87,18 @@ unsigned char kernelmq_info_validate_and_copy( last = area->limit + 1; if (!area->is_available) { - if (src->kernel_phys_base >= area->base && - src->kernel_phys_base <= area->limit) { + if (kinfo->kernel_phys_base >= area->base && + kinfo->kernel_phys_base <= area->limit) { return 0; } - if (src->kernel_phys_limit >= area->base && - src->kernel_phys_limit <= area->limit) { + if (kinfo->kernel_phys_limit >= area->base && + kinfo->kernel_phys_limit <= area->limit) { return 0; } - for (unsigned int j = 0; j < src->modules_count; ++j) { - const struct KernelMQ_Info_Module *const module = &src->modules[j]; + for (unsigned int j = 0; j < kinfo->modules_count; ++j) { + const struct KernelMQ_Info_Module *const module = &kinfo->modules[j]; if (module->base >= area->base && module->base <= area->limit) { @@ -119,8 +113,6 @@ unsigned char kernelmq_info_validate_and_copy( } } - *dest = *src; - return 1; } diff --git a/kernelmq/info.h b/kernelmq/info.h index 211a364..e29a508 100644 --- a/kernelmq/info.h +++ b/kernelmq/info.h @@ -52,7 +52,7 @@ struct KernelMQ_Info { unsigned long kernel_stack_top; }; -unsigned char kernelmq_info_validate_and_copy(struct KernelMQ_Info *dest, const struct KernelMQ_Info *src); +unsigned char kernelmq_info_validate(const struct KernelMQ_Info *kinfo); #ifdef __cplusplus } diff --git a/kernelmq/init.c b/kernelmq/init.c deleted file mode 100644 index b6f6c5b..0000000 --- a/kernelmq/init.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "panic.h" -#include "protected.h" -#include "paging.h" - -#include "info.h" -#include "stdlib.h" -#include "module.h" -#include "process.h" - -#include "tasks.h" -#include "elf.h" -#include "logger.h" - -static struct KernelMQ_Info kinfo; - -static KernelMQ_Process_List process_list; - -void init(const struct KernelMQ_Info *const kinfo_ptr) -{ - kmemset(&kinfo, 0, sizeof(struct KernelMQ_Info)); - - assert(kernelmq_info_validate_and_copy(&kinfo, kinfo_ptr), "Invalid kernel information."); - - protected_initialize(&kinfo); - - // Set up a new post-relocate bootstrap pagetable so that - // we can map in VM, and we no longer rely on pre-relocated - // data. - paging_clear(); - paging_identity(); // Still need 1:1 for lapic and video mem and such. - paging_mapkernel(&kinfo); - paging_load(); - - const enum KernelMQ_Process_Error process_list_init_result = - KernelMQ_Process_List_init(&process_list, &kinfo); - - if (process_list_init_result != KERNELMQ_PROCESS_ERROR_OK) { - logger_fail_from( - "init", - "Process list initialization failed with %u.", - process_list_init_result - ); - - panic("Can not initialize process list."); - } - - logger_debug_from("init", "Process list initialized."); - - KernelMQ_Process_List_print(&process_list); - - if (kinfo.modules_count > 0) { - const struct KernelMQ_ELF_Header *const elf_header = - (void*)kinfo.modules[0].base; - - if (KernelMQ_ELF_Header_is_valid(elf_header)) { - const unsigned long real_entrypoint = - kinfo.modules[0].base + elf_header->entrypoint; - - tasks_switch_to_user(real_entrypoint); - } - else { - logger_warn_from("init", "Invalid ELF header"); - } - } -} diff --git a/kernelmq/main.c b/kernelmq/main.c index 1917bde..ff08a4f 100644 --- a/kernelmq/main.c +++ b/kernelmq/main.c @@ -4,6 +4,16 @@ #include "info.h" #include "stdlib.h" +#include "panic.h" +#include "protected.h" + +#include "module.h" +#include "process.h" + +#include "tasks.h" +#include "elf.h" +#include "logger.h" + // Defined in linker script extern char _kernel_offset; extern char _kernel_size; @@ -13,16 +23,18 @@ extern char _kernel_stack_top; static struct KernelMQ_Info kinfo; -const struct KernelMQ_Info *main(unsigned long multiboot_magic, unsigned long multiboot_info_base) +static KernelMQ_Process_List process_list; + +void main(unsigned long multiboot_magic, unsigned long multiboot_info_base) { if (multiboot_magic != MULTIBOOT_MAGIC) { - return 0; + return; } kmemset(&kinfo, 0, sizeof(struct KernelMQ_Info)); if (!multiboot_parse(&kinfo, multiboot_info_base)) { - return 0; + return; } kinfo.kernel_offset = (unsigned long)&_kernel_offset; @@ -45,5 +57,47 @@ const struct KernelMQ_Info *main(unsigned long multiboot_magic, unsigned long mu paging_enable(); - return &kinfo; + assert(kernelmq_info_validate(&kinfo), "Invalid kernel information."); + + protected_initialize(&kinfo); + + // Set up a new post-relocate bootstrap pagetable so that + // we can map in VM, and we no longer rely on pre-relocated + // data. + paging_clear(); + paging_identity(); // Still need 1:1 for lapic and video mem and such. + paging_mapkernel(&kinfo); + paging_load(); + + const enum KernelMQ_Process_Error process_list_init_result = + KernelMQ_Process_List_init(&process_list, &kinfo); + + if (process_list_init_result != KERNELMQ_PROCESS_ERROR_OK) { + logger_fail_from( + "init", + "Process list initialization failed with %u.", + process_list_init_result + ); + + panic("Can not initialize process list."); + } + + logger_debug_from("init", "Process list initialized."); + + KernelMQ_Process_List_print(&process_list); + + if (kinfo.modules_count > 0) { + const struct KernelMQ_ELF_Header *const elf_header = + (void*)kinfo.modules[0].base; + + if (KernelMQ_ELF_Header_is_valid(elf_header)) { + const unsigned long real_entrypoint = + kinfo.modules[0].base + elf_header->entrypoint; + + tasks_switch_to_user(real_entrypoint); + } + else { + logger_warn_from("init", "Invalid ELF header"); + } + } } diff --git a/kernelmq/start.s b/kernelmq/start.s index 462f12c..a478a8e 100644 --- a/kernelmq/start.s +++ b/kernelmq/start.s @@ -33,11 +33,6 @@ _start: push %eax // Multiboot magic number call main - mov $_kernel_stack_top, %esp // Initialize stack - - push %eax // Kernel information pointer - call init - call halt .size _start, . - _start