Added a PhysicalMemoryManager class.
Stores a linkedlist of free blocks of PhysicalMemory.
This commit is contained in:
parent
4380590af2
commit
fa2bb4df89
|
@ -15,6 +15,69 @@ struct BootstrapMemory {
|
|||
static BootstrapMemory gBootstrap;
|
||||
static bool gBootstrapEnabled = false;
|
||||
|
||||
class PhysicalMemoryManager {
|
||||
public:
|
||||
// Reads the memory map and takes
|
||||
// control of the available regions.
|
||||
PhysicalMemoryManager() {
|
||||
const limine_memmap_response& memmap = boot::GetMemoryMap();
|
||||
for (uint64_t i = 0; i < memmap.entry_count; i++) {
|
||||
const limine_memmap_entry& entry = *memmap.entries[i];
|
||||
if (entry.type == 0) {
|
||||
uint64_t base = entry.base;
|
||||
uint64_t size = entry.length;
|
||||
if (base == gBootstrap.init_page) {
|
||||
base = gBootstrap.next_page;
|
||||
uint64_t bootstrap_used = gBootstrap.next_page - gBootstrap.init_page;
|
||||
dbgln("[PMM] Taking over from bootstrap, used: %x", bootstrap_used);
|
||||
size -= bootstrap_used;
|
||||
}
|
||||
AddMemoryRegion(base, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t AllocatePage() {
|
||||
if (front_ == nullptr) {
|
||||
panic("No available memory regions.");
|
||||
}
|
||||
|
||||
if (front_->num_pages == 0) {
|
||||
panic("Bad state, empty memory block.");
|
||||
}
|
||||
|
||||
uint64_t page = front_->base;
|
||||
front_->base += 0x1000;
|
||||
front_->num_pages--;
|
||||
if (front_->num_pages == 0) {
|
||||
MemBlock* temp = front_;
|
||||
front_ = front_->next;
|
||||
delete temp;
|
||||
}
|
||||
return page;
|
||||
}
|
||||
void FreePage(uint64_t page) { AddMemoryRegion(page, 0x1000); }
|
||||
|
||||
private:
|
||||
void AddMemoryRegion(uint64_t base, uint64_t size) {
|
||||
MemBlock* block = new MemBlock{
|
||||
.next = front_,
|
||||
.base = base,
|
||||
.num_pages = size >> 12,
|
||||
};
|
||||
front_ = block;
|
||||
}
|
||||
struct MemBlock {
|
||||
MemBlock* next = nullptr;
|
||||
uint64_t base = 0;
|
||||
uint64_t num_pages = 0;
|
||||
};
|
||||
|
||||
MemBlock* front_ = nullptr;
|
||||
};
|
||||
|
||||
static PhysicalMemoryManager* gPmm = nullptr;
|
||||
|
||||
}; // namespace
|
||||
|
||||
void InitBootstrapPageAllocation() {
|
||||
|
@ -36,11 +99,18 @@ void InitBootstrapPageAllocation() {
|
|||
}
|
||||
}
|
||||
|
||||
void InitPhysicalMemoryManager() { gPmm = new PhysicalMemoryManager(); }
|
||||
|
||||
uint64_t AllocatePage() {
|
||||
if (gPmm != nullptr) {
|
||||
return gPmm->AllocatePage();
|
||||
}
|
||||
if (!gBootstrapEnabled) {
|
||||
panic("No Bootstrap Memory Manager");
|
||||
}
|
||||
|
||||
dbgln("[PMM] Boostrap Alloc!");
|
||||
|
||||
uint64_t page = gBootstrap.next_page;
|
||||
if (page == gBootstrap.max_page) {
|
||||
panic("Bootstrap Memory Manager OOM");
|
||||
|
|
|
@ -14,7 +14,8 @@ extern "C" void zion() {
|
|||
|
||||
phys_mem::InitBootstrapPageAllocation();
|
||||
KernelHeap heap(0xFFFFFFFF'40000000, 0xFFFFFFFF'80000000);
|
||||
heap.Allocate(1);
|
||||
phys_mem::InitPhysicalMemoryManager();
|
||||
heap.Allocate(0x2000);
|
||||
|
||||
dbgln("Sleeping!");
|
||||
while (1)
|
||||
|
|
Loading…
Reference in New Issue