aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2025-12-12 13:00:26 +0100
committerFelix Morgner <felix.morgner@ost.ch>2025-12-12 13:00:26 +0100
commit8fc5f9e3cc28b07b1f120eb1ffedc042fa6662b8 (patch)
treec2edd9ade614858e844e27677da8abafdda5a669
parent0a2c2c408d8fda248d56df349b4c9f9cc5e8bade (diff)
downloadteachos-8fc5f9e3cc28b07b1f120eb1ffedc042fa6662b8.tar.xz
teachos-8fc5f9e3cc28b07b1f120eb1ffedc042fa6662b8.zip
x86_64/kapi: implement remaining mapping steps
-rw-r--r--arch/x86_64/src/kapi/memory.cpp54
-rw-r--r--kapi/include/kapi/boot.hpp2
-rw-r--r--kapi/include/kapi/memory/page.hpp9
-rw-r--r--src/main.cpp1
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!");
}