feat(pfa): Add PageFrameAllocator class
This commit is contained in:
@@ -10,13 +10,13 @@
|
|||||||
#include <Common/Panic.hpp>
|
#include <Common/Panic.hpp>
|
||||||
#include <Platform/Registers.hpp>
|
#include <Platform/Registers.hpp>
|
||||||
#include <CppLib/Stream.hpp>
|
#include <CppLib/Stream.hpp>
|
||||||
|
#include <Memory/PageFrameAllocator.hpp>
|
||||||
|
|
||||||
namespace Hal {
|
namespace Hal {
|
||||||
constexpr auto InterruptGate = 0x8E;
|
constexpr auto InterruptGate = 0x8E;
|
||||||
constexpr auto TrapGate = 0x8F;
|
constexpr auto TrapGate = 0x8F;
|
||||||
|
|
||||||
InterruptDescriptor* IDT;
|
InterruptDescriptor* IDT;
|
||||||
InterruptDescriptor InterruptDescriptorTable[255]{};
|
|
||||||
IDTRStruct IDTR{};
|
IDTRStruct IDTR{};
|
||||||
|
|
||||||
const char* ExceptionStrings[] = {
|
const char* ExceptionStrings[] = {
|
||||||
@@ -113,7 +113,7 @@ namespace Hal {
|
|||||||
struct SetHandler<N,N> {static void run() {}};
|
struct SetHandler<N,N> {static void run() {}};
|
||||||
|
|
||||||
void IDTInitialize() {
|
void IDTInitialize() {
|
||||||
IDT = (InterruptDescriptor*)&InterruptDescriptorTable;
|
IDT = (InterruptDescriptor*)Memory::g_pfa->Allocate();
|
||||||
IDTR.Limit = 0x0FF;
|
IDTR.Limit = 0x0FF;
|
||||||
IDTR.Base = (uint64_t)&IDT;
|
IDTR.Base = (uint64_t)&IDT;
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -28,10 +28,13 @@
|
|||||||
|
|
||||||
#include <Hal/IDT.hpp>
|
#include <Hal/IDT.hpp>
|
||||||
|
|
||||||
|
#include <Memory/PageFrameAllocator.hpp>
|
||||||
|
|
||||||
using namespace Kt;
|
using namespace Kt;
|
||||||
|
|
||||||
namespace Memory {
|
namespace Memory {
|
||||||
HeapAllocator* g_heap;
|
HeapAllocator* g_heap;
|
||||||
|
PageFrameAllocator* g_pfa;
|
||||||
uint64_t HHDMBase;
|
uint64_t HHDMBase;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -83,12 +86,11 @@ extern "C" void kmain() {
|
|||||||
Memory::HHDMBase = hhdm_offset;
|
Memory::HHDMBase = hhdm_offset;
|
||||||
|
|
||||||
if (memmap_request.response != nullptr) {
|
if (memmap_request.response != nullptr) {
|
||||||
kout << "MemoryManagement: Creating global HeapAllocator" << newline;
|
kout << "MemoryManagement: Creating global PageFrameAllocator" << newline;
|
||||||
|
|
||||||
auto result = Memory::Scan(memmap_request.response);
|
Memory::PageFrameAllocator pmm(Memory::Scan(memmap_request.response));
|
||||||
auto allocator = Memory::HeapAllocator(result);
|
Memory::g_pfa = &pmm;
|
||||||
|
|
||||||
Memory::g_heap = &allocator;
|
|
||||||
} else {
|
} else {
|
||||||
Panic("Guru Meditation Error: System memory map missing!", nullptr);
|
Panic("Guru Meditation Error: System memory map missing!", nullptr);
|
||||||
}
|
}
|
||||||
@@ -97,7 +99,5 @@ extern "C" void kmain() {
|
|||||||
Hal::IDTInitialize();
|
Hal::IDTInitialize();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int*a = (int*)0xffffff;
|
|
||||||
*a=10;
|
|
||||||
hcf();
|
hcf();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* PageFrameAllocator.hpp
|
||||||
|
* Memory allocator for physical pages
|
||||||
|
* Copyright (c) 2025 Daniel Hammer
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PageFrameAllocator.hpp"
|
||||||
|
#include "HHDM.hpp"
|
||||||
|
|
||||||
|
namespace Memory {
|
||||||
|
PageFrameAllocator::PageFrameAllocator(LargestSection section) {
|
||||||
|
/* we need the virtual address rather than the physical address, so we call the helper */
|
||||||
|
g_section = LargestSection{
|
||||||
|
.address = HHDM(section.address),
|
||||||
|
.size = section.size
|
||||||
|
};
|
||||||
|
|
||||||
|
head.next = (Page*)g_section.address;
|
||||||
|
head.next->size = section.size;
|
||||||
|
head.next->next = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* PageFrameAllocator::Allocate() {
|
||||||
|
Page* current = head.next;
|
||||||
|
Page* prev = &head;
|
||||||
|
|
||||||
|
while (current != nullptr) {
|
||||||
|
if (current->size >= 0x1000) {
|
||||||
|
uint64_t current_addr = (uint64_t)current;
|
||||||
|
uint64_t current_end_addr = current_addr + current->size;
|
||||||
|
uint64_t new_size = current->size - 0x1000;
|
||||||
|
|
||||||
|
if (new_size == 0) {
|
||||||
|
prev->next = current->next;
|
||||||
|
return (void*)current;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current->size -= 0x1000;
|
||||||
|
return (void*)current_end_addr - 0x1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = current;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PageFrameAllocator::Free(void* ptr) {
|
||||||
|
auto prev_next = head.next;
|
||||||
|
head.next = (Page*)ptr;
|
||||||
|
|
||||||
|
head.next->next = prev_next;
|
||||||
|
head.next->size = 0x1000;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* PageFrameAllocator.hpp
|
||||||
|
* Memory allocator for physical pages
|
||||||
|
* Copyright (c) 2025 Daniel Hammer
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "Memmap.hpp"
|
||||||
|
|
||||||
|
namespace Memory {
|
||||||
|
class PageFrameAllocator {
|
||||||
|
struct Page {
|
||||||
|
std::size_t size;
|
||||||
|
Page* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
Page head{};
|
||||||
|
|
||||||
|
LargestSection g_section;
|
||||||
|
public:
|
||||||
|
PageFrameAllocator(LargestSection section);
|
||||||
|
|
||||||
|
void* Allocate();
|
||||||
|
void Free(void* ptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern PageFrameAllocator* g_pfa;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user