aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/kapi
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-03-16 19:03:53 +0100
committerFelix Morgner <felix.morgner@ost.ch>2026-03-16 19:03:53 +0100
commit69a92ce3077f01ce43daef5681db298594a4badc (patch)
treede3a97018853d453c550bba7a1507211ae28fd31 /arch/x86_64/kapi
parentcc5f6ef95acb7a0024c43eba314eb1f3563b41b8 (diff)
downloadteachos-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.cpp147
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