From e284d574ed9237a215d994861cc502452fec11ce Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 13 Mar 2026 22:28:50 +0100 Subject: kernel/memory: implement basic bitmap allocator --- kernel/kapi/memory.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) (limited to 'kernel/kapi') diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp index 7c9b1da..1699cd3 100644 --- a/kernel/kapi/memory.cpp +++ b/kernel/kapi/memory.cpp @@ -2,8 +2,17 @@ #include "kapi/system.hpp" +#include "kernel/memory/bitmap_allocator.hpp" + +#include + +#include +#include #include +#include #include +#include +#include #include namespace kapi::memory @@ -20,6 +29,11 @@ namespace kapi::memory system::panic("Tried to allocate frames without an active allocator."); } + auto mark_used(frame) -> void override + { + system::panic("Tried to mark frame as used without an active allocator."); + } + auto release_many(std::pair) -> void override { system::panic("Tried to release frames without an active allocator."); @@ -48,11 +62,17 @@ namespace kapi::memory constinit bad_frame_allocator bad_frame_allocator::instance{}; constinit bad_page_mapper bad_page_mapper::instance{}; + auto constinit allocator = std::optional{}; } // namespace constinit auto static active_frame_allocator = static_cast(&bad_frame_allocator::instance); constinit auto static active_page_mapper = static_cast(&bad_page_mapper::instance); + auto get_frame_allocator() -> frame_allocator & + { + return *active_frame_allocator; + } + auto set_frame_allocator(frame_allocator & allocator) -> std::optional { if (&allocator == active_frame_allocator) @@ -73,12 +93,12 @@ namespace kapi::memory auto allocate_frame() -> std::optional { - return active_frame_allocator->allocate(); + return get_frame_allocator().allocate(); } auto allocate_many_frames(std::size_t count) -> std::optional> { - return active_frame_allocator->allocate_many(count); + return get_frame_allocator().allocate_many(count); } auto map(page page, frame frame) -> std::byte * @@ -91,4 +111,34 @@ namespace kapi::memory return active_page_mapper->unmap(page); } -} // namespace kapi::memory \ No newline at end of file + auto init_pmm(std::size_t frame_count, void (&handoff_handler)(frame_allocator &)) -> void + { + auto const bitmap_bytes = (frame_count + 7uz) / 8uz; + auto const bitmap_pages = (bitmap_bytes + page::size - 1uz) / page::size; + + auto const bitmap_frames = allocate_many_frames(bitmap_pages); + if (!bitmap_frames) + { + system::panic("[OS:MEM] Not enough memory for bitmap allocator!"); + } + + auto const base_address = 0xffff'c000'0000'0000uz; + auto const flags = page_mapper::flags::writable | page_mapper::flags::supervisor_only; + + std::ranges::for_each(std::views::iota(0uz, bitmap_pages), [&](auto index) { + auto page = page::containing(linear_address{base_address + index * page::size}); + auto frame = memory::frame(bitmap_frames->first.number() + index); + active_page_mapper->map(page, frame, flags); + }); + + auto bitmap_ptr = std::bit_cast(base_address); + auto bitmap = std::span{bitmap_ptr, (bitmap_bytes + sizeof(std::uint64_t) - 1uz) / sizeof(std::uint64_t)}; + + allocator.emplace(bitmap, frame_count); + + handoff_handler(allocator.value()); + set_frame_allocator(allocator.value()); + kstd::println("[OS:MEM] Physical memory manager initialized."); + } + +} // namespace kapi::memory -- cgit v1.2.3