diff options
| author | Jon Santmyer <jon@jonsantmyer.com> | 2026-09-04 19:18:23 -0400 |
|---|---|---|
| committer | Jon Santmyer <jon@jonsantmyer.com> | 2026-09-04 19:18:23 -0400 |
| commit | 1768abb217f974cf96448ee847453b604800c546 (patch) | |
| tree | 2dccae458433118e02d25d82a66052a747c59c51 | |
| parent | 8251da342161767fe203627223ccd4a7026701c6 (diff) | |
| download | jove-kernel-1768abb217f974cf96448ee847453b604800c546.tar.gz jove-kernel-1768abb217f974cf96448ee847453b604800c546.tar.bz2 jove-kernel-1768abb217f974cf96448ee847453b604800c546.zip | |
add generic initrd seek function. begin work on init loading
| -rw-r--r-- | arch/x86_64/boot/limine/framebuffer.c | 18 | ||||
| -rw-r--r-- | arch/x86_64/hal/obj.h | 2 | ||||
| -rw-r--r-- | arch/x86_64/hal/paging.c | 34 | ||||
| -rw-r--r-- | arch/x86_64/hal/paging.h | 2 | ||||
| -rw-r--r-- | arch/x86_64/hal/process.c | 2 | ||||
| -rw-r--r-- | arch/x86_64/main.c | 2 | ||||
| -rw-r--r-- | arch/x86_64/sys/init.c | 53 | ||||
| -rw-r--r-- | boot/initrd.c | 49 | ||||
| -rw-r--r-- | boot/initrd.h | 8 | ||||
| -rw-r--r-- | config.h | 5 | ||||
| -rw-r--r-- | hal/obj.h | 2 | ||||
| -rw-r--r-- | init.h | 9 | ||||
| -rw-r--r-- | lib/virtterm.c | 22 |
13 files changed, 157 insertions, 51 deletions
diff --git a/arch/x86_64/boot/limine/framebuffer.c b/arch/x86_64/boot/limine/framebuffer.c index aa93496..ea7c714 100644 --- a/arch/x86_64/boot/limine/framebuffer.c +++ b/arch/x86_64/boot/limine/framebuffer.c @@ -2,6 +2,7 @@ #include "jove.h" #include "config.h" #include "hal/framebuffer.h" +#include "lib/string.h" #include "lib/printf.h" /*We don't know the size of the framebuffer until runtime, but at the same @@ -14,6 +15,7 @@ #define FRAMEBUFFER_MAX_GIANTPAGES ((FRAMEBUFFER_MAX_HUGEPAGES + 511) / 512) PAGEALIGN static page_t fb_pml2[FRAMEBUFFER_MAX_GIANTPAGES][512]; +PAGEALIGN static page_t fb_pml1[FRAMEBUFFER_MAX_HUGEPAGES][512]; extern page_t _kernel_pml3[512]; @@ -21,6 +23,9 @@ void* fb_remap(uintptr_t fb_address, size_t fb_bytes) { + memset(fb_pml2, 0, 0x1000 * FRAMEBUFFER_MAX_GIANTPAGES); + memset(fb_pml1, 0, 0x1000 * FRAMEBUFFER_MAX_HUGEPAGES); + fb_address &= ~IDENT_VIRT_BASE; size_t fb_pages = (fb_bytes + 4095) >> 12; size_t fb_hugepages = (fb_pages + 511) >> 9; @@ -32,15 +37,22 @@ fb_remap(uintptr_t fb_address, } for(size_t pml2 = 0; pml2 < fb_giantpages; pml2++) { - uintptr_t fb_pml2_pptr = KPTR_TOPHYS((uintptr_t)fb_pml2[pml2]); + uintptr_t fb_pml2_pptr = KPTR_TOPHYS(&fb_pml2[pml2]); _kernel_pml3[pml2].value = fb_pml2_pptr | PAGE_PRESENT | PAGE_GLOBAL | PAGE_WRITEABLE; } for(size_t pml1 = 0; pml1 < fb_hugepages; pml1++) { size_t pml2 = pml1 >> 9; size_t pml1_mod = pml1 % 512; - uintptr_t fb_off = fb_address + (pml1 << 21); - fb_pml2[pml2][pml1_mod].value = fb_off | PAGE_PRESENT | PAGE_GLOBAL | PAGE_WRITEABLE | PAGE_PS; + uintptr_t pml1_pptr = KPTR_TOPHYS(&fb_pml1[pml1]); + fb_pml2[pml2][pml1_mod].value = pml1_pptr | PAGE_PRESENT | PAGE_GLOBAL | PAGE_WRITEABLE; + } + + for(size_t pml0 = 0; pml0 < fb_pages; pml0++) { + size_t pml1 = pml0 >> 9; + size_t pml0_mod = pml0 % 512; + uintptr_t pml0_pptr = fb_address + (pml0 << 12); + fb_pml1[pml1][pml0_mod].value = pml0_pptr | PAGE_PRESENT | PAGE_GLOBAL | PAGE_WRITEABLE; } uintptr_t fb_virt = IDENT_VIRT_BASE | (511ULL << PMLI_SHL(3)); diff --git a/arch/x86_64/hal/obj.h b/arch/x86_64/hal/obj.h index 645727d..9569a8a 100644 --- a/arch/x86_64/hal/obj.h +++ b/arch/x86_64/hal/obj.h @@ -8,8 +8,6 @@ enum { JOVE_OBJ_SERIAL_COM = 0x81, - JOVE_OBJ_PAGE_FRAME, - JOVE_OBJ_PAGE_MAPPING, }; /*Represents a locked kernel object pointer inside of a object directory.*/ diff --git a/arch/x86_64/hal/paging.c b/arch/x86_64/hal/paging.c index c1a22a2..9ef67ab 100644 --- a/arch/x86_64/hal/paging.c +++ b/arch/x86_64/hal/paging.c @@ -1,8 +1,10 @@ #include "paging.h" #include "arch/x86_64/x86_64.h" #include "jove.h" +#include "init.h" #include "config.h" #include "smp.h" +#include "hal/obj.h" #include "lib/string.h" #include "lib/printf.h" #include "lib/panic.h" @@ -13,11 +15,11 @@ PAGEALIGN page_t _kernel_pml3[512]; PAGEALIGN page_t _kernel_pml2[512]; PAGEALIGN page_t _kernel_pml1[512]; -#define IDENT_HUGEPAGES ((PHYS_BIGPAGES_MAX + 511) / 512) -#define IDENT_GIANTPAGES ((IDENT_HUGEPAGES + 511) / 512) +#define IDENT_GIANTPAGES ((PHYS_HUGEPAGES_MAX + 511) / 512) +#define IDENT_MASSIVEPAGES ((IDENT_GIANTPAGES + 511) / 512) -PAGEALIGN static page_t ident_pml3[IDENT_GIANTPAGES][512]; -PAGEALIGN static page_t ident_pml2[IDENT_HUGEPAGES][512]; +PAGEALIGN static page_t ident_pml3[IDENT_MASSIVEPAGES][512]; +PAGEALIGN static page_t ident_pml2[IDENT_GIANTPAGES][512]; void* phys_tovirt(uintptr_t phys) @@ -80,6 +82,9 @@ paging_pml4_init(void) memset(_kernel_pml2, 0, 0x1000); memset(_kernel_pml1, 0, 0x1000); + memset(ident_pml3, 0, 0x1000 * IDENT_MASSIVEPAGES); + memset(ident_pml2, 0, 0x1000 * IDENT_GIANTPAGES); + /*Paging entries depend on physical addresses to properly map. * Since the virtual kernel address differs from the physical memory address, * we need to convert the pointers using the physical memory pointer passed @@ -140,24 +145,22 @@ paging_pml4_init(void) /*Identity pages are mapped as huge pages starting at the 256'th PML3 entry. *We want to support any range of physical memory up to several TiB, so *the mapper has to consider multiple heirarchies of huge pages.*/ - for(size_t l3 = 0; l3 < IDENT_GIANTPAGES; l3++) { - memset(ident_pml3[l3], 0, 0x1000); - uintptr_t ident_pml3_pptr = KPTR_TOPHYS((uintptr_t)ident_pml3[l3]); + + for(size_t l3 = 0; l3 < IDENT_MASSIVEPAGES; l3++) { + uintptr_t ident_pml3_pptr = KPTR_TOPHYS(&ident_pml3[l3]); _kernel_pml4[256 + l3].value = ident_pml3_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_GLOBAL; } - for(size_t l2 = 0; l2 < IDENT_HUGEPAGES; l2++) { + for(size_t l2 = 0; l2 < IDENT_GIANTPAGES; l2++) { size_t l3 = l2 / 512; size_t l2_mod = l2 % 512; - memset(ident_pml2[l2], 0, 0x1000); - uintptr_t ident_pml2_pptr = KPTR_TOPHYS((uintptr_t)ident_pml2[l2]); - + uintptr_t ident_pml2_pptr = KPTR_TOPHYS(&ident_pml2[l2]); ident_pml3[l3][l2_mod].value = ident_pml2_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_GLOBAL; } - for(size_t l1 = 0; l1 < PHYS_BIGPAGES_MAX; l1++) { + for(size_t l1 = 0; l1 < PHYS_HUGEPAGES_MAX; l1++) { size_t l2 = l1 / 512; size_t l1_mod = l1 % 512; @@ -167,6 +170,13 @@ paging_pml4_init(void) paging_pml4_switch(kernel_pml4_pptr); + { + jove_owned_obj_t *pgdir_o = obj_take(objdir_getlocal(_rootdir_obj, ROOTDIR_PAGEDIR_I)); + obj_settype(pgdir_o, JOVE_OBJ_PAGEDIR); + obj_setvalue(pgdir_o, kernel_pml4_pptr); + obj_release(pgdir_o); + } + /*Before tasking, if the kernel has a bug and crashes we need some * information about what happened.*/ extern struct int_stackframe *(*__int_handles[])(struct int_stackframe*); diff --git a/arch/x86_64/hal/paging.h b/arch/x86_64/hal/paging.h index 54df1eb..eb916a3 100644 --- a/arch/x86_64/hal/paging.h +++ b/arch/x86_64/hal/paging.h @@ -44,7 +44,7 @@ extern void *_kernel_physptr; #define IDENT_VIRT_BASE 0xFFFF800000000000ULL #define KERNEL_VIRT_BASE 0xFFFFFFFF80000000ULL -#define KPTR_TOPHYS(v) (v - KERNEL_VIRT_BASE + (uintptr_t)_kernel_physptr) +#define KPTR_TOPHYS(v) ((uintptr_t)v - KERNEL_VIRT_BASE + (uintptr_t)_kernel_physptr) uintptr_t paging_get_pml4(void); void paging_pml4_init(void); diff --git a/arch/x86_64/hal/process.c b/arch/x86_64/hal/process.c index dd49456..fb295c0 100644 --- a/arch/x86_64/hal/process.c +++ b/arch/x86_64/hal/process.c @@ -12,7 +12,7 @@ static pcb_t *s_init_pcb = (pcb_t*)&s_init_pcb_bytes; void processing_setup(void (*process_main)) { - uintptr_t ksp = (uintptr_t)&s_init_pcb_bytes + 8; + uintptr_t ksp = ((uintptr_t)&s_init_pcb_bytes) + 0xFF0; s_init_pcb->ksp = (void*)ksp; s_init_pcb->pml4 = paging_get_pml4(); diff --git a/arch/x86_64/main.c b/arch/x86_64/main.c index 44591a5..2d4599e 100644 --- a/arch/x86_64/main.c +++ b/arch/x86_64/main.c @@ -1,4 +1,5 @@ #include "jove.h" +#include "init.h" #include "lib/printf.h" #include "lib/virtterm.h" #include "lib/panic.h" @@ -44,5 +45,6 @@ kernel_entry(void) static void kernel_process_entry(void) { + init_setup(); kpanic("Reached the end of kernel main!\n"); } diff --git a/arch/x86_64/sys/init.c b/arch/x86_64/sys/init.c new file mode 100644 index 0000000..06fbe48 --- /dev/null +++ b/arch/x86_64/sys/init.c @@ -0,0 +1,53 @@ +#include "init.h" +#include "config.h" +#include "jove.h" +#include "hal/obj.h" +#include "lib/string.h" +#include "lib/panic.h" +#include "arch/x86_64/hal/paging.h" +#include "boot/cmdline.h" +#include "boot/initrd.h" + +#define INIT_PROGRAM_HUGEPAGES_MAX ((INIT_PROGRAM_PAGES_MAX + 511) / 512) +#define INIT_STACK_HUGEPAGES_MAX ((INIT_STACK_PAGES_MAX + 511) / 512) + +PAGEALIGN static page_t s_init_program_pml3[512]; +PAGEALIGN static page_t s_init_program_pml2[512]; +PAGEALIGN static page_t s_init_program_pml1[INIT_PROGRAM_HUGEPAGES_MAX][512]; + +PAGEALIGN static page_t s_init_stack_pml3[512]; +PAGEALIGN static page_t s_init_stack_pml2[512]; +PAGEALIGN static page_t s_init_stack_pml1[INIT_STACK_HUGEPAGES_MAX][512]; + +void +init_setup(void) +{ + memset(s_init_program_pml3, 0, 0x1000); + memset(s_init_program_pml2, 0, 0x1000); + memset(s_init_program_pml1, 0, 0x1000 * INIT_PROGRAM_HUGEPAGES_MAX); + + memset(s_init_stack_pml3, 0, 0x1000); + memset(s_init_stack_pml2, 0, 0x1000); + memset(s_init_stack_pml1, 0, 0x1000 * INIT_STACK_HUGEPAGES_MAX); + + uintptr_t init_program_pml3_pptr = KPTR_TOPHYS(s_init_program_pml3); + uintptr_t init_program_pml2_pptr = KPTR_TOPHYS(s_init_program_pml2); + uintptr_t init_program_pml1_pptr = KPTR_TOPHYS(s_init_program_pml1); + + uintptr_t init_stack_pml3_pptr = KPTR_TOPHYS(s_init_stack_pml3); + uintptr_t init_stack_pml2_pptr = KPTR_TOPHYS(s_init_stack_pml2); + uintptr_t init_stack_pml1_pptr = KPTR_TOPHYS(s_init_stack_pml1); + + //Get the init file data from the initrd. + const char *init_path = cmdline_getarg("init"); + if(init_path == NULL) { + kpanic("Kernel commandline is missing 'init' arg.\n"); + } + + jove_owned_obj_t *initrd_obj = obj_take(objdir_getlocal(_rootdir_obj, ROOTDIR_INITRD_I)); + jove_owned_obj_t *initfile_obj = initrd_seek(initrd_obj, init_path); + if(initfile_obj == NULL) { + kpanic("init: Cannot find file '%s' in initrd.\n", init_path); + } + obj_release(initrd_obj); +} diff --git a/boot/initrd.c b/boot/initrd.c index dc16d98..7f7a50c 100644 --- a/boot/initrd.c +++ b/boot/initrd.c @@ -1,8 +1,10 @@ #include "initrd.h" +#include "arch/x86_64/hal/obj.h" #include "init.h" #include "jove.h" #include "lib/printf.h" #include "lib/tar.h" +#include "lib/string.h" #include "hal/obj.h" #include "hal/memory.h" @@ -15,31 +17,54 @@ PAGEALIGN jove_objdir_t s_initrd_objdir = { 0 }; reterr(EBADOBJ); \ } -int -initrd_file_name(jove_owned_obj_t *obj, const char **nameptr) +const char* +initrd_file_name(jove_owned_obj_t *obj) { CHECK_IF_INITRD(obj); struct tar_header *file = obj_deref(obj); - *nameptr = tar_filename(file); - return 0; + return tar_filename(file); } -int -initrd_file_size(jove_owned_obj_t *obj, size_t *sizeptr) +size_t +initrd_file_size(jove_owned_obj_t *obj) { CHECK_IF_INITRD(obj); struct tar_header *file = obj_deref(obj); - *sizeptr = tar_filesize(file); - return 0; + return tar_filesize(file); } -int -initrd_file_data(jove_owned_obj_t *obj, uintptr_t *dataptr) +void* +initrd_file_data(jove_owned_obj_t *obj) { CHECK_IF_INITRD(obj); union tar_block *file = obj_deref(obj); - *dataptr = (uintptr_t)&file[1]; - return 0; + return &(file[1]); +} + +jove_owned_obj_t* +initrd_seek(jove_owned_obj_t *objdir, const char *path) +{ + if(obj_gettype(objdir) != JOVE_OBJ_OBJDIR) { + reterr(EBADOBJ); + } + for(size_t i = 0; i < JOVE_OBJDIR_ENTRIES; i++) { + jove_owned_obj_t *file_obj = obj_take(objdir_getlocal(objdir, i)); + if(obj_gettype(file_obj) != JOVE_OBJ_INITRD_FILE) { + goto loop_continue; + } + const char *filepath = initrd_file_name(file_obj); + if(filepath == NULL) { + goto loop_continue; + } + + if(strncmp(path, filepath, strlen(filepath)+1) == 0) { + return file_obj; + } +loop_continue: + obj_release(file_obj); + } + + return NULL; } void initrd_setup(void) diff --git a/boot/initrd.h b/boot/initrd.h index 9b3bba9..c56b6f8 100644 --- a/boot/initrd.h +++ b/boot/initrd.h @@ -3,9 +3,11 @@ #include "hal/obj.h" -int initrd_file_name(jove_owned_obj_t *obj, const char **nameptr); -int initrd_file_size(jove_owned_obj_t *obj, size_t *sizeptr); -int initrd_file_data(jove_owned_obj_t *obj, uintptr_t *dataptr); +const char *initrd_file_name(jove_owned_obj_t *obj); +size_t initrd_file_size(jove_owned_obj_t *obj); +void *initrd_file_data(jove_owned_obj_t *obj); + +jove_owned_obj_t *initrd_seek(jove_owned_obj_t *objdir, const char *name); void initrd_setup(void); @@ -4,9 +4,12 @@ #define CMDLINE_MAX_ARGUMENTS 128 #define SMP_PROCESSORS_MAX 8 -#define PHYS_BIGPAGES_MAX 512 +#define PHYS_HUGEPAGES_MAX 512 #define FRAMEBUFFER_MAX_WIDTH 1920 #define FRAMEBUFFER_MAX_HEIGHT 1080 +#define INIT_PROGRAM_PAGES_MAX 512 +#define INIT_STACK_PAGES_MAX 1 + #endif @@ -8,8 +8,10 @@ enum JOVE_OBJ_NONE = 0, JOVE_OBJ_UNTYPED, JOVE_OBJ_OBJDIR, + JOVE_OBJ_PAGEDIR, JOVE_OBJ_PROCESSOR, JOVE_OBJ_PROCESS, + JOVE_OBJ_PAGEFRAME, JOVE_OBJ_INITRD_FILE, JOVE_OBJ_FRAMEBUFFER, JOVE_OBJ_VIRTTERM @@ -4,12 +4,15 @@ extern void *_rootdir_obj; #define ROOTDIR_PROCESSORS_I 0x0 -#define ROOTDIR_UNTYPED_I 0x01 -#define ROOTDIR_PCB_I 0x02 -#define ROOTDIR_INITRD_I 0x03 +#define ROOTDIR_PAGEDIR_I 0x01 +#define ROOTDIR_UNTYPED_I 0x02 +#define ROOTDIR_PCB_I 0x03 +#define ROOTDIR_INITRD_I 0x04 #define ROOTDIR_SERIAL_COM_I 0x80 #define ROOTDIR_FRAMEBUFFER_I 0x81 #define ROOTDIR_VIRTTERM_I 0x82 +void init_setup(void); + #endif diff --git a/lib/virtterm.c b/lib/virtterm.c index de43c51..fddd4d1 100644 --- a/lib/virtterm.c +++ b/lib/virtterm.c @@ -93,30 +93,26 @@ vt_init() return; } - jove_owned_obj_t *file_obj; - size_t file_i = 0; - while((file_obj = obj_take(objdir_getlocal(initrd_obj, file_i++)))) { - const char *filename = NULL; - if(initrd_file_name(file_obj, &filename) != 0) { - break; - } - if(strncmp(font_path, filename, strlen(font_path)) == 0) { - initrd_file_data(file_obj, (uintptr_t*)&s_font); - break; - } + jove_owned_obj_t *file_obj = initrd_seek(initrd_obj, font_path); + if(file_obj != NULL) { + s_font = initrd_file_data(file_obj); obj_release(file_obj); } - obj_release(file_obj); + obj_release(initrd_obj); if(s_font == NULL) { kprintf("Could not find file %s in initrd. VTT is disabled.\n", font_path); return; } + if(s_font->magic != PSF1_FONT_MAGIC) { + kprintf("Font '%s' does not match magic number! VTT is disabled.\n", font_path); + return; + } + s_init_vtty.fb_obj = ROOTDIR_FRAMEBUFFER_I; s_init_vtty.cursor_fg = 0x00FFFFFF; - { jove_owned_obj_t *fb_obj = obj_take(objdir_getlocal(_rootdir_obj, ROOTDIR_FRAMEBUFFER_I)); s_init_vtty.width = fb_width(fb_obj) / 9; |
