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
|
interrupt/interrupt_enter.s
|
||||||
memory/kernel_heap.cpp
|
memory/kernel_heap.cpp
|
||||||
memory/paging_util.cpp
|
memory/paging_util.cpp
|
||||||
|
memory/physical_memory.cpp
|
||||||
zion.cpp)
|
zion.cpp)
|
||||||
|
|
||||||
target_include_directories(zion
|
target_include_directories(zion
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "boot/boot_info.h"
|
#include "boot/boot_info.h"
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
|
#include "memory/physical_memory.h"
|
||||||
|
|
||||||
#define PRESENT_BIT 0x1
|
#define PRESENT_BIT 0x1
|
||||||
#define READ_WRITE_BIT 0x2
|
#define READ_WRITE_BIT 0x2
|
||||||
|
@ -39,6 +40,31 @@ uint64_t ShiftForEntryIndexing(uint64_t addr, uint64_t offset) {
|
||||||
addr <<= 3;
|
addr <<= 3;
|
||||||
return addr;
|
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
|
} // namespace
|
||||||
|
|
||||||
void InitPaging() {
|
void InitPaging() {
|
||||||
|
@ -55,10 +81,10 @@ void InitializePml4(uint64_t pml4_physical_addr) {
|
||||||
pml4_virtual[0x1FE] = recursive_entry;
|
pml4_virtual[0x1FE] = recursive_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AllocatePageDirectoryPointer(uint64_t addr);
|
void AllocatePage(uint64_t addr) {
|
||||||
void AllocatePageDirectory(uint64_t addr);
|
uint64_t physical_page = phys_mem::AllocatePage();
|
||||||
void AllocatePageTable(uint64_t addr);
|
MapPage(addr, physical_page);
|
||||||
void AllocatePage(uint64_t addr) { panic("Page Allocation Not Implemented."); }
|
}
|
||||||
|
|
||||||
void EnsureResident(uint64_t addr, uint64_t size) {
|
void EnsureResident(uint64_t addr, uint64_t size) {
|
||||||
uint64_t max = addr + 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 <stdint.h>
|
||||||
|
|
||||||
#include "boot/boot_info.h"
|
|
||||||
#include "boot/limine.h"
|
|
||||||
#include "common/gdt.h"
|
#include "common/gdt.h"
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
#include "interrupt/interrupt.h"
|
#include "interrupt/interrupt.h"
|
||||||
#include "memory/kernel_heap.h"
|
#include "memory/kernel_heap.h"
|
||||||
#include "memory/paging_util.h"
|
#include "memory/paging_util.h"
|
||||||
|
#include "memory/physical_memory.h"
|
||||||
|
|
||||||
extern "C" void zion() {
|
extern "C" void zion() {
|
||||||
InitGdt();
|
InitGdt();
|
||||||
InitIdt();
|
InitIdt();
|
||||||
InitPaging();
|
InitPaging();
|
||||||
|
|
||||||
|
phys_mem::InitBootstrapPageAllocation();
|
||||||
KernelHeap heap(0xFFFFFFFF'40000000, 0xFFFFFFFF'80000000);
|
KernelHeap heap(0xFFFFFFFF'40000000, 0xFFFFFFFF'80000000);
|
||||||
heap.Allocate(1);
|
heap.Allocate(1);
|
||||||
|
|
||||||
|
dbgln("Sleeping!");
|
||||||
while (1)
|
while (1)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue