diff --git a/src/Makefile b/src/Makefile index 1c1811c..d617dcd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -22,15 +22,10 @@ CPPFLAGS = \ -DKERNAUX_DEBUG \ -DKERNAUX_BITFIELDS -# Architecture-dependent OBJS = start.s.o OBJS += main.c.o OBJS += panic.c.o OBJS += paging.c.o - -# Architecture-independent -OBJS += info.c.o - OBJS += multiboot2.c.o OBJS += protected.c.o OBJS += interrupts.c.o interrupts.asm.cpp.o diff --git a/src/info.c b/src/info.c deleted file mode 100644 index 7057df6..0000000 --- a/src/info.c +++ /dev/null @@ -1,305 +0,0 @@ -#include "info.h" -#include "panic.h" - -#include - -#include - -static bool cmdline_terminated(const char *s); - -/****************** - * Initialization * - ******************/ - -void kernel_info_init_start( - struct Kernel_Info *const kinfo, - const size_t offset, - const size_t size, - const size_t phys_base, - const size_t virt_base, - const size_t stack_start, - const size_t stack_size -) { - assert(kinfo, "kinfo"); - - memset(kinfo, 0, sizeof(*kinfo)); - - kinfo->initialized = false; - - kinfo->kernel_offset = offset; - kinfo->kernel_size = size; - - kinfo->kernel_phys_base = phys_base; - kinfo->kernel_virt_base = virt_base; - - kinfo->kernel_stack_start = stack_start; - kinfo->kernel_stack_size = stack_size; -} - -void kernel_info_init_finish(struct Kernel_Info *const kinfo) -{ - assert(kinfo, "kinfo"); - assert(!kinfo->initialized, "!kinfo->initialized"); - - kinfo->kernel_and_modules_total_size = - kinfo->kernel_size + kinfo->modules_total_size; - - kinfo->initialized = true; -} - -void kernel_info_init_from_multiboot2( - struct Kernel_Info *kinfo, - const struct KernAux_Multiboot2_Info *multiboot2_info -) { - assert(kinfo, "kinfo"); - assert(multiboot2_info, "multiboot2_info"); - assert(!kinfo->initialized, "!kinfo->initialized"); - - { - const char *const cmdline = - KernAux_Multiboot2_Info_boot_cmd_line(multiboot2_info); - - if (cmdline) { - assert(strlen(cmdline) <= KERNEL_INFO_CMDLINE_SLEN_MAX, - "Kernel cmdline is too long"); - - strcpy(kinfo->cmdline, cmdline); - } else { - memset(kinfo->cmdline, '\0', sizeof(kinfo->cmdline)); - } - } - - { - const struct KernAux_Multiboot2_ITag_MemoryMap *const tag = - (struct KernAux_Multiboot2_ITag_MemoryMap*) - KernAux_Multiboot2_Info_first_tag_with_type( - multiboot2_info, - KERNAUX_MULTIBOOT2_ITAG_MEMORY_MAP - ); - - if (!tag) { - panic("No memory map provided in Multiboot 2 info."); - } - - for ( - const struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase *entry = - (struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase*) - KERNAUX_MULTIBOOT2_DATA(tag); - (unsigned char*)entry < (unsigned char*)tag + tag->base.size; - entry = - (struct KernAux_Multiboot2_ITag_MemoryMap_EntryBase*) - ((unsigned char*)entry + tag->entry_size) - ) { - if (kinfo->areas_count >= KERNEL_INFO_AREAS_MAX) { - panic("Too many memory map entries in Multiboot 2 info."); - } - - struct Kernel_Info_Area *const area = - &kinfo->areas[kinfo->areas_count]; - - area->base = entry->base_addr; - area->size = entry->length; - area->limit = area->base + area->size - 1; - - area->is_available = entry->type == 1; - - ++kinfo->areas_count; - } - } - - for ( - const struct KernAux_Multiboot2_ITag_Module *tag = - (struct KernAux_Multiboot2_ITag_Module*) - KernAux_Multiboot2_Info_first_tag_with_type( - multiboot2_info, - KERNAUX_MULTIBOOT2_ITAG_MODULE - ); - tag; - tag = (struct KernAux_Multiboot2_ITag_Module*) - KernAux_Multiboot2_Info_tag_with_type_after( - multiboot2_info, - KERNAUX_MULTIBOOT2_ITAG_MODULE, - (struct KernAux_Multiboot2_ITagBase*)tag - ) - ) { - if (kinfo->modules_count >= KERNEL_INFO_MODULES_MAX) { - panic("Too many modules in Multiboot 2 info."); - } - - unsigned int slen = strlen((char*)KERNAUX_MULTIBOOT2_DATA(tag)); - - if (slen > KERNEL_INFO_CMDLINE_SLEN_MAX) { - panic("Multiboot 2 module cmd line is too long."); - } - - struct Kernel_Info_Module *const module = - &kinfo->modules[kinfo->modules_count]; - - strcpy(module->cmdline, (char*)KERNAUX_MULTIBOOT2_DATA(tag)); - - module->base = tag->mod_start; - module->limit = tag->mod_end; - module->size = module->limit - module->base + 1; - - ++kinfo->modules_count; - - kinfo->modules_total_size += module->size; - } -} - -/******************************* - * Other kernel info functions * - *******************************/ - -void kernel_info_print(const struct Kernel_Info *const kinfo) -{ - assert(kinfo, "kinfo"); - - drivers_console_printf("Kernel info\n"); - drivers_console_printf(" cmdline: %s\n", kinfo->cmdline); - drivers_console_printf(" modules: %lu\n", kinfo->modules_count); - drivers_console_printf(" areas: %lu\n", kinfo->areas_count); - drivers_console_printf("\n"); - drivers_console_printf(" offset: %lu\n", kinfo->kernel_offset); - drivers_console_printf(" size: %lu\n", kinfo->kernel_size); - drivers_console_printf(" phys base: %lu\n", kinfo->kernel_phys_base); - drivers_console_printf(" virt base: %lu\n", kinfo->kernel_virt_base); - drivers_console_printf("\n"); - drivers_console_printf(" modules size: %lu\n", kinfo->modules_total_size); - drivers_console_printf(" kernel & modules size: %lu\n", kinfo->kernel_and_modules_total_size); - drivers_console_printf("\n"); - drivers_console_printf(" stack start: %lu\n", kinfo->kernel_stack_start); - drivers_console_printf(" stack size: %lu\n", kinfo->kernel_stack_size); -} - -bool kernel_info_is_valid(const struct Kernel_Info *const kinfo) -{ - assert(kinfo, "kinfo"); - assert(kinfo->initialized, "kinfo->initialized"); - - if (!cmdline_terminated(kinfo->cmdline)) return false; - - if (kinfo->modules_count > KERNEL_INFO_MODULES_MAX) return false; - if (kinfo->areas_count > KERNEL_INFO_AREAS_MAX) return false; - - if (kinfo->kernel_offset == 0) return false; - if (kinfo->kernel_size == 0) return false; - - if (kinfo->kernel_virt_base - kinfo->kernel_phys_base != - kinfo->kernel_offset) - { - return false; - } - - if (kinfo->kernel_stack_size != 16 * 1024) return false; - - if (!(kinfo->kernel_stack_start >= kinfo->kernel_phys_base && - kinfo->kernel_stack_start < - kinfo->kernel_phys_base + kinfo->kernel_size)) - { - return false; - } - - const size_t stack_end = - kinfo->kernel_stack_start + kinfo->kernel_stack_size; - - if (!(stack_end - 1 >= kinfo->kernel_phys_base && - stack_end - 1 < kinfo->kernel_phys_base + kinfo->kernel_size)) - { - return false; - } - - size_t modules_total_size = 0; - - for (size_t i = 0; i < kinfo->modules_count; ++i) { - const struct Kernel_Info_Module *const module = &kinfo->modules[i]; - - modules_total_size += module->size; - - if (module->size == 0) return false; - if (module->base + module->size != module->limit + 1) return false; - if (!cmdline_terminated(module->cmdline)) return false; - } - - if (kinfo->modules_total_size != modules_total_size) return false; - - if (kinfo->kernel_and_modules_total_size != - kinfo->kernel_size + kinfo->modules_total_size) - { - return false; - } - - uint64_t last = 0; - - for (size_t i = 0; i < kinfo->areas_count; ++i) { - const struct Kernel_Info_Area *const area = &kinfo->areas[i]; - - if (last > area->base) return false; - if (area->size == 0) return false; - if (area->base + area->size != area->limit + 1) return false; - - last = area->limit + 1; - - if (!area->is_available) { - if (kinfo->kernel_phys_base >= area->base && - kinfo->kernel_phys_base <= area->limit) - { - return false; - } - - if (kinfo->kernel_phys_base + kinfo->kernel_size - 1 >= area->base - && - kinfo->kernel_phys_base + kinfo->kernel_size - 1 <= area->limit) - { - return false; - } - - for (unsigned int j = 0; j < kinfo->modules_count; ++j) { - const struct Kernel_Info_Module *const module = - &kinfo->modules[j]; - - if (module->base >= area->base && module->base <= area->limit) { - return false; - } - - if (module->limit >= area->base && - module->limit <= area->limit) - { - return false; - } - } - } - } - - return true; -} - -void kernel_info_setup_pfa( - const struct Kernel_Info *const kinfo, - const KernAux_PFA pfa -) { - assert(kinfo, "kinfo"); - assert(pfa, "pfa"); - assert(kinfo->initialized, "kinfo->initialized"); - - for (size_t i = 0; i < kinfo->areas_count; ++i) { - const struct Kernel_Info_Area *const area = &kinfo->areas[i]; - - if (area->is_available) { - KernAux_PFA_mark_available(pfa, area->base, area->limit); - } - } -} - -/********************* - * Utility functions * - *********************/ - -bool cmdline_terminated(const char *const str) -{ - for (size_t i = 0; i < KERNEL_INFO_CMDLINE_SIZE_MAX; ++i) { - if (str[i] == '\0') return true; - } - - return false; -} diff --git a/src/info.h b/src/info.h deleted file mode 100644 index fb37241..0000000 --- a/src/info.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef KERNEL_INCLUDED_INFO -#define KERNEL_INCLUDED_INFO 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -#include -#include - -#define KERNEL_INFO_CMDLINE_SIZE_MAX 256 -#define KERNEL_INFO_CMDLINE_SLEN_MAX (KERNEL_INFO_CMDLINE_SIZE_MAX - 1) - -#define KERNEL_INFO_MODULES_MAX 20 -#define KERNEL_INFO_AREAS_MAX 20 - -struct Kernel_Info_Module { - size_t base; - size_t size; - size_t limit; - - char cmdline[KERNEL_INFO_CMDLINE_SIZE_MAX]; -}; - -struct Kernel_Info_Area { - // We use uint64_t instead of size_t because it what Multiboot 2 gives us. - uint64_t base; - uint64_t size; - uint64_t limit; - - bool is_available; -}; - -struct Kernel_Info { - bool initialized; - - char cmdline[KERNEL_INFO_CMDLINE_SIZE_MAX]; - - struct Kernel_Info_Module modules[KERNEL_INFO_MODULES_MAX]; - size_t modules_count; - - struct Kernel_Info_Area areas[KERNEL_INFO_AREAS_MAX]; - size_t areas_count; - - // Higher-half offset, typically 3 GiB - size_t kernel_offset; - size_t kernel_size; - size_t kernel_phys_base; - size_t kernel_virt_base; - - size_t modules_total_size; - size_t kernel_and_modules_total_size; - - size_t kernel_stack_start; - size_t kernel_stack_size; -}; - -void kernel_info_init_start( - struct Kernel_Info *kinfo, - size_t offset, - size_t size, - size_t phys_base, - size_t virt_base, - size_t stack_start, - size_t stack_size -); - -void kernel_info_init_finish(struct Kernel_Info *kinfo); - -void kernel_info_init_from_multiboot2( - struct Kernel_Info *kinfo, - const struct KernAux_Multiboot2_Info *multiboot2_info -); - -bool kernel_info_is_valid(const struct Kernel_Info *kinfo); -void kernel_info_print(const struct Kernel_Info *kinfo); -void kernel_info_setup_pfa(const struct Kernel_Info *kinfo, KernAux_PFA pfa); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/main.c b/src/main.c index 3e323f6..23c90ae 100644 --- a/src/main.c +++ b/src/main.c @@ -1,13 +1,10 @@ #define KERNAUX_ACCESS_PROTECTED -#include "paging.h" - -#include "info.h" - #include "heap.h" +#include "interrupts.h" +#include "paging.h" #include "panic.h" #include "protected.h" -#include "interrupts.h" #include #include @@ -32,7 +29,6 @@ extern uint8_t _kernel_stack_size; static KernAux_Memmap memmap = NULL; -static struct Kernel_Info kinfo; static struct KernAux_PFA pfa; static struct Paging paging; @@ -83,35 +79,20 @@ void main( KernAux_Memmap_print(memmap, &display); } - kernel_info_init_start( - &kinfo, - (size_t)&_kernel_offset, - (size_t)&_kernel_size, - (size_t)&_kernel_phys_base, - (size_t)&_kernel_virt_base, - (size_t)&_kernel_stack_start, - (size_t)&_kernel_stack_size - ); - kernel_info_init_from_multiboot2(&kinfo, multiboot2_info); - kernel_info_init_finish(&kinfo); - kernel_info_print(&kinfo); - assert(kernel_info_is_valid(&kinfo), "Invalid kernel information."); - KernAux_PFA_initialize(&pfa); - kernel_info_setup_pfa(&kinfo, &pfa); // TODO: maybe rename to init? paging_clear(&paging); paging_identity(&paging); - paging_mapkernel(&paging, &kinfo); + paging_mapkernel(&paging); paging_load(&paging); paging_enable(); interrupts_init(); - protected_initialize(&kinfo); + protected_initialize(); drivers_console_puts("[INFO] main: Finished."); } diff --git a/src/paging.c b/src/paging.c index dad8886..15cc02b 100644 --- a/src/paging.c +++ b/src/paging.c @@ -5,6 +5,10 @@ #include +extern uint8_t _kernel_size; +extern uint8_t _kernel_phys_base; +extern uint8_t _kernel_virt_base; + static void mapping(struct Paging *paging, uint32_t virt, uint32_t phys); void paging_load(struct Paging *const paging) @@ -56,18 +60,16 @@ void paging_identity(struct Paging *const paging) } } -void paging_mapkernel( - struct Paging *const paging, - const struct Kernel_Info *const kinfo -) { - assert(!(kinfo->kernel_phys_base % KERNAUX_ARCH_I386_PAGE_SIZE), "Kernel physical address is not aligned."); - assert(!(kinfo->kernel_virt_base % KERNAUX_ARCH_I386_PAGE_SIZE), "Kernel virtual address is not aligned."); +void paging_mapkernel(struct Paging *const paging) +{ + assert(!((size_t)&_kernel_phys_base % KERNAUX_ARCH_I386_PAGE_SIZE), "Kernel physical address is not aligned."); + assert(!((size_t)&_kernel_virt_base % KERNAUX_ARCH_I386_PAGE_SIZE), "Kernel virtual address is not aligned."); - size_t phys = kinfo->kernel_phys_base; - size_t virt = kinfo->kernel_virt_base; + size_t phys = (size_t)&_kernel_phys_base; + size_t virt = (size_t)&_kernel_virt_base; size_t mapped = 0; - while (mapped < kinfo->kernel_size) { + while (mapped < (size_t)&_kernel_size) { mapping(paging, virt, phys); phys += KERNAUX_ARCH_I386_PAGE_SIZE; diff --git a/src/paging.h b/src/paging.h index 129c100..2e9a9c8 100644 --- a/src/paging.h +++ b/src/paging.h @@ -2,7 +2,6 @@ #define KERNEL_INCLUDED_PAGING 1 #include "config.h" -#include "info.h" #include @@ -25,6 +24,6 @@ void paging_enable(); void paging_clear(struct Paging *paging); void paging_identity(struct Paging *paging); -void paging_mapkernel(struct Paging *paging, const struct Kernel_Info *kinfo); +void paging_mapkernel(struct Paging *paging); #endif diff --git a/src/protected.c b/src/protected.c index c2e860b..3a0031c 100644 --- a/src/protected.c +++ b/src/protected.c @@ -1,7 +1,6 @@ #include "protected.h" #include "config.h" -#include "info.h" #include "interrupts.h" #include @@ -12,6 +11,8 @@ #include #include +extern uint8_t _kernel_stack_end; + static struct KernAux_Arch_I386_DTR gdt_pointer; static struct KernAux_Arch_I386_DTE gdt_entries[GDT_SIZE]; @@ -19,7 +20,7 @@ static struct KernAux_Arch_I386_TSS tss; static void gdt_set_gates(); -void protected_initialize(const struct Kernel_Info *const kinfo) +void protected_initialize() { drivers_intel_8259_pic_remap(32, 40); drivers_intel_8259_pic_disable_all(); @@ -33,7 +34,7 @@ void protected_initialize(const struct Kernel_Info *const kinfo) drivers_console_puts("[INFO] protected: Setup TSS."); memset(&tss, 0, sizeof(tss)); tss.ss0 = GDT_KERNEL_DS_SELECTOR; - tss.esp0 = kinfo->kernel_stack_start + kinfo->kernel_stack_size; + tss.esp0 = (uint32_t)&_kernel_stack_end; drivers_console_puts("[INFO] protected: Load GDT."); gdt_pointer.size = sizeof(struct KernAux_Arch_I386_DTE) * GDT_SIZE - 1; diff --git a/src/protected.h b/src/protected.h index 49dc5d9..6c42211 100644 --- a/src/protected.h +++ b/src/protected.h @@ -1,8 +1,6 @@ #ifndef KERNEL_INCLUDED_PROTECTED #define KERNEL_INCLUDED_PROTECTED 1 -#include "info.h" - -void protected_initialize(const struct Kernel_Info *kinfo); +void protected_initialize(); #endif