diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-03-16 19:03:53 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-03-16 19:03:53 +0100 |
| commit | 69a92ce3077f01ce43daef5681db298594a4badc (patch) | |
| tree | de3a97018853d453c550bba7a1507211ae28fd31 /arch/x86_64/kapi | |
| parent | cc5f6ef95acb7a0024c43eba314eb1f3563b41b8 (diff) | |
| download | teachos-69a92ce3077f01ce43daef5681db298594a4badc.tar.xz teachos-69a92ce3077f01ce43daef5681db298594a4badc.zip | |
x86_64/memory: remove recursive mapping
Diffstat (limited to 'arch/x86_64/kapi')
| -rw-r--r-- | arch/x86_64/kapi/memory.cpp | 147 |
1 files changed, 58 insertions, 89 deletions
diff --git a/arch/x86_64/kapi/memory.cpp b/arch/x86_64/kapi/memory.cpp index 11bc69c..f74eea6 100644 --- a/arch/x86_64/kapi/memory.cpp +++ b/arch/x86_64/kapi/memory.cpp @@ -1,7 +1,6 @@ #include "kapi/memory.hpp" #include "kapi/boot.hpp" -#include "kapi/memory/buffered_allocator.hpp" #include "kapi/system.hpp" #include "arch/boot/boot.hpp" @@ -10,11 +9,7 @@ #include "arch/memory/kernel_mapper.hpp" #include "arch/memory/mmu.hpp" #include "arch/memory/page_table.hpp" -#include "arch/memory/page_utilities.hpp" -#include "arch/memory/paging_root.hpp" -#include "arch/memory/recursive_page_mapper.hpp" #include "arch/memory/region_allocator.hpp" -#include "arch/memory/scoped_mapping.hpp" #include <kstd/print> @@ -26,7 +21,6 @@ #include <bit> #include <cstddef> #include <cstdint> -#include <memory> #include <optional> #include <ranges> #include <span> @@ -37,12 +31,7 @@ namespace kapi::memory namespace { - constexpr auto static unused_page_address = linear_address{0x0000'7fff'cafe'faceuz}; - constexpr auto static recursive_page_map_index = arch::memory::page_table::entry_count - 2; - auto constinit region_based_allocator = std::optional<arch::memory::region_allocator>{}; - auto constinit allocation_buffer = std::optional<buffered_allocator<4>>{}; - auto constinit recursive_page_mapper = std::optional<arch::memory::recursive_page_mapper>{}; //! Instantiate a basic, memory region based, early frame allocator for remapping. auto collect_memory_information() @@ -71,65 +60,13 @@ namespace kapi::memory arch::cpu::i32_efer::set(arch::cpu::i32_efer::flags::execute_disable_bit_enable); } - //! Inject, or graft, a faux recursive PML4 into the active page mapping structure. - auto inject_faux_pml4(frame_allocator & allocator, page_mapper & mapper) - { - using arch::memory::page_table; - using arch::memory::paging_root; - using arch::memory::pml_index; - using entry_flags = arch::memory::page_table::entry::flags; - - auto page = page::containing(unused_page_address); - - auto temporary_mapper = arch::memory::scoped_mapping{page, mapper}; - auto new_pml4_frame = allocator.allocate(); - - auto pml4 = std::construct_at(temporary_mapper.map_as<page_table>(*new_pml4_frame, entry_flags::writable)); - (*pml4)[recursive_page_map_index].frame(new_pml4_frame.value(), entry_flags::present | entry_flags::writable); - - auto pml4_index = pml_index<4>(page); - auto old_pml4 = paging_root::get(); - auto pml4_entry = (*old_pml4)[pml4_index]; - - auto pml3_index = pml_index<3>(page); - auto old_pml3 = old_pml4->next(pml4_index); - auto pml3_entry = (**old_pml3)[pml3_index]; - - auto pml2_index = pml_index<2>(page); - auto old_pml2 = (**old_pml3).next(pml3_index); - auto pml2_entry = (**old_pml2)[pml2_index]; - - auto pml1_index = pml_index<1>(page); - auto old_pml1 = (**old_pml2).next(pml2_index); - auto pml1_entry = (**old_pml1)[pml1_index]; - - (*paging_root::get())[recursive_page_map_index].frame(new_pml4_frame.value(), - entry_flags::present | entry_flags::writable); - - arch::memory::tlb_flush_all(); - - auto new_pml4 = paging_root::get(); - (*new_pml4)[pml4_index] = pml4_entry; - - auto new_pml3 = new_pml4->next(pml4_index); - (**new_pml3)[pml3_index] = pml3_entry; - - auto new_pml2 = (**new_pml3).next(pml3_index); - (**new_pml2)[pml2_index] = pml2_entry; - - auto new_pml1 = (**new_pml2).next(pml2_index); - (**new_pml1)[pml1_index] = pml1_entry; - - return *new_pml4_frame; - } - - auto remap_kernel(page_mapper & mapper) -> void + [[maybe_unused]] auto remap_kernel(page_mapper & mapper) -> void { auto kernel_mapper = arch::memory::kernel_mapper{boot::bootstrap_information.mbi}; kernel_mapper.remap_kernel(mapper); } - auto remap_vga_text_mode_buffer(page_mapper & mapper) -> void + [[maybe_unused]] auto remap_vga_text_mode_buffer(page_mapper & mapper) -> void { constexpr auto vga_base = std::uintptr_t{0xb8000}; auto vga_physical_start = physical_address{vga_base}; @@ -141,7 +78,7 @@ namespace kapi::memory mapper.map(page, frame, page_mapper::flags::writable | page_mapper::flags::supervisor_only); } - auto remap_multiboot_information(page_mapper & mapper) -> void + [[maybe_unused]] auto remap_multiboot_information(page_mapper & mapper) -> void { auto mbi_base = std::bit_cast<std::uintptr_t>(boot::bootstrap_information.mbi); auto mbi_size = boot::bootstrap_information.mbi->size_bytes(); @@ -157,7 +94,7 @@ namespace kapi::memory } } - auto handoff_to_kernel_pmm(frame_allocator & new_allocator) -> void + [[maybe_unused]] auto handoff_to_kernel_pmm(frame_allocator & new_allocator) -> void { auto memory_map = boot::bootstrap_information.mbi->memory_map(); @@ -196,6 +133,39 @@ namespace kapi::memory std::ranges::for_each(std::views::iota(mbi_start, mbi_end), [&](auto frame) { new_allocator.mark_used(frame); }); } + auto establish_higher_half_direct_mapping() -> void + { + auto hhdm_frame = kapi::memory::allocate_frame(); + auto hhdm_pml3 = static_cast<arch::memory::page_table *>(hhdm_frame->start_address()); + hhdm_pml3->clear(); + + std::ranges::for_each(std::views::iota(0uz, 512uz), [&](auto index) { + auto frame = kapi::memory::frame{(1024uz * 1024uz * 1024uz * index)}; + auto & entry = (*hhdm_pml3)[index]; + entry.frame(frame, arch::memory::page_table::entry::flags::present | + arch::memory::page_table::entry::flags::writable | + arch::memory::page_table::entry::flags::huge_page); + }); + + auto current_cr3 = arch::cpu::cr3::read(); + auto pml4_address = linear_address{current_cr3.address().raw()}; + auto pml4 = static_cast<arch::memory::page_table *>(pml4_address); + (*pml4)[256].frame(*hhdm_frame, arch::memory::page_table::entry::flags::present | + arch::memory::page_table::entry::flags::writable | + arch::memory::page_table::entry::flags::global); + } + + auto clear_lower_address_space() -> void + { + auto current_cr3 = arch::cpu::cr3::read(); + auto pml4_address = memory::higher_half_direct_map_base + current_cr3.address().raw(); + auto pml4 = static_cast<arch::memory::page_table *>(pml4_address); + + std::ranges::for_each(std::views::iota(0uz, 1uz), [&](auto index) { (*pml4)[index].clear(); }); + + arch::memory::tlb_flush_all(); + } + } // namespace auto init() -> void @@ -212,37 +182,36 @@ namespace kapi::memory enable_cpu_protections(); region_based_allocator.emplace(collect_memory_information()); - allocation_buffer.emplace(&*region_based_allocator); - set_frame_allocator(*allocation_buffer); + set_frame_allocator(*region_based_allocator); - recursive_page_mapper.emplace(); - set_page_mapper(*recursive_page_mapper); + kstd::println("[x86_64:MEM] Establishing higher-half direct mapping."); - kstd::println("[x86_64:MEM] Preparing new paging hierarchy."); + establish_higher_half_direct_mapping(); + clear_lower_address_space(); - auto new_pml4_frame = inject_faux_pml4(*allocation_buffer, *recursive_page_mapper); + kstd::println("[x86_64:MEM] Preparing new paging hierarchy."); - remap_kernel(*recursive_page_mapper); - remap_vga_text_mode_buffer(*recursive_page_mapper); - remap_multiboot_information(*recursive_page_mapper); + // remap_kernel(*recursive_page_mapper); + // remap_vga_text_mode_buffer(*recursive_page_mapper); + // remap_multiboot_information(*recursive_page_mapper); - kstd::println("[x86_64:MEM] Switching to new paging hierarchy."); + // kstd::println("[x86_64:MEM] Switching to new paging hierarchy."); - auto cr3 = arch::cpu::cr3::read(); - cr3.frame(new_pml4_frame); - arch::cpu::cr3::write(cr3); + // auto cr3 = arch::cpu::cr3::read(); + // cr3.frame(new_pml4_frame); + // arch::cpu::cr3::write(cr3); - auto memory_map = boot::bootstrap_information.mbi->memory_map(); - auto highest_byte = std::ranges::max(std::views::transform( - std::views::filter(memory_map.regions(), - [](auto const & region) { return region.type == multiboot2::memory_type::available; }), - [](auto const & region) { return region.base + region.size_in_B; })); + // auto memory_map = boot::bootstrap_information.mbi->memory_map(); + // auto highest_byte = std::ranges::max(std::views::transform( + // std::views::filter(memory_map.regions(), + // [](auto const & region) { return region.type == multiboot2::memory_type::available; }), + // [](auto const & region) { return region.base + region.size_in_B; })); - init_pmm(frame::containing(physical_address{highest_byte}).number() + 1, handoff_to_kernel_pmm); + // init_pmm(frame::containing(physical_address{highest_byte}).number() + 1, handoff_to_kernel_pmm); - kstd::println("[x86_64:MEM] Releasing bootstrap memory allocators."); - allocation_buffer.reset(); - region_based_allocator.reset(); + // kstd::println("[x86_64:MEM] Releasing bootstrap memory allocators."); + // allocation_buffer.reset(); + // region_based_allocator.reset(); } } // namespace kapi::memory |
