diff --git a/kernel/include/memory/VMM.h b/kernel/include/memory/VMM.h index 9082789d..0309195d 100644 --- a/kernel/include/memory/VMM.h +++ b/kernel/include/memory/VMM.h @@ -5,13 +5,16 @@ namespace Paging { class VirtualMemoryManager { - void Init(); // fetch page table from cr3 - void Init(PageTable* PML4); + public: + void init(); // fetch page table from cr3 + void init(PageTable* PML4); - void Map(uint64_t virtualAddress, uint64_t physicalAddress); - void Unmap(uint64_t virtualAddress); + void map(uint64_t virtualAddress, uint64_t physicalAddress); + void unmap(uint64_t virtualAddress); private: PageTable* PML4; }; -} \ No newline at end of file +} + +extern Paging::VirtualMemoryManager kernelVMM; \ No newline at end of file diff --git a/kernel/src/init/Init.cpp b/kernel/src/init/Init.cpp index 1b2782db..25a63c27 100644 --- a/kernel/src/init/Init.cpp +++ b/kernel/src/init/Init.cpp @@ -5,6 +5,7 @@ #include "interrupts/Interrupts.h" #include "io/Serial.h" #include "memory/RangeAllocator.h" +#include "memory/VMM.h" #include "panic/hang.h" #include "render/Draw.h" #include "render/TextRenderer.h" @@ -32,4 +33,5 @@ void Init::early_init() // ASSERT(TextRenderer::try_initialize()); physical_allocator.init_from_mmap(); + kernelVMM.init(); } \ No newline at end of file diff --git a/kernel/src/memory/VMM.cpp b/kernel/src/memory/VMM.cpp index 833d9824..029627b2 100644 --- a/kernel/src/memory/VMM.cpp +++ b/kernel/src/memory/VMM.cpp @@ -1,18 +1,22 @@ #include "memory/VMM.h" +#include "memory/RangeAllocator.h" +#include "std/string.h" + +Paging::VirtualMemoryManager kernelVMM; namespace Paging { - void VirtualMemoryManager::Init() + void VirtualMemoryManager::init() { asm volatile("mov %%cr3, %0" : "=r"(PML4)); } - void VirtualMemoryManager::Init(PageTable* PML4) + void VirtualMemoryManager::init(PageTable* PML4) { this->PML4 = PML4; } - void VirtualMemoryManager::Unmap(uint64_t virtualAddress) + void VirtualMemoryManager::unmap(uint64_t virtualAddress) { virtualAddress >>= 12; uint64_t P_i = virtualAddress & 0x1ff; @@ -54,4 +58,63 @@ namespace Paging PDE.ReadWrite = false; PT->entries[P_i] = PDE; } + + void VirtualMemoryManager::map(uint64_t virtualAddress, uint64_t physicalAddress) + { + virtualAddress >>= 12; + uint64_t P_i = virtualAddress & 0x1ff; + virtualAddress >>= 9; + uint64_t PT_i = virtualAddress & 0x1ff; + virtualAddress >>= 9; + uint64_t PD_i = virtualAddress & 0x1ff; + virtualAddress >>= 9; + uint64_t PDP_i = virtualAddress & 0x1ff; + + PageDirectoryEntry PDE; + + PDE = PML4->entries[PDP_i]; + PageTable* PDP; + if (!PDE.Present) + { + PDP = (PageTable*)physical_allocator.request_page(); + memset(PDP, 0, 0x1000); + PDE.Address = (uint64_t)PDP >> 12; + PDE.Present = true; + PDE.ReadWrite = true; + PML4->entries[PDP_i] = PDE; + } + else { PDP = (PageTable*)((uint64_t)PDE.Address << 12); } + + PDE = PDP->entries[PD_i]; + PageTable* PD; + if (!PDE.Present) + { + PD = (PageTable*)physical_allocator.request_page(); + memset(PDP, 0, 0x1000); + PDE.Address = (uint64_t)PD >> 12; + PDE.Present = true; + PDE.ReadWrite = true; + PDP->entries[PD_i] = PDE; + } + else { PD = (PageTable*)((uint64_t)PDE.Address << 12); } + + PDE = PD->entries[PT_i]; + PageTable* PT; + if (!PDE.Present) + { + PT = (PageTable*)physical_allocator.request_page(); + memset(PDP, 0, 0x1000); + PDE.Address = (uint64_t)PT >> 12; + PDE.Present = true; + PDE.ReadWrite = true; + PD->entries[PT_i] = PDE; + } + else { PT = (PageTable*)((uint64_t)PDE.Address << 12); } + + PDE = PT->entries[P_i]; + PDE.Present = true; + PDE.ReadWrite = true; + PDE.Address = physicalAddress >> 12; + PT->entries[P_i] = PDE; + } } \ No newline at end of file