diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86_64/boot/limine/memorymap.c | 2 | ||||
-rw-r--r-- | arch/x86_64/elf.c | 27 | ||||
-rw-r--r-- | arch/x86_64/init.c | 63 | ||||
-rw-r--r-- | arch/x86_64/lib/object.c | 59 | ||||
-rw-r--r-- | arch/x86_64/memory/koentry-ptr.c | 16 | ||||
-rw-r--r-- | arch/x86_64/memory/message.c | 40 | ||||
-rw-r--r-- | arch/x86_64/memory/page-mapping.c | 34 | ||||
-rw-r--r-- | arch/x86_64/memory/pml4.c (renamed from arch/x86_64/memory/page_directory.c) | 86 | ||||
-rw-r--r-- | arch/x86_64/memory/untyped_retype_page.c | 38 | ||||
-rw-r--r-- | arch/x86_64/syscall/invoke-mapping.c | 8 | ||||
-rw-r--r-- | arch/x86_64/syscall/wrappers.h | 2 | ||||
-rw-r--r-- | arch/x86_64/usermode.c | 137 |
12 files changed, 239 insertions, 273 deletions
diff --git a/arch/x86_64/boot/limine/memorymap.c b/arch/x86_64/boot/limine/memorymap.c index ec0f545..43aecf7 100644 --- a/arch/x86_64/boot/limine/memorymap.c +++ b/arch/x86_64/boot/limine/memorymap.c @@ -31,7 +31,7 @@ boot_populate_untyped(void) if(entry->type != LIMINE_MEMMAP_USABLE) continue; size_t table_index = s_untyped_dir.self.data++; - uintmax_t *untyped_data = vmem_phys_tovirt(entry->base); + uintmax_t *untyped_data = pptr_tovirt_ident(entry->base); objdir_entry_t *table_entry = &s_untyped_dir.entries[table_index]; table_entry->type = KO_MEMORY_UNTYPED; diff --git a/arch/x86_64/elf.c b/arch/x86_64/elf.c new file mode 100644 index 0000000..696b7a7 --- /dev/null +++ b/arch/x86_64/elf.c @@ -0,0 +1,27 @@ +#include "elf.h" +#include <stddef.h> + +int +elf64_ehdr_valid(Elf64_Ehdr *ehdr) +{ + if(ehdr->e_ident[EI_MAG0] != ELFMAG0 || + ehdr->e_ident[EI_MAG1] != ELFMAG1 || + ehdr->e_ident[EI_MAG2] != ELFMAG2 || + ehdr->e_ident[EI_MAG3] != ELFMAG3) + return 0; + if(ehdr->e_ident[EI_CLASS] != ELFCLASS64) return 0; + if(ehdr->e_ident[EI_DATA] != ELFDATA2LSB) return 0; + if(ehdr->e_type != ET_EXEC) return 0; + if(ehdr->e_machine != EM_X86_64) return 0; + + return 1; +} + +void* +elf64_loadexec(Elf64_Ehdr *ehdr) +{ + if(!elf64_ehdr_valid(ehdr)) return NULL; + + void *entry = (void*)ehdr->e_entry; + return entry; +} diff --git a/arch/x86_64/init.c b/arch/x86_64/init.c new file mode 100644 index 0000000..4ec7718 --- /dev/null +++ b/arch/x86_64/init.c @@ -0,0 +1,63 @@ +#include "init.h" +#include "arch/x86_64/page.h" +#include "device/processor.h" + +uintptr_t +init_alloc_pageframe() +{ + objdir_entry_t *untyped_dir_entry = &_initDirectory.entries[INIT_OBJECT_UNTYPED_DIR]; + objdir_t *untyped_dir = ko_entry_data(untyped_dir_entry); + + /*Seek to the last member of untyped directory.*/ + uint8_t lastmembi = 1; + for(; untyped_dir->entries[lastmembi].type == KO_MEMORY_UNTYPED; lastmembi++); + objdir_entry_t *lastmemb = &untyped_dir->entries[lastmembi]; + + objdir_entry_t pageframe; + ko_untyped_split(lastmemb, &pageframe, 0x1000); + return pageframe.data; +} + +void +init_map_pageframe(uintptr_t pptr, uintptr_t vptr, uint8_t pflags) +{ + uint64_t pathval; + uint16_t *path = (uint16_t*)&pathval; + pml4_get_path(vptr, 4, path); + + processor_t *proc = processor_current(); + pmle_t *pml4 = pptr_tovirt_ident(proc->pdir); + + pmle_t *pmld = pml4; + for(uint8_t d = 0; d < 3; d++) { + uint16_t pmli = path[d]; + pmle_t *pmle = &pmld[pmli]; + if(!pmle->p) { + pmle->value = init_alloc_pageframe() | PAGE_PRESENT | PAGE_RW | PAGE_US; + } + pmld = pptr_tovirt_ident(pmle->paddr << 12); + } + pmld[path[3]].value = pptr | pflags; + __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); +} + +void +init_ensure_page(uintptr_t vptr, uint8_t pflags) +{ + uint64_t pathval; + uint16_t *path = (uint16_t*)&pathval; + pml4_get_path(vptr, 4, path); + + processor_t *proc = processor_current(); + pmle_t *pml4 = pptr_tovirt_ident(proc->pdir); + + pmle_t *pmld = pml4, *pmle; + for(uint8_t d = 0; d < 4; d++) { + uint16_t pmli = path[d]; + pmle = &pmld[pmli]; + if(!pmle->p) { + pmle->value = init_alloc_pageframe() | (d == 3 ? pflags : PAGE_PRESENT | PAGE_RW | PAGE_US); + } + pmld = pptr_tovirt_ident(pmle->paddr << 12); + } +} diff --git a/arch/x86_64/lib/object.c b/arch/x86_64/lib/object.c new file mode 100644 index 0000000..4ab8f06 --- /dev/null +++ b/arch/x86_64/lib/object.c @@ -0,0 +1,59 @@ +#include "object.h" +#include "error.h" +#include "device/processor.h" +#include "arch/x86_64/page.h" +#include "arch/x86_64/page-mapping.h" + +void* +ko_entry_data(objdir_entry_t *entry) +{ + if((intmax_t)entry->data < 0) return (void*)entry->data; + return pptr_tovirt_ident(entry->data); +} + +uintptr_t +ko_data_toentry(uintptr_t vptr) +{ + return vptr_tophys((void*)vptr); +} + +int +ko_message_unmap(objdir_entry_t *message, uintptr_t *saveptr) +{ + /* message data should point to the virtual address. */ + /* If it doesn't, fail*/ + if(!(message->extra & KODE_EX_MESSAGE_MAPPED)) return KE_BADCALL; + uintptr_t vptr = message->data; + + processor_t *cproc = processor_current(); + pmle_t *pml4 = pptr_tovirt_ident(cproc->pdir); + + pmle_t *message_pmle = pml4_get_mapping(pml4, 4, vptr); + *saveptr = (uintptr_t)pptr_tovirt_ident(message_pmle->paddr << 12); + + message_pmle->p = 0; + __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); + + message->extra &= ~KODE_EX_MESSAGE_MAPPED; + return 0; +} + +int +ko_message_remap(objdir_entry_t *message) +{ + if(message->extra & KODE_EX_MESSAGE_MAPPED) return KE_BADCALL; + uintptr_t vptr = message->data; + + processor_t *cproc = processor_current(); + pmle_t *pml4 = pptr_tovirt_ident(cproc->pdir); + + pmle_t *message_pmle = pml4_get_mapping(pml4, 4, vptr); + + message_pmle->p = 1; + __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); + + message->extra |= KODE_EX_MESSAGE_MAPPED; + return 0; +} + +void ko_message_move(objdir_entry_t *message, uintptr_t vptr); diff --git a/arch/x86_64/memory/koentry-ptr.c b/arch/x86_64/memory/koentry-ptr.c deleted file mode 100644 index b32d4e7..0000000 --- a/arch/x86_64/memory/koentry-ptr.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "memory.h" -#include "arch/x86_64/page.h" -#include <stdint.h> - -void* -ko_entry_data(objdir_entry_t *entry) -{ - if((intmax_t)entry->data < 0) return (void*)entry->data; - return vmem_phys_tovirt(entry->data); -} - -uintptr_t -ko_data_toentry(uintptr_t vptr) -{ - return vmem_ident_tophys((void*)vptr); -} diff --git a/arch/x86_64/memory/message.c b/arch/x86_64/memory/message.c index 1fbdfc8..d5bedb7 100644 --- a/arch/x86_64/memory/message.c +++ b/arch/x86_64/memory/message.c @@ -6,43 +6,3 @@ #include "arch/x86_64/page-mapping.h" #include "print.h" -int -ko_message_unmap(objdir_entry_t *message, uintptr_t *saveptr) -{ - /* message data should point to the virtual address. */ - /* If it doesn't, fail*/ - if(!(message->extra & KODE_EX_MESSAGE_MAPPED)) return KE_BADCALL; - uintptr_t vptr = message->data; - - processor_t *cproc = processor_current(); - pmle_t *pml4 = vmem_phys_tovirt(cproc->pdir); - - pmle_t *message_pmle = mem_mapping_vptr_mapping(pml4, 4, vptr); - *saveptr = (uintptr_t)vmem_phys_tovirt(message_pmle->paddr << 12); - - message_pmle->p = 0; - __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); - - message->extra &= ~KODE_EX_MESSAGE_MAPPED; - return 0; -} - -int -ko_message_remap(objdir_entry_t *message) -{ - if(message->extra & KODE_EX_MESSAGE_MAPPED) return KE_BADCALL; - uintptr_t vptr = message->data; - - processor_t *cproc = processor_current(); - pmle_t *pml4 = vmem_phys_tovirt(cproc->pdir); - - pmle_t *message_pmle = mem_mapping_vptr_mapping(pml4, 4, vptr); - - message_pmle->p = 1; - __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); - - message->extra |= KODE_EX_MESSAGE_MAPPED; - return 0; -} - -void ko_message_move(objdir_entry_t *message, uintptr_t vptr); diff --git a/arch/x86_64/memory/page-mapping.c b/arch/x86_64/memory/page-mapping.c index d4b4e98..bbf210a 100644 --- a/arch/x86_64/memory/page-mapping.c +++ b/arch/x86_64/memory/page-mapping.c @@ -1,28 +1,28 @@ #include "arch/x86_64/page-mapping.h" #include "arch/x86_64/page.h" +#include "memory.h" +#include "error.h" #include <stddef.h> #include "print.h" -pmle_t* -page_mapping_traverse(pmle_t *pml4, uint8_t depth, uint16_t *path) +void +mapping_setup_init() { - uint16_t pathi = path[0]; - - pmle_t *pmle = &pml4[pathi]; - pmle_t *pmle_table = vmem_phys_tovirt(pmle->paddr << 12); - if(depth == 0) return pmle; - if(!pmle->p) return NULL; - return page_mapping_traverse(pmle_table, depth - 1, path + 1); + pml4_setup_init(); } -pmle_t* -mem_mapping_vptr_mapping(pmle_t *pml4, uint8_t depth, uintptr_t vptr) +void +mapping_setup(objdir_entry_t *mapping) { - uint64_t pathval = 0; - uint16_t *path = (uint16_t*)&pathval; + pmle_t *pml4 = (pmle_t*)ko_entry_data(mapping); + pml4_setup(pml4); +} - for(uint8_t i = 0; i < depth; i++) { - path[i] = PML_I_FOR_LAYER(vptr, 4 - i); - } - return page_mapping_traverse(pml4, depth - 1, path); +int +mapping_try_map_obj(objdir_entry_t *mapping, uintptr_t vptr, objdir_entry_t *obj) +{ + if(vptr & 0xFFFF800000000000) return KE_OOB; + pmle_t *pml4 = (pmle_t*)ko_entry_data(mapping); + uintptr_t pptr = (uintptr_t)ko_entry_data(obj); + return pml4_try_map(pml4, pptr, vptr); } diff --git a/arch/x86_64/memory/page_directory.c b/arch/x86_64/memory/pml4.c index 11e4861..fcfc897 100644 --- a/arch/x86_64/memory/page_directory.c +++ b/arch/x86_64/memory/pml4.c @@ -5,37 +5,78 @@ #include "object.h" #include "string.h" #include "jove.h" +#include "error.h" #include <stdint.h> +#define IDENTITY_BASE 0xFFFF800000000000 +uintptr_t vptr_tophys(void *vptr) +{ + return ((uintptr_t)vptr) - IDENTITY_BASE; +} + physptr_t -vmem_tophys_koff(virtptr_t v) +vptr_tophys_koff(virtptr_t v) { return v - (physptr_t)&_kernel_start + _boot_kernel_phys_base; } -#define IDENTITY_BASE 0xFFFF800000000000 void* -vmem_phys_tovirt(physptr_t p) +pptr_tovirt_ident(physptr_t p) { return (void*)(p + IDENTITY_BASE); } -uintptr_t vmem_ident_tophys(void *vptr) -{ - return ((uintptr_t)vptr) - IDENTITY_BASE; -} - void* pmle_get_page(pmle_t entry) { uintptr_t pptr = entry.paddr << 12; - return vmem_phys_tovirt(pptr); + return pptr_tovirt_ident(pptr); +} + +void +pml4_get_path(uintptr_t vptr, uint8_t depth, uint16_t *path) +{ + for(uint8_t i = 0; i < depth; i++) { + path[i] = PML_I_FOR_LAYER(vptr, 4 - i); + } } -uint8_t -pmle_level(pmle_t entry) +pmle_t* +pml4_traverse(pmle_t *pml4, uint8_t depth, uint16_t *path) { - return entry.osflg; + uint16_t pathi = path[0]; + + pmle_t *pmle = &pml4[pathi]; + pmle_t *pmle_table = pptr_tovirt_ident(pmle->paddr << 12); + if(depth == 0) return pmle; + if(!pmle->p) return NULL; + return pml4_traverse(pmle_table, depth - 1, path + 1); +} + +pmle_t* +pml4_get_mapping(pmle_t *pml4, uint8_t depth, uintptr_t vptr) +{ + uint64_t pathval = 0; + uint16_t *path = (uint16_t*)&pathval; + + pml4_get_path(vptr, depth, path); + return pml4_traverse(pml4, depth - 1, path); +} + +int +pml4_try_map(pmle_t *pml4, uintptr_t pptr, uintptr_t vptr) +{ + uint64_t pathval = 0; + uint16_t *path = (uint16_t*)&pathval; + + pml4_get_path(vptr, 4, path); + pmle_t *mapping = pml4_traverse(pml4, 3, path); + + if(mapping == NULL) return KE_DNE; + if(mapping->p) return KE_FULL; + + mapping->value = pptr | PAGE_PRESENT | PAGE_RW | PAGE_US; + return KE_OK; } __attribute__((aligned(0x1000))) pmle_t s_kernel_pml4[512]; // Page L4 @@ -47,7 +88,7 @@ __attribute__((aligned(0x1000))) pmle_t s_idmap_pml3[512]; __attribute__((aligned(0x1000))) pmle_t s_idmap_pml2[512]; void -vmem_setup(void) +pml4_setup_init(void) { memset(s_kernel_pml4, 0, 0x1000); memset(s_kernel_pml3, 0, 0x1000); @@ -63,13 +104,13 @@ vmem_setup(void) size_t kernel_size = kernel_end - kernel_start; size_t kernel_size_pages = (kernel_size / 0x1000) + 1; - physptr_t kernel_pml4_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml4); - physptr_t kernel_pml3_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml3); - physptr_t kernel_pml2_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml2); - physptr_t kernel_pml1_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml1); + physptr_t kernel_pml4_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml4); + physptr_t kernel_pml3_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml3); + physptr_t kernel_pml2_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml2); + physptr_t kernel_pml1_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml1); - physptr_t idmap_pml3_base = vmem_tophys_koff((virtptr_t)&s_idmap_pml3); - physptr_t idmap_pml2_base = vmem_tophys_koff((virtptr_t)&s_idmap_pml2); + physptr_t idmap_pml3_base = vptr_tophys_koff((virtptr_t)&s_idmap_pml3); + physptr_t idmap_pml2_base = vptr_tophys_koff((virtptr_t)&s_idmap_pml2); processor_t *processor = processor_current(); processor->pdir = kernel_pml4_base; @@ -103,3 +144,10 @@ vmem_setup(void) .data = kernel_pml4_base }; } + +void +pml4_setup(pmle_t *pml4) +{ + memset(pml4, 0, 0x800); + memcpy(&pml4[256], &s_kernel_pml4[256], 0x800); +} diff --git a/arch/x86_64/memory/untyped_retype_page.c b/arch/x86_64/memory/untyped_retype_page.c deleted file mode 100644 index 32afe2c..0000000 --- a/arch/x86_64/memory/untyped_retype_page.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "memory.h" -#include "arch/x86_64/page.h" -#include "print.h" -#include <stddef.h> - -static int -s_untyped_retype( - objdir_entry_t *untyped_entry, - size_t size, - size_t align, - void **dest) -{ - if(untyped_entry->type != KO_MEMORY_UNTYPED) return -1; - if((untyped_entry->data & (align - 1)) != 0) return -2; //EALIGN - - uintptr_t *untyped_data = vmem_phys_tovirt(untyped_entry->data); - uintmax_t untyped_size = *untyped_data; - - if(untyped_size <= size) { - return -3; - } - - *untyped_data -= size; - *dest = (void*)(untyped_entry->data + untyped_size - size); - - return 0; -} - -int untyped_retype_page(objdir_entry_t *untyped_entry, void **dest) -{ - int r = s_untyped_retype(untyped_entry, 0x1000, 0x1000, dest); - if(r != 0) return r; - - #ifdef DBG_MEM - klogf("Untyped block %p retyped to page at %p\n", untyped_entry->data, *dest); - #endif - return r; -} diff --git a/arch/x86_64/syscall/invoke-mapping.c b/arch/x86_64/syscall/invoke-mapping.c index be401d6..5fde8be 100644 --- a/arch/x86_64/syscall/invoke-mapping.c +++ b/arch/x86_64/syscall/invoke-mapping.c @@ -16,7 +16,7 @@ s_handle_invoke_mapping_exists( size_t payload_at ) { - pmle_t *pml4 = (pmle_t*)vmem_phys_tovirt(target_entry->data); + pmle_t *pml4 = (pmle_t*)pptr_tovirt_ident(target_entry->data); pmle_t *target_pml; uint8_t target_depth; SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml); @@ -36,7 +36,7 @@ s_handle_invoke_mapping_map( size_t payload_at ) { - pmle_t *pml4 = (pmle_t*)vmem_phys_tovirt(target_entry->data); + pmle_t *pml4 = (pmle_t*)pptr_tovirt_ident(target_entry->data); pmle_t *target_pml; uint8_t target_depth; SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml); @@ -85,7 +85,7 @@ s_handle_invoke_mapping_unmap( size_t payload_at ) { - pmle_t *pml4 = (pmle_t*)vmem_phys_tovirt(target_entry->data); + pmle_t *pml4 = (pmle_t*)pptr_tovirt_ident(target_entry->data); pmle_t *target_pml; uint8_t target_depth; SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml); @@ -105,7 +105,7 @@ s_handle_invoke_mapping_unmap( if(dest_entry->type != KO_NONE) return KE_FULL; uintptr_t pmle_addr = target_pml->paddr << 12; - size_t *untyped = vmem_phys_tovirt(pmle_addr); + size_t *untyped = pptr_tovirt_ident(pmle_addr); __asm__ volatile("invlpg (%0)":: "r"(untyped): "memory"); *untyped = 0x1000; diff --git a/arch/x86_64/syscall/wrappers.h b/arch/x86_64/syscall/wrappers.h index a6fdf88..0803262 100644 --- a/arch/x86_64/syscall/wrappers.h +++ b/arch/x86_64/syscall/wrappers.h @@ -8,7 +8,7 @@ SYSCALL_PAYLOAD_TAKEL(payload, at, depth, uint8_t); \ if(((depth + 1) * sizeof(uint16_t)) + at >= KO_MESSAGE_BYTES) return KE_BADMSG; \ if(depth == 0 && *(uint16_t*)&payload[at] > 255) return KE_OOB; \ - pml = page_mapping_traverse(pml4, depth, (uint16_t*)&payload[at]); \ + pml = pml4_traverse(pml4, depth, (uint16_t*)&payload[at]); \ at += (depth + 1) * sizeof(uint16_t) #endif diff --git a/arch/x86_64/usermode.c b/arch/x86_64/usermode.c index aa626a9..8975993 100644 --- a/arch/x86_64/usermode.c +++ b/arch/x86_64/usermode.c @@ -1,76 +1,4 @@ -#include "arch/x86_64/object.h" -#include "object.h" -#include "bootargs.h" -#include "device/initrd.h" -#include "object.h" -#include "panic.h" -#include "string.h" -#include "device/processor.h" -#include "arch/x86_64/page.h" -#include "print.h" -static tcb_t s_init_tcb; - -//Dynamic allocation hell!!! -static uintptr_t -s_new_mapping(objdir_t *untyped_dir) -{ - objdir_entry_t *untyped_entry = NULL; - for(int i = untyped_dir->self.data - 1; i != 0; i--) { - untyped_entry = &untyped_dir->entries[i]; - if(untyped_entry->type != KO_MEMORY_UNTYPED) continue; - uintptr_t mapping = 0; - int err = untyped_retype_page(untyped_entry, (void**)&mapping); - if(err != 0) continue; - return mapping; - } - kpanic("Could not allocate page for init\n"); -} - -static pmle_t* -s_ensure_mapping_layer(pmle_t *pml, objdir_t *untyped_dir, uintptr_t addr, uint8_t layer) -{ - pmli_t pmli = PML_I_FOR_LAYER(addr, layer); - if(pml[pmli].p) - return pmle_get_page(pml[pmli]); - - uintptr_t table_phys = s_new_mapping(untyped_dir); - pmle_t *table = vmem_phys_tovirt(table_phys); - memset(table, 0, 0x1000); - - pml[pmli] = (pmle_t) { - .p = 1, - .rw = 1, - .us = 1, - .osflg = (layer - 1) & 3, - .paddr = table_phys >> 12 - }; - __asm__ volatile("invlpg (%0)":: "r"(table_phys)); - return vmem_phys_tovirt(table_phys); -} - -static uintptr_t -s_map_page(pmle_t *pml4, objdir_t *untyped_dir, uintptr_t addr) -{ - pmle_t *pml3 = s_ensure_mapping_layer(pml4, untyped_dir, addr, 4); - pmle_t *pml2 = s_ensure_mapping_layer(pml3, untyped_dir, addr, 3); - pmle_t *pml1 = s_ensure_mapping_layer(pml2, untyped_dir, addr, 2); - - pmli_t pml1i = PML_I_FOR_LAYER(addr, 1); - pmle_t *pmle = &pml1[pml1i]; - - uintptr_t pptr = s_new_mapping(untyped_dir); - - *pmle = (pmle_t) { - .p = 1, - .rw = 1, - .us = 1, - .osflg = 0, - .paddr = pptr >> 12 - }; - __asm__ volatile("invlpg (%0)":: "r"(addr)); - return pptr; -} __attribute__((noreturn)) static void @@ -85,68 +13,3 @@ s_enter_usermode(void *ip, void *sp) "r"(sp), "r"(ip): "memory"); for(;;); } - -void -init_load(void) -{ - const char *init_filename = bootargs_getarg("init"); - if(init_filename == NULL) { - kpanic("Missing boot argument \"init\""); - } - tar_header_t *init_header = initrd_find_file(init_filename); - if(init_header == NULL) { - kpanic("Init file not found in initrd. (expected \"%s\")", init_filename); - } - - _initDirectory.entries[INIT_OBJECT_TCB] = (objdir_entry_t) { - .type = KO_TCB, - .data = vmem_tophys_koff((uintptr_t)&s_init_tcb) - }; - - objdir_t *untyped_dir = (objdir_t*)_initDirectory.entries[INIT_OBJECT_UNTYPED_DIR].data; - pmle_t *pml4 = vmem_phys_tovirt(_initDirectory.entries[INIT_OBJECT_PAGEMAP].data & ~3ULL); - - //Reserve and map pages for init binary - size_t init_size = initrd_file_size(init_header); - - size_t init_pages = (init_size >> 12); - uintptr_t init_base = 0x1000; - - for(size_t i = 0; i < init_pages + 1; i++) { - s_map_page(pml4, untyped_dir, init_base + (i * 0x1000)); - } - //Copy over init data - memcpy((void*)init_base, (&((tar_block_t*)init_header)[1])->data, init_size); - - //Create a user stack - uintptr_t stack_base = 0x00007FFFFFFFF000; - s_map_page(pml4, untyped_dir, stack_base); - uintptr_t sp = stack_base + 0xFF0; - - //Create a kernel stack for the init TCB - uintptr_t ksp_base = (uintptr_t)&s_init_tcb.kstack; - s_init_tcb.ksp = ksp_base + 0xFF0; - - processor_t *proc = (processor_t*)processor_current(); - proc->tss.rsp0 = s_init_tcb.ksp; - klogf("RSP0 %p\n", s_init_tcb.ksp); - - //Create a message object for init - uintptr_t message_base = init_base + (init_pages << 12); - message_base += ((~(message_base & 0xFFF)) & 0xFFF) + 1; - - uintptr_t message_phys = s_map_page(pml4, untyped_dir, message_base); - _initDirectory.entries[INIT_OBJECT_MESSAGE] = (objdir_entry_t) { - .type = KO_MESSAGE, - .extra = KODE_EX_MESSAGE_MAPPED, - .data = message_base - }; - - //Write message address to user stack. - sp -= sizeof(uintptr_t); - *((uintptr_t*)sp) = message_base; - - //Setup usermode and jump - proc->tcb = &s_init_tcb; - s_enter_usermode((void*)init_base, (void*)sp); -} |