aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64
diff options
context:
space:
mode:
authorMatteo Gmür <matteo.gmuer1@ost.ch>2024-11-09 14:51:10 +0000
committerMatteo Gmür <matteo.gmuer1@ost.ch>2024-11-09 14:51:10 +0000
commitd18cf4a3e4abdea80992b8bba3d1ca50ae215253 (patch)
treedfdbdf4b3b88dffd8cee0ba6233a80549e2beb7c /arch/x86_64
parent416f08ee8791aeeb15e216650711f2a84e6f8114 (diff)
downloadteachos-d18cf4a3e4abdea80992b8bba3d1ca50ae215253.tar.xz
teachos-d18cf4a3e4abdea80992b8bba3d1ca50ae215253.zip
Add switch method to kernel
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/include/arch/memory/paging/inactive_page_table.hpp9
-rw-r--r--arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp25
-rw-r--r--arch/x86_64/src/memory/paging/inactive_page_table.cpp8
3 files changed, 38 insertions, 4 deletions
diff --git a/arch/x86_64/include/arch/memory/paging/inactive_page_table.hpp b/arch/x86_64/include/arch/memory/paging/inactive_page_table.hpp
index 54a53f4..a9ab258 100644
--- a/arch/x86_64/include/arch/memory/paging/inactive_page_table.hpp
+++ b/arch/x86_64/include/arch/memory/paging/inactive_page_table.hpp
@@ -16,13 +16,20 @@ namespace teachos::arch::memory::paging
* @brief Constructor.
*
* @param frame Frame that should be mapped as the level 4 page table.
+ */
+ inactive_page_table(allocator::physical_frame frame);
+
+ /**
+ * @brief Constructor.
+ *
+ * @param frame Frame that should be mapped as the level 4 page table.
* @param active_page_table Actual active page table that should be unmapped so we can map a new level 4
* page table.
* @param temporary_page Temporary page that should be used to map the given frame as the new level 4 page
* table.
*/
inactive_page_table(allocator::physical_frame frame, active_page_table & active_page_table,
- temporary_page temporary_page);
+ temporary_page & temporary_page);
allocator::physical_frame page_table_level_4_frame; ///< Temporary level 4 page table
};
diff --git a/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp b/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp
index 67d1673..0786ec1 100644
--- a/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp
+++ b/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp
@@ -44,8 +44,12 @@ namespace teachos::arch::memory::paging
auto const frame = allocator.allocate_frame();
exception_handling::assert(frame.has_value(),
"[Kernel Mapper] Frame could not be allocated and therefore kernel not mapped");
- inactive_page_table inactive_table{frame.value(), active_table, temporary_page};
- remap_elf_kernel_sections(inactive_table, temporary_page, active_table);
+ inactive_page_table new_table{frame.value(), active_table, temporary_page};
+ remap_elf_kernel_sections(new_table, temporary_page, active_table);
+ auto const old_table = switch_active_page_table(new_table);
+ auto const old_level_4_page =
+ virtual_page::containing_address(old_table.page_table_level_4_frame.start_address());
+ active_table.unmap_page(allocator, old_level_4_page);
}
private:
@@ -84,6 +88,23 @@ namespace teachos::arch::memory::paging
}
/**
+ * @brief Switches the current active table pointed to by the CR3 register with another page table that is currently
+ * inactive.
+ *
+ * @param new_table Inactive page table that should now be made active and replace the current active one.
+ * @return The previous active page table.
+ */
+ auto switch_active_page_table(inactive_page_table new_table) -> inactive_page_table
+ {
+ auto const backup = allocator::physical_frame::containing_address(cpu::read_cr3_register());
+ auto const old_table = inactive_page_table{backup};
+
+ auto const new_address = new_table.page_table_level_4_frame.start_address();
+ cpu::write_cr3_register(new_address);
+ return old_table;
+ }
+
+ /**
* @brief Maps the required entries according to every elf section and it's contained frames. Additionally each of
* thoose frames gets the correct entry flags according to elf section flags.
*
diff --git a/arch/x86_64/src/memory/paging/inactive_page_table.cpp b/arch/x86_64/src/memory/paging/inactive_page_table.cpp
index f6ecb8b..4e0610e 100644
--- a/arch/x86_64/src/memory/paging/inactive_page_table.cpp
+++ b/arch/x86_64/src/memory/paging/inactive_page_table.cpp
@@ -2,8 +2,14 @@
namespace teachos::arch::memory::paging
{
+ inactive_page_table::inactive_page_table(allocator::physical_frame frame)
+ : page_table_level_4_frame{frame}
+ {
+ // Nothing to do
+ }
+
inactive_page_table::inactive_page_table(allocator::physical_frame frame, active_page_table & active_page_table,
- temporary_page temporary_page)
+ temporary_page & temporary_page)
: page_table_level_4_frame{frame}
{
auto table = temporary_page.map_table_frame(page_table_level_4_frame, active_page_table);