From d18cf4a3e4abdea80992b8bba3d1ca50ae215253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Sat, 9 Nov 2024 14:51:10 +0000 Subject: Add switch method to kernel --- .../arch/memory/paging/inactive_page_table.hpp | 9 +++++++- .../include/arch/memory/paging/kernel_mapper.hpp | 25 ++++++++++++++++++++-- .../src/memory/paging/inactive_page_table.cpp | 8 ++++++- 3 files changed, 38 insertions(+), 4 deletions(-) (limited to 'arch') 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 @@ -12,6 +12,13 @@ namespace teachos::arch::memory::paging */ struct inactive_page_table { + /** + * @brief Constructor. + * + * @param frame Frame that should be mapped as the level 4 page table. + */ + inactive_page_table(allocator::physical_frame frame); + /** * @brief Constructor. * @@ -22,7 +29,7 @@ namespace teachos::arch::memory::paging * 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: @@ -83,6 +87,23 @@ namespace teachos::arch::memory::paging temporary_page.unmap_page(active_table); } + /** + * @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); -- cgit v1.2.3