port: handover

This commit is contained in:
Jordan ⌨️ 2023-12-21 08:22:51 +01:00 committed by Keyboard Slayer
parent 9c367ca8f1
commit e45cc2aff3
7 changed files with 123 additions and 123 deletions

View file

@ -6,6 +6,10 @@
"cute-engineering/libheap": { "cute-engineering/libheap": {
"git": "https://github.com/cute-engineering/libheap.git", "git": "https://github.com/cute-engineering/libheap.git",
"tag": "v1.1.0" "tag": "v1.1.0"
},
"cute-engineering/handover": {
"git": "https://github.com/cute-engineering/handover.git",
"tag": "v1.4.0"
} }
} }
} }

View file

@ -10,7 +10,8 @@
#include "asm.h" #include "asm.h"
#include "cpuid.h" #include "cpuid.h"
#include "dbg/log.h" #include "dbg/log.h"
#include "loader.h" #include "handover.h"
#include "handover/utils.h"
#include "paging.h" #include "paging.h"
static size_t page_size = mib$(2); 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)); 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 (rec.tag != HANDOVER_FB)
if (mmaps.entries[i].type != LOADER_FB)
{ {
try$(hal_space_map((HalPage *)pml4, try$(hal_space_map((HalPage *)pml4,
hal_mmap_l2h(entry.base), align_down$(hal_mmap_l2h(rec.start), PMM_PAGE_SIZE),
entry.base, align_down$(rec.start, PMM_PAGE_SIZE),
entry.len, align_up$(rec.size, PMM_PAGE_SIZE),
HAL_MEM_READ | HAL_MEM_WRITE | HAL_MEM_HUGE)); HAL_MEM_READ | HAL_MEM_WRITE | HAL_MEM_HUGE));
} }
} }

View file

@ -1,9 +1,11 @@
#include <dbg/log.h> #include <dbg/log.h>
#include <hal.h> #include <hal.h>
#include <loader.h> #include <handover.h>
#include <string.h> #include <string.h>
#include <sync/spinlock.h> #include <sync/spinlock.h>
#include "handover/handover.h"
#include "handover/utils.h"
#include "pmm.h" #include "pmm.h"
static PmmBitmap bitmap = {0}; static PmmBitmap bitmap = {0};
@ -44,21 +46,22 @@ static void pmm_mark_used(uintptr_t base, size_t len)
Res pmm_init(void) Res pmm_init(void)
{ {
Mmap mmaps = loader_get_mmap(); HandoverPayload *hand = handover();
MmapEntry last_entry = mmaps.entries[mmaps.len - 1]; 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; bitmap.last_high = bitmap.len - 1;
log$("Bitmap size: %d bytes", bitmap.len); 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); log$("Bitmap base: %p", record.start);
bitmap.bitmap = (uint8_t *)hal_mmap_l2h(mmaps.entries[i].base); bitmap.bitmap = (uint8_t *)hal_mmap_l2h(record.start);
mmaps.entries[i].base += bitmap.len; record.start += bitmap.len;
mmaps.entries[i].len -= bitmap.len; record.size -= bitmap.len;
break; break;
} }
} }
@ -70,11 +73,11 @@ Res pmm_init(void)
memset(bitmap.bitmap, 0xFF, bitmap.len); 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);
} }
} }

View file

@ -1,5 +1,5 @@
#include <dbg/log.h> #include <dbg/log.h>
#include <loader.h> #include <handover.h>
#include <specs/elf.h> #include <specs/elf.h>
#include <string.h> #include <string.h>
@ -25,15 +25,15 @@ static bool need_switch = false;
Res load_scheduler(void) Res load_scheduler(void)
{ {
Module sched = loader_get_module("/bin/procman"); HandoverRecord sched = handover_file_find(handover(), "/bin/procman");
if (sched.len == 0) if (sched.size == 0)
{ {
return err$(RES_NOENT); return err$(RES_NOENT);
} }
try$(hal_space_create(&sched_vspace)); 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) if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0)
{ {
return err$(RES_INVAL); return err$(RES_INVAL);
@ -46,7 +46,7 @@ Res load_scheduler(void)
for (size_t i = 0; i < hdr->e_phnum; i++) 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) if (phdr->p_type == PT_LOAD)
{ {
@ -62,7 +62,7 @@ Res load_scheduler(void)
log$("Scheduler segment mapped to 0x%x", paddr.base); 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)); 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); 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_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}); hal_context_start(sched_ctx, hdr->e_entry, USER_STACK_BASE, (SysArgs){0, 0, 0, 0, 0, 0});
need_switch = true; need_switch = true;

View file

