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