From 6c609e98406f2747bd869f92a39cc8d8b0bcdd47 Mon Sep 17 00:00:00 2001 From: PoliEcho Date: Sun, 27 Sep 2026 15:10:18 +0200 Subject: [PATCH] vmm bullshit --- kernel/include/vmm.h | 9 +++++++ kernel/src/kmain.c | 64 ++++++++++++++++++++++++++++++++------------ kernel/src/vmm.c | 46 ++++++++++++++++++++++++------- 3 files changed, 93 insertions(+), 26 deletions(-) create mode 100644 kernel/include/vmm.h diff --git a/kernel/include/vmm.h b/kernel/include/vmm.h new file mode 100644 index 0000000..7b9ffdf --- /dev/null +++ b/kernel/include/vmm.h @@ -0,0 +1,9 @@ +#ifndef _VMM_H +#define _VMM_H +#include "types.h" + +#define CANONICAL_MASK_KERNEL 0xFFFF800000000000 +#define CANONICAL_MASK_USER 0x00007FFFFFFFFFF000 + +int vmm_alloc(void** vaddr, uint64_t count, uint64_t flags); +#endif \ No newline at end of file diff --git a/kernel/src/kmain.c b/kernel/src/kmain.c index 4a83d87..05120de 100644 --- a/kernel/src/kmain.c +++ b/kernel/src/kmain.c @@ -1,23 +1,28 @@ +#include "errno.h" +#include "types.h" #include -#include -#include -#include -#include -#include -#include #include #include +#include +#include #include +#include +#include +#include +#include +#include +#include -__noreturn -void _start(void) { +__noreturn void _start(void) { int err = 0; // Serial console for debugging - if ((err = serial_init(COM1)) < 0) panic(NULL, "Failed to initialize Serial driver. (%d)", err); + if ((err = serial_init(COM1)) < 0) + panic(NULL, "Failed to initialize Serial driver. (%d)", err); // Load structures from bootloader - if ((err = boot_init()) < 0) panic(NULL, "Failed to parse bootloader structures. (%d)", err); + if ((err = boot_init()) < 0) + panic(NULL, "Failed to parse bootloader structures. (%d)", err); // CPUID thingy :p uint32_t eax = 0; @@ -26,26 +31,51 @@ void _start(void) { pr_info("[kernel] CPUID_GETVENDORID: %s\n", s); // System init - if ((err = gdt_init()) < 0) panic(NULL, "Failed to initalize GDT. (%d)", err); - if ((err = isr_init()) < 0) panic(NULL, "Failed to initalize ISRs. (%d)", err); + if ((err = gdt_init()) < 0) + panic(NULL, "Failed to initalize GDT. (%d)", err); + if ((err = isr_init()) < 0) + panic(NULL, "Failed to initalize ISRs. (%d)", err); // Memory management - if ((err = pmm_init()) < 0) panic(NULL, "Failed to initalize Physical Memory Manager. (%d)", err); - if ((err = pag_init()) < 0) panic(NULL, "Failed to initalize Paging. (%d)", err); + if ((err = pmm_init()) < 0) + panic(NULL, "Failed to initalize Physical Memory Manager. (%d)", + err); + if ((err = pag_init()) < 0) + panic(NULL, "Failed to initalize Paging. (%d)", err); // random number generation rand_init(); // test random number generation printk("Random number generation test:\n"); for (uint8_t i = 0; i <= 16; i++) { - printk("%d: %lu\n",i,get_random_number()); + printk("%d: %lu\n", i, get_random_number()); } + // test VMM + { + void* vaddr; + int ret = vmm_alloc(&vaddr, 2, 0); + if (ret != SUCCESS) { + panic(NULL, "vmm_alloc returned %d", ret); + } + { + uint64_t* pml4 = pag_get_pml4(); + uint64_t* pte = pag_get_pte(pml4, vaddr); + if (!IS_ERR(pte) && (*pte & PTE_FLAG_PRESENT)) { + printk("page allocated\n"); + } else { + printk("page not allocated\n"); + } + } + memset(vaddr, 69, 2 * PAGE_SIZE); + *(char*)((vaddr + (2 * PAGE_SIZE)) - 1) = 0; + printk("read back:\n%s\n", (char*)vaddr); + } // The most important function in the world. splash(); // Patiently wait for things to do :) - while (1); + while (1) + ; }; - diff --git a/kernel/src/vmm.c b/kernel/src/vmm.c index 3c8ec6f..1af7637 100644 --- a/kernel/src/vmm.c +++ b/kernel/src/vmm.c @@ -1,9 +1,11 @@ +#include "vmm.h" #include "kernel.h" #include #include #include #include #include +#include #include // allocates set number of pages at address provided @@ -12,27 +14,53 @@ int vmm_alloc(void** vaddr, uint64_t count, uint64_t flags) { if (flags == 0) { flags = PTE_FLAG_PRESENT | PTE_FLAG_WRITE | PTE_FLAG_NOEXEC; } + bool random_vaddr = *vaddr ? false : true; uint64_t* pml4 = pag_get_pml4(); - for (uint64_t i = 0; i < count; i++) { - uint64_t* pte = pag_get_pte(pml4, vaddr); - if (!IS_ERR(pte) && (*pte & PTE_FLAG_PRESENT)) { - // TODO actualy handle conflict - return EEXIST; + { + uint8_t limit_counter = 0; + while (true) { + if (random_vaddr) { + retry_selection: + *vaddr = (void*)ALIGN_DOWN(get_random_number(), + PAGE_SIZE); + + *vaddr = (void*)((uint64_t)(*vaddr) & + CANONICAL_MASK_USER); + if (!(flags & PTE_FLAG_USER)) { + *vaddr = (void*)((uint64_t)(*vaddr) | + CANONICAL_MASK_KERNEL); + } + } + for (uint64_t i = 0; i < count; i++) { + uint64_t* pte = + pag_get_pte(pml4, *vaddr + (i * PAGE_SIZE)); + if (!IS_ERR(pte) && (*pte & PTE_FLAG_PRESENT)) { + if (!random_vaddr) { + return -EEXIST; + } else { + if (limit_counter < UINT8_MAX) { + goto retry_selection; + } else { + return -EAGAIN; + } + } + } + } + break; } } for (uint64_t i = 0; i < count; i++) { void* paddr = pmm_alloc(); int pag_map_ret = - pag_map(pml4, (void*)(((size_t)vaddr) * i * PAGE_SIZE), - paddr, flags); + pag_map(pml4, *vaddr + (i * PAGE_SIZE), paddr, flags); if (pag_map_ret != SUCCESS) { if (i != 0) { for (i -= 1; i != UINT64_MAX; i--) { if (pag_unmap(pml4, - (void*)(((size_t)vaddr) * - i * PAGE_SIZE)) != + *vaddr + + (i * PAGE_SIZE)) != SUCCESS) { panic(NULL, "failed to unmap "