diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2025-12-12 13:00:26 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2025-12-12 13:00:26 +0100 |
| commit | 8fc5f9e3cc28b07b1f120eb1ffedc042fa6662b8 (patch) | |
| tree | c2edd9ade614858e844e27677da8abafdda5a669 | |
| parent | 0a2c2c408d8fda248d56df349b4c9f9cc5e8bade (diff) | |
| download | teachos-8fc5f9e3cc28b07b1f120eb1ffedc042fa6662b8.tar.xz teachos-8fc5f9e3cc28b07b1f120eb1ffedc042fa6662b8.zip | |
x86_64/kapi: implement remaining mapping steps
| -rw-r--r-- | arch/x86_64/src/kapi/memory.cpp | 54 | ||||
| -rw-r--r-- | kapi/include/kapi/boot.hpp | 2 | ||||
| -rw-r--r-- | kapi/include/kapi/memory/page.hpp | 9 | ||||
| -rw-r--r-- | src/main.cpp | 1 |
4 files changed, 59 insertions, 7 deletions
diff --git a/arch/x86_64/src/kapi/memory.cpp b/arch/x86_64/src/kapi/memory.cpp index a20483c..abc0526 100644 --- a/arch/x86_64/src/kapi/memory.cpp +++ b/arch/x86_64/src/kapi/memory.cpp @@ -1,5 +1,6 @@ #include "kapi/memory.hpp" +#include "kapi/boot.hpp" #include "kapi/cio.hpp" #include "kapi/system.hpp" @@ -19,6 +20,7 @@ #include <multiboot2/information.hpp> #include <atomic> +#include <bit> #include <memory> #include <span> @@ -114,6 +116,42 @@ namespace teachos::memory return *new_pml4_frame; } + auto remap_kernel() -> void + { + auto kernel_mapper = x86_64::kernel_mapper{boot::bootstrap_information.mbi}; + kernel_mapper.remap_kernel(); + } + + 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}; + auto vga_virtual_start = linear_address{vga_base + std::bit_cast<std::uintptr_t>(&boot::x86_64::TEACHOS_VMA)}; + + auto page = page::containing(vga_virtual_start); + auto frame = frame::containing(vga_physical_start); + + mapper.map(page, frame, page_mapper::flags::writable); + } + + 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(); + auto mbi_physical_start = physical_address{mbi_base}; + auto mbi_virtual_start = linear_address{mbi_base + std::bit_cast<std::uintptr_t>(&boot::x86_64::TEACHOS_VMA)}; + auto mbi_block_count = (mbi_size + PLATFORM_FRAME_SIZE - 1) / PLATFORM_FRAME_SIZE; + + for (auto i = 0uz; i < mbi_block_count; ++i) + { + auto page = page::containing(mbi_virtual_start) + 1; + auto frame = frame::containing(mbi_physical_start) + 1; + mapper.map(page, frame, page_mapper::flags::empty); + } + + boot::bootstrap_information.mbi = std::bit_cast<multiboot2::information_view const *>(mbi_virtual_start.raw()); + } + } // namespace auto active_frame_allocator() -> frame_allocator & @@ -138,11 +176,14 @@ namespace teachos::memory auto init() -> void { auto static constinit is_initialized = std::atomic_flag{}; + if (is_initialized.test_and_set()) { system::panic("[x86_64] Memory management has already been initialized."); } + cio::println("[x86_64:MEM] Enabling additional CPU protection features."); + enable_cpu_protections(); auto early_allocator = create_early_frame_allocator(); @@ -154,17 +195,18 @@ namespace teachos::memory auto new_pml4_frame = inject_faux_pml4(allocation_buffer); - auto kernel_mapper = x86_64::kernel_mapper{boot::bootstrap_information.mbi}; - kernel_mapper.remap_kernel(); - cio::println("[x86_64:MEM] prepared new kernel image page maps."); + cio::println("[x86_64:MEM] Preparing new paging hierarchy."); + + remap_kernel(); + remap_vga_text_mode_buffer(recursive_mapper); + remap_multiboot_information(recursive_mapper); + + cio::println("[x86_64:MEM] Switching to new paging hierarchy."); auto cr3 = cpu::x86_64::cr3::read(); cr3.address(new_pml4_frame.start_address()); cpu::x86_64::cr3::write(cr3); - // 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(); mapper = nullptr; allocator = nullptr; } diff --git a/kapi/include/kapi/boot.hpp b/kapi/include/kapi/boot.hpp index 9c344cf..dd99198 100644 --- a/kapi/include/kapi/boot.hpp +++ b/kapi/include/kapi/boot.hpp @@ -11,7 +11,7 @@ namespace teachos::boot //! @qualifier platform-defined //! An object passed from the early pre-main stage to the kernel executable. - extern "C" information const bootstrap_information; + extern "C" information bootstrap_information; } // namespace teachos::boot #endif diff --git a/kapi/include/kapi/memory/page.hpp b/kapi/include/kapi/memory/page.hpp index 66e8482..0b7083a 100644 --- a/kapi/include/kapi/memory/page.hpp +++ b/kapi/include/kapi/memory/page.hpp @@ -51,6 +51,15 @@ namespace teachos::memory return m_number; } + //! Get a handle n pages after the one referenced by this handle. + //! + //! @param n The positive offset to this page. + //! @return A handle referencing the page n pages after the one referenced by this handle. + constexpr auto operator+(std::size_t n) const noexcept -> page + { + return page{m_number + n}; + } + //! Check if this page handle reference the same frame as another one. //! //! @param other Another page handle. diff --git a/src/main.cpp b/src/main.cpp index fc7d2f4..3394275 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,7 @@ auto main() -> int teachos::cio::println("[OS] IO subsystem initialized."); teachos::memory::init(); + teachos::cio::println("[OS] Memory subsystem initialized."); teachos::system::panic("Returning from kernel main!"); } |
