diff options
Diffstat (limited to 'arch/x86_64/src')
| -rw-r--r-- | arch/x86_64/src/kapi/memory.cpp | 74 |
1 files changed, 71 insertions, 3 deletions
diff --git a/arch/x86_64/src/kapi/memory.cpp b/arch/x86_64/src/kapi/memory.cpp index 99dcb5c..f34729a 100644 --- a/arch/x86_64/src/kapi/memory.cpp +++ b/arch/x86_64/src/kapi/memory.cpp @@ -1,28 +1,34 @@ #include "kapi/memory.hpp" -#include "kapi/memory/frame.hpp" -#include "kapi/memory/frame_allocator.hpp" +#include "kapi/cio.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/mmu.hpp" +#include "x86_64/memory/page_table.hpp" +#include "x86_64/memory/paging_root.hpp" #include "x86_64/memory/region_allocator.hpp" #include <multiboot2/information.hpp> #include <atomic> +#include <memory> #include <span> namespace teachos::memory { std::size_t const PLATFORM_FRAME_SIZE{4096}; + std::size_t const PLATFORM_PAGE_SIZE{PLATFORM_FRAME_SIZE}; namespace { // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) auto constinit allocator = static_cast<frame_allocator *>(nullptr); + constexpr auto static unused_page_address = 0x0000'7fff'cafe'faceuz; + auto create_memory_information() -> x86_64::region_allocator::memory_information { auto const & mbi = boot::bootstrap_information.mbi; @@ -51,6 +57,67 @@ namespace teachos::memory cpu::x86_64::cr0::set(cpu::x86_64::cr0::flags::write_protect); cpu::x86_64::i32_efer::set(cpu::x86_64::i32_efer::flags::execute_disable_bit_enable); } + + auto inject_faux_pml4(frame_allocator & allocator) -> void + { + using entry_flags = x86_64::page_table::entry::flags; + using page_table = x86_64::page_table; + + auto temporary_page = page::containing(linear_address{unused_page_address}); + auto temporary_page_address = temporary_page.start_address(); + + auto & pml4 = x86_64::paging_root::get(); + + // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers) + auto faux_pml4_frame = + allocator.allocate() + .and_then([&](auto frame) -> auto { + auto index = temporary_page_address >> 39 & 0x1ffu; + pml4[index].frame(frame, entry_flags::present | entry_flags::writable); + return pml4.next(index); + }) + .and_then([&](auto pml) -> auto { + std::construct_at(pml); + auto index = temporary_page_address >> 30 & 0x1ffu; + (*pml)[index].frame(*allocator.allocate(), entry_flags::present | entry_flags::writable); + return pml->next(index); + }) + .and_then([&](auto pml) -> auto { + std::construct_at(pml); + auto index = temporary_page_address >> 21 & 0x1ffu; + (*pml)[index].frame(*allocator.allocate(), entry_flags::present | entry_flags::writable); + return pml->next(index); + }) + .transform([&](auto pml) -> auto { + std::construct_at(pml); + auto index = temporary_page_address >> 12 & 0x1ffu; + (*pml)[index].frame(*allocator.allocate(), entry_flags::present | entry_flags::writable); + return pml; + }) + .and_then([&](auto pml) -> auto { + auto faux_pml4_pointer = std::bit_cast<page_table *>(temporary_page_address.raw()); + auto faux_pml4 = std::construct_at<page_table>(faux_pml4_pointer); + + auto index = temporary_page_address >> 12 & 0x1ffu; + auto frame = (*pml)[index].frame(); + + (*faux_pml4)[510].frame(*frame, entry_flags::present | entry_flags::writable); + return frame; + }); + // NOLINTEND(cppcoreguidelines-avoid-magic-numbers) + + if (!faux_pml4_frame) + { + system::panic("[MEM] Failed to map and construct faux PML4"); + } + + // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers) + pml4[510].frame(*faux_pml4_frame, entry_flags::present | entry_flags::writable); + x86_64::tlb_flush_all(); + + cio::println("[MEM] Injected faux PML4 as recursive map."); + } + } // namespace auto active_allocator() -> frame_allocator & @@ -71,8 +138,9 @@ namespace teachos::memory system::panic("[x86_64] Memory management has already been initialized."); } - [[maybe_unused]] auto allocator = create_early_frame_allocator(); + auto allocator = create_early_frame_allocator(); enable_cpu_protections(); + inject_faux_pml4(allocator); // paging::kernel_mapper kernel(allocator, memory_information); // kernel.remap_kernel(); |
