aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2025-12-01 19:32:19 +0100
committerFelix Morgner <felix.morgner@ost.ch>2025-12-01 19:32:19 +0100
commit203355e51690073e571d4906d53f2494c3dad41b (patch)
tree538180b7d5fbaf4327394521c02d403537314c6b
parent005d7ea3df29e736750d409b816caa29cf9bab2f (diff)
downloadteachos-203355e51690073e571d4906d53f2494c3dad41b.tar.xz
teachos-203355e51690073e571d4906d53f2494c3dad41b.zip
x86_64/memory: prepare scoped_mapping extraction
-rw-r--r--arch/x86_64/CMakeLists.txt2
-rw-r--r--arch/x86_64/include/x86_64/memory/scoped_mapping.hpp39
-rw-r--r--arch/x86_64/src/kapi/memory.cpp12
-rw-r--r--arch/x86_64/src/memory/scoped_mapping.cpp73
4 files changed, 126 insertions, 0 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt
index 8451945..4d32f76 100644
--- a/arch/x86_64/CMakeLists.txt
+++ b/arch/x86_64/CMakeLists.txt
@@ -27,6 +27,7 @@ target_sources("x86_64" PRIVATE
"src/memory/page_table.cpp"
"src/memory/paging_root.cpp"
"src/memory/region_allocator.cpp"
+ "src/memory/scoped_mapping.cpp"
# VGA text mode
"src/vga/text.cpp"
@@ -53,6 +54,7 @@ target_sources("x86_64" PRIVATE
"include/x86_64/memory/page_table.hpp"
"include/x86_64/memory/paging_root.hpp"
"include/x86_64/memory/region_allocator.hpp"
+ "include/x86_64/memory/scoped_mapping.hpp"
# VGA I/O
"include/x86_64/vga/text.hpp"
diff --git a/arch/x86_64/include/x86_64/memory/scoped_mapping.hpp b/arch/x86_64/include/x86_64/memory/scoped_mapping.hpp
new file mode 100644
index 0000000..1719e6b
--- /dev/null
+++ b/arch/x86_64/include/x86_64/memory/scoped_mapping.hpp
@@ -0,0 +1,39 @@
+#ifndef TEACHOS_X86_64_SCOPED_MAPPING_HPP
+#define TEACHOS_X86_64_SCOPED_MAPPING_HPP
+
+#include "kapi/memory.hpp"
+
+#include "x86_64/memory/page_table.hpp"
+
+namespace teachos::memory::x86_64
+{
+
+ struct scoped_mapping
+ {
+ scoped_mapping(scoped_mapping const &) = delete;
+ scoped_mapping(scoped_mapping &&);
+ scoped_mapping(linear_address address, frame_allocator & allocator);
+
+ ~scoped_mapping();
+
+ auto operator=(scoped_mapping const &) -> scoped_mapping = delete;
+ auto operator=(scoped_mapping &&) -> scoped_mapping &;
+
+ auto map(frame frame, page_table::entry::flags flags) -> std::byte *;
+ auto unmap() -> void;
+
+ template<typename DataType>
+ auto map_as(frame frame, page_table::entry::flags flags) -> DataType *
+ {
+ return std::bit_cast<DataType *>(map(frame, flags));
+ }
+
+ private:
+ linear_address m_address;
+ frame_allocator * m_allocator;
+ bool m_mapped;
+ };
+
+} // namespace teachos::memory::x86_64
+
+#endif \ No newline at end of file
diff --git a/arch/x86_64/src/kapi/memory.cpp b/arch/x86_64/src/kapi/memory.cpp
index f34729a..920c82b 100644
--- a/arch/x86_64/src/kapi/memory.cpp
+++ b/arch/x86_64/src/kapi/memory.cpp
@@ -10,6 +10,7 @@
#include "x86_64/memory/page_table.hpp"
#include "x86_64/memory/paging_root.hpp"
#include "x86_64/memory/region_allocator.hpp"
+#include "x86_64/memory/scoped_mapping.hpp"
#include <multiboot2/information.hpp>
@@ -140,8 +141,19 @@ namespace teachos::memory
auto allocator = create_early_frame_allocator();
enable_cpu_protections();
+
+ // TODO: remove
inject_faux_pml4(allocator);
+ // TODO: implement
+ auto temporary_mapper = x86_64::scoped_mapping{linear_address{unused_page_address}, allocator};
+ auto new_pml4_frame = allocator.allocate();
+
+ auto new_plm4 = temporary_mapper.map_as<x86_64::page_table>(
+ *new_pml4_frame, x86_64::page_table::entry::flags::present | x86_64::page_table::entry::flags::writable);
+ (*new_plm4)[510].frame(new_pml4_frame.value(),
+ x86_64::page_table::entry::flags::present | x86_64::page_table::entry::flags::writable);
+
// paging::kernel_mapper kernel(allocator, memory_information);
// kernel.remap_kernel();
// video::vga::text::write("Kernel remapping successful", video::vga::text::common_attributes::green_on_black);
diff --git a/arch/x86_64/src/memory/scoped_mapping.cpp b/arch/x86_64/src/memory/scoped_mapping.cpp
new file mode 100644
index 0000000..c436ee5
--- /dev/null
+++ b/arch/x86_64/src/memory/scoped_mapping.cpp
@@ -0,0 +1,73 @@
+#include "x86_64/memory/scoped_mapping.hpp"
+
+#include "kapi/memory.hpp"
+#include "kapi/system.hpp"
+
+#include "x86_64/memory/mmu.hpp"
+
+#include <utility>
+
+namespace teachos::memory::x86_64
+{
+
+ scoped_mapping::scoped_mapping(scoped_mapping && other)
+ : m_address{std::exchange(other.m_address, linear_address{})}
+ , m_allocator{std::exchange(other.m_allocator, nullptr)}
+ , m_mapped{std::exchange(other.m_mapped, false)}
+ {}
+
+ scoped_mapping::scoped_mapping(linear_address address, frame_allocator & allocator)
+ : m_address{address}
+ , m_allocator{&allocator}
+ , m_mapped{false}
+ {}
+
+ scoped_mapping::~scoped_mapping()
+ {
+ if (m_mapped)
+ {
+ unmap();
+ x86_64::tlb_flush(m_address);
+ }
+ }
+
+ auto scoped_mapping::operator=(scoped_mapping && other) -> scoped_mapping &
+ {
+ if (&other == this)
+ {
+ return *this;
+ }
+
+ using std::swap;
+
+ swap(m_address, other.m_address);
+ swap(m_allocator, other.m_allocator);
+ swap(m_mapped, other.m_mapped);
+
+ return *this;
+ }
+
+ auto scoped_mapping::map(frame frame, page_table::entry::flags flags) -> std::byte *
+ {
+ static_cast<void>(frame);
+ static_cast<void>(flags);
+
+ m_mapped = true;
+
+ return nullptr;
+ }
+
+ auto scoped_mapping::unmap() -> void
+ {
+ if (!m_mapped)
+ {
+ system::panic("[MEM] Tried to release an unmapped temporary mapping!");
+ }
+
+ // TODO: scan pages
+ // TODO: remove mapping
+ // TODO: release temporary table frames
+ m_mapped = false;
+ }
+
+} // namespace teachos::memory::x86_64 \ No newline at end of file