#include "kapi/memory.hpp" #include "kapi/memory/frame.hpp" #include "kapi/memory/frame_allocator.hpp" #include "kapi/system.hpp" #include "x86_64/boot/boot.hpp" #include "x86_64/boot/ld.hpp" #include "x86_64/cpu/registers.hpp" #include "x86_64/memory/region_allocator.hpp" #include #include namespace teachos::memory { std::size_t const PLATFORM_FRAME_SIZE{4096}; namespace { // NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables) auto constinit is_initialized = std::atomic_flag{}; auto constinit allocator = static_cast(nullptr); // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables) auto create_memory_information() -> x86_64::region_allocator::memory_information { auto const & mbi = boot::x86_64::multiboot_information_pointer.get(); auto map = mbi->memory_map(); // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) return {.image_range = std::make_pair(physical_address{&boot::x86_64::_start_physical}, physical_address{&boot::x86_64::_end_physical}), .mbi_range = std::make_pair(physical_address{std::bit_cast(mbi)}, physical_address{std::bit_cast(mbi) + mbi->size_bytes()}), .memory_map = map}; // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) }; auto create_early_frame_allocator() { auto memory_map = boot::x86_64::multiboot_information_pointer->maybe_memory_map(); if (!memory_map) { system::panic("[x86_64] Failed to create early allocator, no memory map available."); } return x86_64::region_allocator{create_memory_information()}; } auto enable_cpu_protections() -> void { cpu::x86_64::set_cr0_bit(cpu::x86_64::cr0_flags::WRITE_PROTECT); // set_efer_bit(efer_flags::NXE); } } // namespace auto active_allocator() -> frame_allocator & { if (!allocator) { system::panic("[x86_64] The frame allocator has not been set yet."); } return *allocator; } auto init() -> void { if (is_initialized.test_and_set()) { system::panic("[x86_64] Memory management has already been initialized."); } [[maybe_unused]] auto allocator = create_early_frame_allocator(); enable_cpu_protections(); // paging::kernel_mapper kernel(allocator, memory_information); // kernel.remap_kernel(); // video::vga::text::write("Kernel remapping successful", video::vga::text::common_attributes::green_on_black); // video::vga::text::newline(); // remap_heap(heap::KERNEL_HEAP_START, heap::KERNEL_HEAP_SIZE); // video::vga::text::write("Heap remapping successful", video::vga::text::common_attributes::green_on_black); // video::vga::text::newline(); } } // namespace teachos::memory