feat/kernel: Started on valloc implementation for amd64
This commit is contained in:
parent
91fc826022
commit
3aa5a1bb86
6 changed files with 132 additions and 6 deletions
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
|
@ -6,6 +6,9 @@
|
||||||
"limine.h": "c",
|
"limine.h": "c",
|
||||||
"stddef.h": "c",
|
"stddef.h": "c",
|
||||||
"stdint.h": "c",
|
"stdint.h": "c",
|
||||||
"typeinfo": "c"
|
"typeinfo": "c",
|
||||||
|
"log.h": "c",
|
||||||
|
"pmm.h": "c",
|
||||||
|
"paging.h": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
MAKEFLAGS += -rR
|
MAKEFLAGS += -rR
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
|
|
||||||
QEMUFLAGS := -m 2G -serial stdio -display none
|
QEMUFLAGS := -m 2G -serial stdio # -display none
|
||||||
IMAGE_NAME := release/emk
|
IMAGE_NAME := release/emk
|
||||||
|
|
||||||
HOST_CC := cc
|
HOST_CC := cc
|
||||||
|
|
|
@ -253,5 +253,10 @@ void paging_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (uint64_t gb4 = 0; gb4 < 0x100000000; gb4 += PAGE_SIZE)
|
||||||
|
{
|
||||||
|
vmap(kernel_pagemap, (uint64_t)HIGHER_HALF(gb4), gb4, VMM_PRESENT | VMM_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
pmset(kernel_pagemap);
|
pmset(kernel_pagemap);
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
#include <sys/kpanic.h>
|
#include <sys/kpanic.h>
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <arch/paging.h>
|
#include <arch/paging.h>
|
||||||
|
#include <mm/vmm.h>
|
||||||
|
|
||||||
__attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3);
|
__attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3);
|
||||||
__attribute__((used, section(".limine_requests"))) static volatile struct limine_memmap_request memmap_request = {
|
__attribute__((used, section(".limine_requests"))) static volatile struct limine_memmap_request memmap_request = {
|
||||||
|
@ -67,7 +68,7 @@ void emk_entry(void)
|
||||||
hhdm_offset = hhdm_request.response->offset;
|
hhdm_offset = hhdm_request.response->offset;
|
||||||
log_early("HHDM Offset: %llx", hhdm_offset);
|
log_early("HHDM Offset: %llx", hhdm_offset);
|
||||||
pmm_init();
|
pmm_init();
|
||||||
log_early("Initialized PMM");
|
log_early("Initialized physical page manager");
|
||||||
|
|
||||||
/* Test allocate a single physical page */
|
/* Test allocate a single physical page */
|
||||||
char *a = palloc(1, true);
|
char *a = palloc(1, true);
|
||||||
|
@ -89,5 +90,22 @@ void emk_entry(void)
|
||||||
paging_init();
|
paging_init();
|
||||||
log_early("Initialized paging");
|
log_early("Initialized paging");
|
||||||
|
|
||||||
|
/* Kernel Virtual Memory Context, not to be confused with KVM */
|
||||||
|
vpm_ctx_t *kvm_ctx = vmm_init(kernel_pagemap);
|
||||||
|
if (!kvm_ctx)
|
||||||
|
{
|
||||||
|
kpanic(NULL, "Failed to create kernel VMM context");
|
||||||
|
}
|
||||||
|
log_early("Initialized virtual page manager");
|
||||||
|
|
||||||
|
char *b = valloc(kvm_ctx, 1, VMM_PRESENT | VMM_WRITE);
|
||||||
|
if (!b)
|
||||||
|
{
|
||||||
|
kpanic(NULL, "Failed to allocate single virtual page");
|
||||||
|
}
|
||||||
|
|
||||||
|
*b = 32;
|
||||||
|
log_early("Allocated 1 virtual page: %llx", (uint64_t)b);
|
||||||
|
|
||||||
hlt();
|
hlt();
|
||||||
}
|
}
|
94
kernel/src/mm/vmm.c
Normal file
94
kernel/src/mm/vmm.c
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/* EMK 1.0 Copyright (c) 2025 Piraterna */
|
||||||
|
#include <mm/vmm.h>
|
||||||
|
#include <mm/pmm.h>
|
||||||
|
#include <util/log.h>
|
||||||
|
#include <util/align.h>
|
||||||
|
#include <boot/emk.h>
|
||||||
|
#include <arch/paging.h>
|
||||||
|
|
||||||
|
vpm_ctx_t *vmm_init(uint64_t *pm)
|
||||||
|
{
|
||||||
|
if (!pm || !IS_PAGE_ALIGNED(PHYSICAL(pm)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
vpm_ctx_t *ctx = (vpm_ctx_t *)palloc(1, true);
|
||||||
|
if (!ctx)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ctx->pagemap = pm;
|
||||||
|
ctx->root = NULL; /* valloc creates the root if not present */
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *valloc(vpm_ctx_t *ctx, size_t pages, uint64_t flags)
|
||||||
|
{
|
||||||
|
if (!ctx || !pages)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Allocate physical pages */
|
||||||
|
void *phys = palloc(pages, true);
|
||||||
|
if (!phys)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
uint64_t virt = VPM_MIN_ADDR;
|
||||||
|
vm_region_t *prev = NULL;
|
||||||
|
vm_region_t *curr = ctx->root;
|
||||||
|
|
||||||
|
while (curr)
|
||||||
|
{
|
||||||
|
uint64_t curr_end = curr->start + (curr->pages * PAGE_SIZE);
|
||||||
|
if (virt + (pages * PAGE_SIZE) <= curr->start)
|
||||||
|
{
|
||||||
|
/* Found a gap */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
virt = curr_end;
|
||||||
|
prev = curr;
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map the virtual to physical pages */
|
||||||
|
for (size_t i = 0; i < pages; i++)
|
||||||
|
{
|
||||||
|
uint64_t vaddr = virt + (i * PAGE_SIZE);
|
||||||
|
uint64_t paddr = (uint64_t)phys + (i * PAGE_SIZE);
|
||||||
|
if (vmap(ctx->pagemap, vaddr, paddr, flags) != 0)
|
||||||
|
{
|
||||||
|
/* Mapping failed, unmap any mapped pages and free physical memory */
|
||||||
|
for (size_t j = 0; j < i; j++)
|
||||||
|
{
|
||||||
|
vunmap(ctx->pagemap, virt + (j * PAGE_SIZE));
|
||||||
|
}
|
||||||
|
pfree(phys, pages);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create new region */
|
||||||
|
vm_region_t *region = (vm_region_t *)palloc(1, true);
|
||||||
|
if (!region)
|
||||||
|
{
|
||||||
|
/* Region allocation failed, clean up */
|
||||||
|
for (size_t i = 0; i < pages; i++)
|
||||||
|
{
|
||||||
|
vunmap(ctx->pagemap, virt + (i * PAGE_SIZE));
|
||||||
|
}
|
||||||
|
pfree(phys, pages);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
region->start = virt;
|
||||||
|
region->pages = pages;
|
||||||
|
region->next = curr;
|
||||||
|
|
||||||
|
if (prev)
|
||||||
|
{
|
||||||
|
prev->next = region;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ctx->root = region;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (void *)virt;
|
||||||
|
}
|
|
@ -3,6 +3,11 @@
|
||||||
#define VMM_H
|
#define VMM_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifndef VPM_MIN_ADDR
|
||||||
|
#define VPM_MIN_ADDR 0x1000
|
||||||
|
#endif // VPM_MIN_ADDR
|
||||||
|
|
||||||
typedef struct vm_region
|
typedef struct vm_region
|
||||||
{
|
{
|
||||||
|
@ -12,12 +17,13 @@ typedef struct vm_region
|
||||||
/* TOOD: Maybe store flags */
|
/* TOOD: Maybe store flags */
|
||||||
} vm_region_t;
|
} vm_region_t;
|
||||||
|
|
||||||
typedef struct vma_ctx
|
typedef struct vpm_ctx
|
||||||
{
|
{
|
||||||
vm_region_t *root;
|
vm_region_t *root;
|
||||||
uint64_t *pagemap;
|
uint64_t *pagemap;
|
||||||
} vma_ctx_t;
|
} vpm_ctx_t;
|
||||||
|
|
||||||
void vmm_init();
|
vpm_ctx_t *vmm_init(uint64_t *pm);
|
||||||
|
void *valloc(vpm_ctx_t *ctx, size_t pages, uint64_t flags);
|
||||||
|
|
||||||
#endif // VMM_H
|
#endif // VMM_H
|
Loading…
Add table
Add a link
Reference in a new issue