@ -0,0 +1,23 @@
#pragma once
#include <handover/handover.h>
#include <handover/builder.h>
#include <handover/utils.h>
/* --- 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);

View file

@ -1,14 +1,20 @@
#include <dbg/log.h> #include <dbg/log.h>
#include <hal.h> #include <hal.h>
#include <loader.h> #include <handover.h>
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include "handover/builder.h"
#include "handover/handover.h"
#include "limine.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 = { static volatile struct limine_memmap_request memmap_req = {
.id = LIMINE_MEMMAP_REQUEST, .id = LIMINE_MEMMAP_REQUEST,
@ -42,37 +48,37 @@ volatile struct limine_module_request module_request = {
/* --- Loader functions ---------------------------------------------------- */ /* --- Loader functions ---------------------------------------------------- */
Mmap loader_get_mmap(void) void handover_parse_mmap(HandoverBuilder *self)
{ {
if (mmap.len > 0)
{
return mmap;
}
if (memmap_req.response == NULL) if (memmap_req.response == NULL)
{ {
error$("Couldn't retrieve memory map from Limine"); error$("Couldn't retrieve memory map from Limine");
hal_panic(); 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$("Retrieved memory map from Limine");
log$("====================================================="); log$("======================================================");
log$(" TYPE | BASE | LIMIT "); log$(" TYPE | BASE | LIMIT ");
log$("====================================================="); log$("======================================================");
size_t i; for (size_t i = 0; i < memmap_req.response->entry_count; i++)
for (i = 0; i < memmap_req.response->entry_count; i++)
{ {
struct limine_memmap_entry *entry = memmap_req.response->entries[i]; struct limine_memmap_entry *entry = memmap_req.response->entries[i];
MmapEntry *mmap_entry = &mmap.entries[i]; HandoverRecord record = {0};
switch (entry->type) switch (entry->type)
{ {
case LIMINE_MEMMAP_USABLE: case LIMINE_MEMMAP_USABLE:
{ {
log$("FREE | %p | %p", entry->base, entry->base + entry->length); log$("FREE | %p | %p", entry->base, entry->base + entry->length);
mmap_entry->type = LOADER_FREE; record.tag = HANDOVER_FREE;
break; break;
} }
@ -81,7 +87,7 @@ Mmap loader_get_mmap(void)
case LIMINE_MEMMAP_BAD_MEMORY: case LIMINE_MEMMAP_BAD_MEMORY:
{ {
log$("RESERVED | %p | %p", entry->base, entry->base + entry->length); log$("RESERVED | %p | %p", entry->base, entry->base + entry->length);
mmap_entry->type = LOADER_RESERVED; record.tag = HANDOVER_RESERVED;
break; break;
} }
@ -89,21 +95,21 @@ Mmap loader_get_mmap(void)
case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE: case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE:
{ {
log$("RECLAIMABLE | %p | %p", entry->base, entry->base + entry->length); log$("RECLAIMABLE | %p | %p", entry->base, entry->base + entry->length);
mmap_entry->type = LOADER_RECLAIMABLE; record.tag = HANDOVER_LOADER;
break; break;
} }
case LIMINE_MEMMAP_KERNEL_AND_MODULES: case LIMINE_MEMMAP_KERNEL_AND_MODULES:
{ {
log$("MODULE | %p | %p", entry->base, entry->base + entry->length); log$("MODULE | %p | %p", entry->base, entry->base + entry->length);
mmap_entry->type = LOADER_KERNEL; record.tag = HANDOVER_KERNEL;
break; break;
} }
case LIMINE_MEMMAP_FRAMEBUFFER: case LIMINE_MEMMAP_FRAMEBUFFER:
{ {
log$("FRAMEBUFFER| %p | %p", entry->base, entry->base + entry->length); log$("FRAMEBUFFER | %p | %p", entry->base, entry->base + entry->length);
mmap_entry->type = LOADER_FB; record.tag = HANDOVER_FB;
break; break;
} }
@ -114,14 +120,13 @@ Mmap loader_get_mmap(void)
} }
} }
mmap_entry->base = entry->base; record.start = entry->base;
mmap_entry->len = entry->length; record.size = entry->length;
handover_builder_append(self, record);
} }
log$("====================================================="); log$("=====================================================");
mmap.len = i;
return mmap;
} }
uintptr_t hal_mmap_l2h(uintptr_t addr) uintptr_t hal_mmap_l2h(uintptr_t addr)
@ -173,27 +178,45 @@ Rsdp *hal_acpi_rsdp(void)
return (Rsdp *)rsdp_req.response->address; return (Rsdp *)rsdp_req.response->address;
} }
Module loader_get_module(char const *path) void handover_parse_module(HandoverBuilder *self)
{ {
if (module_request.response == NULL) 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++) for (size_t i = 0; i < module_request.response->module_count; i++)
{ {
if (memcmp(path, module_request.response->modules[i]->path, strlen(path)) == 0) size_t str_offset = handover_builder_append_str(self, module_request.response->modules[i]->path);
{ rec = (HandoverRecord){
Module mod = { .tag = HANDOVER_FILE,
.base = (uintptr_t)module_request.response->modules[i]->address, .flags = 0,
.len = module_request.response->modules[i]->size, .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);
return mod;
} }
} }
return (Module){0}; 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 builder.payload;
} }

View file

@ -1,54 +0,0 @@
#pragma once
#include <res.h>
#include <stddef.h>
#include <stdint.h>
/* --- 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);