Add a bootstrap physical memory manager.
This will allow the real physical memory manager to use allocations.
This commit is contained in:
parent
747c2a4e17
commit
2d719d0443
|
@ -7,6 +7,7 @@ add_executable(zion
|
|||
interrupt/interrupt_enter.s
|
||||
memory/kernel_heap.cpp
|
||||
memory/paging_util.cpp
|
||||
memory/physical_memory.cpp
|
||||
zion.cpp)
|
||||
|
||||
target_include_directories(zion
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "boot/boot_info.h"
|
||||
#include "debug/debug.h"
|
||||
#include "memory/physical_memory.h"
|
||||
|
||||
#define PRESENT_BIT 0x1
|
||||
#define READ_WRITE_BIT 0x2
|
||||
|
@ -39,6 +40,31 @@ uint64_t ShiftForEntryIndexing(uint64_t addr, uint64_t offset) {
|
|||
addr <<= 3;
|
||||
return addr;
|
||||
}
|
||||
|
||||
void MapPage(uint64_t virt, uint64_t phys) {
|
||||
if (PageLoaded(virt)) {
|
||||
panic("Allocating Over Existing Page: %m", virt);
|
||||
}
|
||||
|
||||
if (!PageDirectoryPointerLoaded(virt)) {
|
||||
uint64_t page = phys_mem::AllocatePage();
|
||||
*Pml4Entry(virt) = page | PRESENT_BIT | READ_WRITE_BIT;
|
||||
ZeroOutPage(PageDirectoryPointerEntry(virt));
|
||||
}
|
||||
if (!PageDirectoryLoaded(virt)) {
|
||||
uint64_t page = phys_mem::AllocatePage();
|
||||
*PageDirectoryPointerEntry(virt) = page | PRESENT_BIT | READ_WRITE_BIT;
|
||||
ZeroOutPage(PageDirectoryEntry(virt));
|
||||
}
|
||||
if (!PageTableLoaded(virt)) {
|
||||
uint64_t page = phys_mem::AllocatePage();
|
||||
*PageDirectoryEntry(virt) = page | PRESENT_BIT | READ_WRITE_BIT;
|
||||
ZeroOutPage(PageTableEntry(virt));
|
||||
}
|
||||
|
||||
*PageTableEntry(virt) = PageAlign(phys) | PRESENT_BIT | READ_WRITE_BIT;
|
||||
ZeroOutPage(reinterpret_cast<uint64_t*>(virt));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void InitPaging() {
|
||||
|
@ -55,10 +81,10 @@ void InitializePml4(uint64_t pml4_physical_addr) {
|
|||
pml4_virtual[0x1FE] = recursive_entry;
|
||||
}
|
||||
|
||||
void AllocatePageDirectoryPointer(uint64_t addr);
|
||||
void AllocatePageDirectory(uint64_t addr);
|
||||
void AllocatePageTable(uint64_t addr);
|
||||
void AllocatePage(uint64_t addr) { panic("Page Allocation Not Implemented."); }
|
||||
void AllocatePage(uint64_t addr) {
|
||||
uint64_t physical_page = phys_mem::AllocatePage();
|
||||
MapPage(addr, physical_page);
|
||||
}
|
||||
|
||||
void EnsureResident(uint64_t addr, uint64_t size) {
|
||||
uint64_t max = addr + size;
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
#include "memory/physical_memory.h"
|
||||
|
||||
#include "boot/boot_info.h"
|
||||
#include "debug/debug.h"
|
||||
|
||||
namespace phys_mem {
|
||||
namespace {
|
||||
|
||||
struct BootstrapMemory {
|
||||
uint64_t init_page = 0;
|
||||
uint64_t next_page = 0;
|
||||
uint64_t max_page = 0;
|
||||
};
|
||||
|
||||
static BootstrapMemory gBootstrap;
|
||||
static bool gBootstrapEnabled = false;
|
||||
|
||||
}; // namespace
|
||||
|
||||
void InitBootstrapPageAllocation() {
|
||||
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];
|
||||
// We may want to chose a high address space to not limit
|
||||
// the number of buffers we can allocate later but
|
||||
// if we limit the number of pages this should be fine.
|
||||
// Currently set to the minimum of 3 for one kernel heap allocation:
|
||||
// PageDirectory + PageTable + Page
|
||||
if (entry.type == 0 && entry.length >= 0x3000) {
|
||||
gBootstrap.init_page = entry.base;
|
||||
gBootstrap.next_page = entry.base;
|
||||
gBootstrap.max_page = entry.base + 0x3000;
|
||||
gBootstrapEnabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t AllocatePage() {
|
||||
if (!gBootstrapEnabled) {
|
||||
panic("No Bootstrap Memory Manager");
|
||||
}
|
||||
|
||||
uint64_t page = gBootstrap.next_page;
|
||||
if (page == gBootstrap.max_page) {
|
||||
panic("Bootstrap Memory Manager OOM");
|
||||
}
|
||||
gBootstrap.next_page += 0x1000;
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
} // namespace phys_mem
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace phys_mem {
|
||||
|
||||
// Called before creating a kernel heap object
|
||||
// that allows dynamic allocation. The real
|
||||
// PhysicalMemoryManager requires some allocations
|
||||
// to initialize so we need this first.
|
||||
void InitBootstrapPageAllocation();
|
||||
|
||||
void InitPhysicalMemoryManager();
|
||||
|
||||
uint64_t AllocatePage();
|
||||
void FreePage(uint64_t page);
|
||||
|
||||
} // namespace phys_mem
|
|
@ -1,21 +1,22 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "boot/boot_info.h"
|
||||
#include "boot/limine.h"
|
||||
#include "common/gdt.h"
|
||||
#include "debug/debug.h"
|
||||
#include "interrupt/interrupt.h"
|
||||
#include "memory/kernel_heap.h"
|
||||
#include "memory/paging_util.h"
|
||||
#include "memory/physical_memory.h"
|
||||
|
||||
extern "C" void zion() {
|
||||
InitGdt();
|
||||
InitIdt();
|
||||
InitPaging();
|
||||
|
||||
phys_mem::InitBootstrapPageAllocation();
|
||||
KernelHeap heap(0xFFFFFFFF'40000000, 0xFFFFFFFF'80000000);
|
||||
heap.Allocate(1);
|
||||
|
||||
dbgln("Sleeping!");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue