diff --git a/zion/CMakeLists.txt b/zion/CMakeLists.txt index ef48bff..2156aee 100644 --- a/zion/CMakeLists.txt +++ b/zion/CMakeLists.txt @@ -15,6 +15,7 @@ add_executable(zion loader/init_loader.cpp memory/kernel_heap.cpp memory/kernel_stack_manager.cpp + memory/kernel_vmm.cpp memory/paging_util.cpp memory/physical_memory.cpp memory/slab_allocator.cpp diff --git a/zion/memory/kernel_vmm.cpp b/zion/memory/kernel_vmm.cpp new file mode 100644 index 0000000..54a2a41 --- /dev/null +++ b/zion/memory/kernel_vmm.cpp @@ -0,0 +1,32 @@ +#include "memory/kernel_vmm.h" + +#include "debug/debug.h" +#include "memory/paging_util.h" + +namespace { + +KernelVmm* gKernelVmm = nullptr; + +} +KernelVmm::KernelVmm() { + if (gKernelVmm) { + panic("KernelVmm double init."); + } + gKernelVmm = this; +} + +uint64_t KernelVmm::AcquireSlabHeapRegion(uint64_t slab_size_bytes) { + return gKernelVmm->AcquireSlabHeapRegionInternal(slab_size_bytes); +} + +uint64_t KernelVmm::AcquireSlabHeapRegionInternal(uint64_t slab_size_bytes) { + uint64_t next_slab = next_slab_heap_page_; + if (next_slab >= kKernelBuddyHeapEnd) { + panic("Slab heap overrun"); + } + next_slab_heap_page_ += slab_size_bytes; + // TODO: Consider handling this as a part of a page-fault handler + // rather than auto mapping all over the place. + EnsureResident(next_slab, slab_size_bytes); + return next_slab; +} diff --git a/zion/memory/kernel_vmm.h b/zion/memory/kernel_vmm.h new file mode 100644 index 0000000..dfa983c --- /dev/null +++ b/zion/memory/kernel_vmm.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#include "memory/constants.h" + +class KernelVmm { + public: + KernelVmm(); + + static uint64_t AcquireSlabHeapRegion(uint64_t slab_size_bytes); + + private: + uint64_t next_slab_heap_page_ = kKernelSlabHeapStart; + + uint64_t AcquireSlabHeapRegionInternal(uint64_t slab_size_bytes); +}; diff --git a/zion/memory/slab_allocator.cpp b/zion/memory/slab_allocator.cpp index e858258..3188867 100644 --- a/zion/memory/slab_allocator.cpp +++ b/zion/memory/slab_allocator.cpp @@ -2,25 +2,13 @@ #include "debug/debug.h" #include "memory/constants.h" +#include "memory/kernel_vmm.h" #include "memory/paging_util.h" namespace { -// TODO: Store these in a kernel VMM. const uint64_t kSlabSize = 4 * KiB; const uint64_t kSlabMask = ~(kSlabSize - 1); -uint64_t gNextSlab = kKernelSlabHeapStart; - -uint64_t NextSlab() { - // FIXME: Synchronization. - uint64_t next_slab = gNextSlab; - if (next_slab >= kKernelBuddyHeapEnd) { - panic("Slab heap overrun"); - } - gNextSlab += kSlabSize; - EnsureResident(next_slab, 1); - return next_slab; -} } // namespace @@ -91,8 +79,8 @@ glcr::ErrorOr SlabAllocator::Allocate() { return slab->Allocate(); } - dbgln("Allocating new kernel slab size {}", elem_size_); - void* next_slab = (uint64_t*)NextSlab(); + void* next_slab = + reinterpret_cast(KernelVmm::AcquireSlabHeapRegion(kSlabSize)); slabs_.PushFront(glcr::AdoptPtr(new (next_slab) Slab(elem_size_))); return slabs_.PeekFront()->Allocate(); } diff --git a/zion/zion.cpp b/zion/zion.cpp index 44ad639..3fc40bd 100644 --- a/zion/zion.cpp +++ b/zion/zion.cpp @@ -10,6 +10,7 @@ #include "loader/init_loader.h" #include "memory/kernel_heap.h" #include "memory/kernel_stack_manager.h" +#include "memory/kernel_vmm.h" #include "memory/paging_util.h" #include "memory/physical_memory.h" #include "scheduler/process_manager.h" @@ -23,6 +24,7 @@ extern "C" void zion() { early_dbgln("[boot] Init Physical Memory Manager."); phys_mem::InitBootstrapPageAllocation(); + KernelVmm kvmm; KernelHeap heap; phys_mem::InitPhysicalMemoryManager(); phys_mem::DumpRegions();