diff --git a/project.json b/project.json index f370016..4a0e402 100644 --- a/project.json +++ b/project.json @@ -6,6 +6,10 @@ "cute-engineering/libheap": { "git": "https://github.com/cute-engineering/libheap.git", "tag": "v1.1.0" + }, + "cute-engineering/handover": { + "git": "https://github.com/cute-engineering/handover.git", + "tag": "v1.4.0" } } } diff --git a/src/kernel/archs/x86_64/paging.c b/src/kernel/archs/x86_64/paging.c index 8d244f8..0615f9c 100644 --- a/src/kernel/archs/x86_64/paging.c +++ b/src/kernel/archs/x86_64/paging.c @@ -10,7 +10,8 @@ #include "asm.h" #include "cpuid.h" #include "dbg/log.h" -#include "loader.h" +#include "handover.h" +#include "handover/utils.h" #include "paging.h" static size_t page_size = mib$(2); @@ -188,18 +189,17 @@ Res paging_init(void) try$(kmmap_page(pml4, hal_mmap_l2h(i), i, flags)); } - Mmap mmaps = loader_get_mmap(); + HandoverPayload *hand = handover(); + HandoverRecord rec; - for (size_t i = 0; i < mmaps.len; i++) + handover_foreach_record(hand, rec) { - MmapEntry entry = mmaps.entries[i]; - - if (mmaps.entries[i].type != LOADER_FB) + if (rec.tag != HANDOVER_FB) { try$(hal_space_map((HalPage *)pml4, - hal_mmap_l2h(entry.base), - entry.base, - entry.len, + align_down$(hal_mmap_l2h(rec.start), PMM_PAGE_SIZE), + align_down$(rec.start, PMM_PAGE_SIZE), + align_up$(rec.size, PMM_PAGE_SIZE), HAL_MEM_READ | HAL_MEM_WRITE | HAL_MEM_HUGE)); } } diff --git a/src/kernel/core/pmm.c b/src/kernel/core/pmm.c index f7019da..214672b 100644 --- a/src/kernel/core/pmm.c +++ b/src/kernel/core/pmm.c @@ -1,9 +1,11 @@ #include #include -#include +#include #include #include +#include "handover/handover.h" +#include "handover/utils.h" #include "pmm.h" static PmmBitmap bitmap = {0}; @@ -44,21 +46,22 @@ static void pmm_mark_used(uintptr_t base, size_t len) Res pmm_init(void) { - Mmap mmaps = loader_get_mmap(); - MmapEntry last_entry = mmaps.entries[mmaps.len - 1]; + HandoverPayload *hand = handover(); + HandoverRecord last_entry = hand->records[hand->count - 1]; + HandoverRecord record; - bitmap.len = align_up$((last_entry.base + last_entry.len) / (PMM_PAGE_SIZE * 8), PMM_PAGE_SIZE); + bitmap.len = align_up$((last_entry.start + last_entry.size) / (PMM_PAGE_SIZE * 8), PMM_PAGE_SIZE); bitmap.last_high = bitmap.len - 1; log$("Bitmap size: %d bytes", bitmap.len); - for (size_t i = 0; i < mmaps.len; i++) + handover_foreach_record(hand, record) { - if (mmaps.entries[i].type == LOADER_FREE && mmaps.entries[i].len >= bitmap.len) + if (record.tag == HANDOVER_FREE && record.size >= bitmap.len) { - log$("Bitmap base: %p", mmaps.entries[i].base); - bitmap.bitmap = (uint8_t *)hal_mmap_l2h(mmaps.entries[i].base); - mmaps.entries[i].base += bitmap.len; - mmaps.entries[i].len -= bitmap.len; + log$("Bitmap base: %p", record.start); + bitmap.bitmap = (uint8_t *)hal_mmap_l2h(record.start); + record.start += bitmap.len; + record.size -= bitmap.len; break; } } @@ -70,11 +73,11 @@ Res pmm_init(void) memset(bitmap.bitmap, 0xFF, bitmap.len); - for (size_t i = 0; i < mmaps.len; i++) + handover_foreach_record(hand, record) { - if (mmaps.entries[i].type == LOADER_FREE) + if (record.tag == HANDOVER_FREE) { - pmm_mark_free(mmaps.entries[i].base, mmaps.entries[i].len); + pmm_mark_free(record.start, record.size); } } diff --git a/src/kernel/core/pre-sched.c b/src/kernel/core/pre-sched.c index 63abef0..7616b39 100644 --- a/src/kernel/core/pre-sched.c +++ b/src/kernel/core/pre-sched.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -25,15 +25,15 @@ static bool need_switch = false; Res load_scheduler(void) { - Module sched = loader_get_module("/bin/procman"); - if (sched.len == 0) + HandoverRecord sched = handover_file_find(handover(), "/bin/procman"); + if (sched.size == 0) { return err$(RES_NOENT); } try$(hal_space_create(&sched_vspace)); - Elf_Ehdr *hdr = (Elf_Ehdr *)sched.base; + Elf_Ehdr *hdr = (Elf_Ehdr *)sched.start; if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0) { return err$(RES_INVAL); @@ -46,7 +46,7 @@ Res load_scheduler(void) for (size_t i = 0; i < hdr->e_phnum; i++) { - Elf_Phdr *phdr = (Elf_Phdr *)(sched.base + hdr->e_phoff + i * hdr->e_phentsize); + Elf_Phdr *phdr = (Elf_Phdr *)(sched.start + hdr->e_phoff + i * hdr->e_phentsize); if (phdr->p_type == PT_LOAD) { @@ -62,7 +62,7 @@ Res load_scheduler(void) log$("Scheduler segment mapped to 0x%x", paddr.base); try$(hal_space_map(sched_vspace, phdr->p_vaddr, paddr.base, align_up$(phdr->p_memsz, PMM_PAGE_SIZE), HAL_MEM_READ | HAL_MEM_WRITE | HAL_MEM_USER | HAL_MEM_EXEC)); - memcpy((void *)hal_mmap_l2h(paddr.base), (void *)sched.base + phdr->p_offset, phdr->p_filesz); + memcpy((void *)hal_mmap_l2h(paddr.base), (void *)sched.start + phdr->p_offset, phdr->p_filesz); memset((void *)hal_mmap_l2h(paddr.base + phdr->p_filesz), 0, phdr->p_memsz - phdr->p_filesz); } } @@ -77,6 +77,7 @@ Res load_scheduler(void) } hal_space_map(sched_vspace, USER_STACK_BASE, sched_stack_obj.base, STACK_SIZE, HAL_MEM_READ | HAL_MEM_WRITE | HAL_MEM_USER); + hal_context_start(sched_ctx, hdr->e_entry, USER_STACK_BASE, (SysArgs){0, 0, 0, 0, 0, 0}); need_switch = true; diff --git a/src/kernel/klibs/handover.h b/src/kernel/klibs/handover.h new file mode 100644 index 0000000..2a6c6a4 --- /dev/null +++ b/src/kernel/klibs/handover.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include + +/* --- Handover ------------------------------------------------------------ */ + +HandoverPayload *handover(void); + +void handover_parse_module(HandoverBuilder *self); + +void handover_parse_mmap(HandoverBuilder *self); + +/* --- Misc ---------------------------------------------------------------- */ + +typedef struct +{ + size_t phys; + size_t virt; +} KernelMmap; + +KernelMmap loader_get_kernel_mmap(void); \ No newline at end of file diff --git a/src/kernel/klibs/limine/loader.c b/src/kernel/klibs/limine/handover.c similarity index 58% rename from src/kernel/klibs/limine/loader.c rename to src/kernel/klibs/limine/handover.c index 1dea573..0c8d09f 100644 --- a/src/kernel/klibs/limine/loader.c +++ b/src/kernel/klibs/limine/handover.c @@ -1,14 +1,20 @@ #include #include -#include +#include #include #include +#include "handover/builder.h" +#include "handover/handover.h" #include "limine.h" -static Mmap mmap = {0}; +/* --- Handover ------------------------------------------------------------- */ -/* --- Limine requests ----------------------------------------------------- */ +static uint8_t handover_buffer[kib$(16)] = {0}; +static HandoverBuilder builder; +static bool is_handover_init = false; + +/* --- Limine requests ------------------------------------------------------ */ static volatile struct limine_memmap_request memmap_req = { .id = LIMINE_MEMMAP_REQUEST, @@ -42,37 +48,37 @@ volatile struct limine_module_request module_request = { /* --- Loader functions ---------------------------------------------------- */ -Mmap loader_get_mmap(void) +void handover_parse_mmap(HandoverBuilder *self) { - if (mmap.len > 0) - { - return mmap; - } - if (memmap_req.response == NULL) { error$("Couldn't retrieve memory map from Limine"); hal_panic(); } + + if (kernel_addr_req.response == NULL) + { + error$("Couldn't retrieve kernel address from Limine"); + hal_panic(); + } log$("Retrieved memory map from Limine"); - log$("====================================================="); - log$(" TYPE | BASE | LIMIT "); - log$("====================================================="); + log$("======================================================"); + log$(" TYPE | BASE | LIMIT "); + log$("======================================================"); - size_t i; - for (i = 0; i < memmap_req.response->entry_count; i++) + for (size_t i = 0; i < memmap_req.response->entry_count; i++) { struct limine_memmap_entry *entry = memmap_req.response->entries[i]; - MmapEntry *mmap_entry = &mmap.entries[i]; + HandoverRecord record = {0}; switch (entry->type) { case LIMINE_MEMMAP_USABLE: { - log$("FREE | %p | %p", entry->base, entry->base + entry->length); - mmap_entry->type = LOADER_FREE; + log$("FREE | %p | %p", entry->base, entry->base + entry->length); + record.tag = HANDOVER_FREE; break; } @@ -80,30 +86,30 @@ Mmap loader_get_mmap(void) case LIMINE_MEMMAP_RESERVED: case LIMINE_MEMMAP_BAD_MEMORY: { - log$("RESERVED | %p | %p", entry->base, entry->base + entry->length); - mmap_entry->type = LOADER_RESERVED; + log$("RESERVED | %p | %p", entry->base, entry->base + entry->length); + record.tag = HANDOVER_RESERVED; break; } case LIMINE_MEMMAP_ACPI_RECLAIMABLE: case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE: { - log$("RECLAIMABLE | %p | %p", entry->base, entry->base + entry->length); - mmap_entry->type = LOADER_RECLAIMABLE; + log$("RECLAIMABLE | %p | %p", entry->base, entry->base + entry->length); + record.tag = HANDOVER_LOADER; break; } case LIMINE_MEMMAP_KERNEL_AND_MODULES: { log$("MODULE | %p | %p", entry->base, entry->base + entry->length); - mmap_entry->type = LOADER_KERNEL; + record.tag = HANDOVER_KERNEL; break; } case LIMINE_MEMMAP_FRAMEBUFFER: { - log$("FRAMEBUFFER| %p | %p", entry->base, entry->base + entry->length); - mmap_entry->type = LOADER_FB; + log$("FRAMEBUFFER | %p | %p", entry->base, entry->base + entry->length); + record.tag = HANDOVER_FB; break; } @@ -114,14 +120,13 @@ Mmap loader_get_mmap(void) } } - mmap_entry->base = entry->base; - mmap_entry->len = entry->length; + record.start = entry->base; + record.size = entry->length; + + handover_builder_append(self, record); } log$("====================================================="); - - mmap.len = i; - return mmap; } uintptr_t hal_mmap_l2h(uintptr_t addr) @@ -173,27 +178,45 @@ Rsdp *hal_acpi_rsdp(void) return (Rsdp *)rsdp_req.response->address; } -Module loader_get_module(char const *path) +void handover_parse_module(HandoverBuilder *self) { if (module_request.response == NULL) { - return (Module){0}; + error$("Couldn't retrieve list of modules from Limine"); + hal_panic(); } + HandoverRecord rec = {0}; + for (size_t i = 0; i < module_request.response->module_count; i++) { - if (memcmp(path, module_request.response->modules[i]->path, strlen(path)) == 0) - { - Module mod = { - .base = (uintptr_t)module_request.response->modules[i]->address, - .len = module_request.response->modules[i]->size, - }; + size_t str_offset = handover_builder_append_str(self, module_request.response->modules[i]->path); + rec = (HandoverRecord){ + .tag = HANDOVER_FILE, + .flags = 0, + .start = (uintptr_t)module_request.response->modules[i]->address, + .size = module_request.response->modules[i]->size, + .file = { + .name = str_offset, + .meta = 0, + }, + }; - memcpy(mod.name, module_request.response->modules[i]->path, strlen(path)); + handover_builder_append(self, rec); + } +} + +HandoverPayload *handover(void) +{ + if (!is_handover_init) + { + handover_builder_init(&builder, handover_buffer, kib$(16)); + handover_parse_module(&builder); + handover_parse_mmap(&builder); + + is_handover_init = true; - return mod; - } } - return (Module){0}; + return builder.payload; } \ No newline at end of file diff --git a/src/kernel/klibs/loader.h b/src/kernel/klibs/loader.h deleted file mode 100644 index 9102b99..0000000 --- a/src/kernel/klibs/loader.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include -#include -#include - -/* --- MEMMAPS ------------------------------------------------------------- */ - -#define LOADER_MAX (128) - -enum memmap_type -{ - LOADER_FREE, - LOADER_RESERVED, - LOADER_RECLAIMABLE, - LOADER_KERNEL, - LOADER_FB, -}; - -typedef struct -{ - size_t base; - size_t len; - enum memmap_type type; -} MmapEntry; - -typedef struct -{ - size_t len; - MmapEntry entries[LOADER_MAX]; -} Mmap; - -typedef struct -{ - size_t phys; - size_t virt; -} KernelMmap; - -Mmap loader_get_mmap(void); - -/* --- Modules -------------------------------------------------------------- */ - -typedef struct -{ - uintptr_t base; - size_t len; - char name[64]; -} Module; - -Module loader_get_module(char const *path); - -/* --- Misc ---------------------------------------------------------------- */ - -KernelMmap loader_get_kernel_mmap(void); \ No newline at end of file