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": {
"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"
}
}
}

View file

@ -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));
}
}

View file

@ -1,9 +1,11 @@
#include <dbg/log.h>
#include <hal.h>
#include <loader.h>
#include <handover.h>
#include <string.h>
#include <sync/spinlock.h>
#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);
}
}

View file

@ -1,5 +1,5 @@
#include <dbg/log.h>
#include <loader.h>
#include <handover.h>
#include <specs/elf.h>
#include <string.h>
@ -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;

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 <hal.h>
#include <loader.h>
#include <handover.h>
#include <stddef.h>
#include <string.h>
#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$("======================================================");
log$(" TYPE | BASE | LIMIT ");
log$("=====================================================");
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;
record.tag = HANDOVER_FREE;
break;
}
@ -81,7 +87,7 @@ Mmap loader_get_mmap(void)
case LIMINE_MEMMAP_BAD_MEMORY:
{
log$("RESERVED | %p | %p", entry->base, entry->base + entry->length);
mmap_entry->type = LOADER_RESERVED;
record.tag = HANDOVER_RESERVED;
break;
}
@ -89,21 +95,21 @@ Mmap loader_get_mmap(void)
case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE:
{
log$("RECLAIMABLE | %p | %p", entry->base, entry->base + entry->length);
mmap_entry->type = LOADER_RECLAIMABLE;
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));
return mod;
handover_builder_append(self, rec);
}
}
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);