fix(vmm): Fix crash on CR3 loading

This commit is contained in:
Daniel Hammer
2025-04-18 14:20:17 +02:00
parent 2515149f28
commit d63addfb64
3 changed files with 29 additions and 25 deletions
+2 -10
View File
@@ -102,19 +102,11 @@ extern "C" void kmain() {
#if defined (__x86_64__)
Hal::IDTInitialize();
#endif
// auto kaddr_request_response = kernel_address_request.response;
Memory::VMM::Paging g_paging{};
g_paging.Init((uint64_t)&KernelStartSymbol, ((uint64_t)&KernelEndSymbol - (uint64_t)&KernelStartSymbol), memmap_request.response);
g_paging.Init((uint64_t)&KernelStartSymbol, ((uint64_t)&KernelEndSymbol - (uint64_t)&KernelStartSymbol));
// g_paging.Map(0xcfc0000, 0xcfc0000);
// kout << "0x" << base::hex << Memory::VMM::GetCR3();
kout << "0x" << base::hex << 0xdeadbeef << "\n";
kout << "0x" << base::hex << Memory::HHDM(0xdeadbeef) << "\n";
#endif
Hal::Halt();
}
+25 -14
View File
@@ -14,32 +14,43 @@ namespace Memory::VMM {
PML4 = (PageTable*)SubHHDM((PageTable*)Memory::g_pfa->AllocateZeroed());
}
void Paging::Init(std::uint64_t kernelBaseVirt, std::uint64_t kernelSize) {
void Paging::Init(std::uint64_t kernelBaseVirt, std::uint64_t kernelSize, limine_memmap_response* memMap) {
// Map kernel
Kt::KernelLogStream(Kt::DEBUG, "VMM") << "Paging::Init called with kernelBaseVirt as 0x" << base::hex << kernelBaseVirt << " and kernelSize as " << base::dec << kernelSize;
for (std::uint64_t pageAddr = kernelBaseVirt; pageAddr < (kernelBaseVirt + kernelSize); pageAddr += 0x1000) {
Kt::KernelLogStream(Kt::DEBUG, "VMM") << "Mapping 0x" << base::hex << GetPhysKernelAddress(pageAddr) << " to 0x" << pageAddr;
Map(GetPhysKernelAddress(pageAddr), pageAddr);
}
// TODO map HHDM
// TODO map ACPI tables
// Map HHDM memMap entries
LoadCR3((PageTable*)&PML4);
for (size_t i = 0; i < memMap->entry_count; i++) {
auto entry = memMap->entries[i];
for (size_t pageAddr = entry->base; pageAddr < (entry->base + entry->length); pageAddr += 0x1000) {
Map(pageAddr, HHDM(pageAddr));
}
}
LoadCR3(PML4);
Kt::KernelLogStream(Kt::OK, "VMM") << "Switched CR3";
}
PageTable* Paging::HandleLevel(VirtualAddress virtualAddress, PageTable* table, const size_t level) {
PageTableEntry* entry = (PageTableEntry*)Memory::HHDM(&table->entries[virtualAddress.GetIndex(level)]);
entry->Present = true;
entry->Writable = true;
uint64_t downLevelAddr = Memory::SubHHDM((uint64_t)Memory::g_pfa->AllocateZeroed());
entry->Address = downLevelAddr >> 12;
return (PageTable*)downLevelAddr;
if (!entry->Present) {
entry->Present = true;
entry->Writable = true;
uint64_t downLevelAddr = Memory::SubHHDM((uint64_t)Memory::g_pfa->AllocateZeroed());
entry->Address = downLevelAddr >> 12;
return (PageTable*)downLevelAddr;
} else {
return (PageTable*)(entry->Address << 12);
}
}
void Paging::Map(std::uint64_t physicalAddress, std::uint64_t virtualAddress) {
@@ -58,7 +69,7 @@ namespace Memory::VMM {
pageEntry->Present = true;
pageEntry->Writable = true;
pageEntry->Address = virtualAddress >> 12;
pageEntry->Address = physicalAddress >> 12;
}
std::uint64_t Paging::GetPhysAddr(std::uint64_t pml4, std::uint64_t virtualAddress, bool use40BitL1) {
+2 -1
View File
@@ -1,4 +1,5 @@
#pragma once
#include <limine.h>
#include <cstdint>
#include <Terminal/Terminal.hpp>
@@ -87,7 +88,7 @@ namespace Memory::VMM {
PageTable* HandleLevel(VirtualAddress virtualAddress, PageTable* table, size_t level);
public:
Paging();
void Init(std::uint64_t kernelBaseVirt, std::uint64_t kernelSize);
void Init(std::uint64_t kernelBaseVirt, std::uint64_t kernelSize, limine_memmap_response* memMap);
void Map(std::uint64_t physicalAddress, std::uint64_t virtualAddress);
static std::uint64_t GetPhysAddr(std::uint64_t PML4, std::uint64_t virtualAddress, bool use40BitL1 = false);
std::uint64_t GetPhysAddr(std::uint64_t virtualAddress);