aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/kapi/memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/src/kapi/memory.cpp')
-rw-r--r--arch/x86_64/src/kapi/memory.cpp54
1 files changed, 48 insertions, 6 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;
}