port: handover
This commit is contained in:
parent
9c367ca8f1
commit
e45cc2aff3
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
23
src/kernel/klibs/handover.h
Normal file
23
src/kernel/klibs/handover.h
Normal 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);
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,30 +86,30 @@ Mmap loader_get_mmap(void)
|
||||||
case LIMINE_MEMMAP_RESERVED:
|
case LIMINE_MEMMAP_RESERVED:
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
case LIMINE_MEMMAP_ACPI_RECLAIMABLE:
|
case LIMINE_MEMMAP_ACPI_RECLAIMABLE:
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
|
@ -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);
|
|
Loading…
Reference in a new issue