diff options
| author | Matteo Gmür <matteo.gmuer1@ost.ch> | 2024-11-02 11:49:38 +0000 |
|---|---|---|
| committer | Matteo Gmür <matteo.gmuer1@ost.ch> | 2024-11-02 11:49:38 +0000 |
| commit | 5ffe7d69545bf098efdd70f105a5df83304b211a (patch) | |
| tree | 52172b6cefe76644e7348f280a289ab52d974d14 | |
| parent | d488a0709c5a2701482130a3d9c972c0b468a1d2 (diff) | |
| download | teachos-5ffe7d69545bf098efdd70f105a5df83304b211a.tar.xz teachos-5ffe7d69545bf098efdd70f105a5df83304b211a.zip | |
Add physical frame iterator and continue implementing kernel mapping.
15 files changed, 353 insertions, 67 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index 1f15c79..42aa6ef 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -52,7 +52,6 @@ target_sources("_memory" PRIVATE "src/memory/paging/virtual_page.cpp" "src/memory/paging/active_page_table.cpp" "src/memory/paging/inactive_page_table.cpp" - "src/memory/paging/kernel_mapper.cpp" "src/memory/paging/tlb.cpp" ) diff --git a/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp b/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp index 4b6c2d4..f2b77f8 100644 --- a/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp +++ b/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp @@ -18,7 +18,7 @@ namespace teachos::arch::memory::allocator * * @param mem_info Structure containg all relevant information to map and allocate memory */ - area_frame_allocator(multiboot::memory_information mem_info); + area_frame_allocator(multiboot::memory_information const & mem_info); /** * @brief Allocate memory by finding and returning a free physical frame. diff --git a/arch/x86_64/include/arch/memory/allocator/physical_frame.hpp b/arch/x86_64/include/arch/memory/allocator/physical_frame.hpp index 146e557..b95687c 100644 --- a/arch/x86_64/include/arch/memory/allocator/physical_frame.hpp +++ b/arch/x86_64/include/arch/memory/allocator/physical_frame.hpp @@ -3,6 +3,7 @@ #include <compare> #include <cstdint> +#include <iterator> namespace teachos::arch::memory::allocator { @@ -17,6 +18,11 @@ namespace teachos::arch::memory::allocator struct physical_frame { /** + * @brief Defaulted constructor. + */ + physical_frame() = default; + + /** * @brief Constructor. * * @param frame_number Index number that should be assigned to this physical frame. @@ -48,8 +54,126 @@ namespace teachos::arch::memory::allocator */ auto operator<=>(const physical_frame & other) const -> std::partial_ordering = default; - std::size_t - frame_number; ///< Index number of the current physical frame, used to distinguish it from other frames. + std::size_t frame_number = + {}; ///< Index number of the current physical frame, used to distinguish it from other frames. + }; + + /** + * @brief Iterator for the frame number + */ + struct physical_frame_iterator + { + using iterator_category = std::random_access_iterator_tag; ///< Iterator category of this type. + using difference_type = std::ptrdiff_t; ///< Type when diving one instance of this iterator by another. + using value_type = physical_frame; ///< Underlying value pointed to by this iterator. + + /** + * @brief Defaulted constructor. + */ + physical_frame_iterator() = default; + + /** + * @brief Constructor. + * + * @param value Underlying value the iterator should point too + */ + explicit physical_frame_iterator(value_type value); + + /** + * @brief Dereferences the initally given pointer to its value. + * + * @return Reference to the value. + */ + auto operator*() -> value_type &; + + /** + * @brief Get underlying value, which is the intially passed pointer. + * + * @return Underlying value passed intially. + */ + auto operator->() -> value_type *; + + /** + * @brief Post increment operator. Returns a copy of the value. + * + * @return Copy of the incremented underlying address. + */ + auto operator++(int) -> physical_frame_iterator; + + /** + * @brief Pre increment operator. Returns a reference to the changed value. + * + * @return Reference to the incremented underlying address. + */ + auto operator++() -> physical_frame_iterator &; + + /** + * @brief Addition assignment operator. Returns a reference to the changed value. + * + * @param operand Value we want to add to the underlying address. + * @return Reference to the changed underlying address. + */ + auto operator+=(difference_type operand) -> physical_frame_iterator &; + + /** + * @brief Subtraction assignment operator. Returns a reference to the changed value. + * + * @param operand Value we want to subtract from the underlying address. + * @return Reference to the changed underlying address. + */ + auto operator-=(difference_type operand) -> physical_frame_iterator &; + + /** + * @brief Addition operator. Returns the changed value. + * + * @param operand Value we want to add to a copy of the underlying address. + * @return Copy of underlying address incremented by the given value. + */ + auto operator+(difference_type operand) const -> physical_frame_iterator; + + /** + * @brief Subtraction operator. Returns the changed value. + * + * @param operand Value we want to subtrcat from a copy of the underlying address. + * @return Copy of underlying address decremented by the given value. + */ + auto operator-(difference_type operand) const -> physical_frame_iterator; + + /** + * @brief Subtraction operator. Returns the size difference between two iterators. + * + * @param other Other iterator we want to substract the underlying address with ours. + * @return Size difference between the underlying address of this instance and the given iterator. + */ + auto operator-(const physical_frame_iterator & other) const -> difference_type; + + /** + * @brief Index operator overload. Returns a reference to the value at the given index. Simply returns the + * dereferenced underlying pointer incremented by the given index. + * + * @param index Index we want to access and get the value from. + * @return Reference to the value at the given index. + */ + auto operator[](difference_type index) const -> value_type; + + /** + * @brief Defaulted comparsion operator. Simply compares the memory address of both iterators. + * + * @param other Other iterator to compare to. + * @return Whether both iterators point to the same underlying address in memory. + */ + auto operator==(physical_frame_iterator const & other) const -> bool = default; + + /** + * @brief Defaulted threeway comparsion operator. Simply compares the memory address of both iterators. + * + * @param other Other iterator to compare to. + * @return Whether the given iterator is smaller or larger than this iterator. + */ + auto operator<=>(physical_frame_iterator const & other) const -> std::strong_ordering = default; + + private: + value_type value = {}; ///< Underlying address the iterator is currently pointing too. }; } // namespace teachos::arch::memory::allocator diff --git a/arch/x86_64/include/arch/memory/multiboot/reader.hpp b/arch/x86_64/include/arch/memory/multiboot/reader.hpp index baa49c9..a5c4872 100644 --- a/arch/x86_64/include/arch/memory/multiboot/reader.hpp +++ b/arch/x86_64/include/arch/memory/multiboot/reader.hpp @@ -1,6 +1,7 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_READER_HPP #define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_READER_HPP +#include "arch/memory/multiboot/elf_symbols_section.hpp" #include "arch/memory/multiboot/memory_map.hpp" #include <cstdint> @@ -13,8 +14,12 @@ namespace teachos::arch::memory::multiboot */ struct memory_information { - std::size_t kernel_start; ///< Start address of the kernel code in memory. - std::size_t kernel_end; ///< End address of the kernel code in memory. + std::size_t kernel_start; ///< Start address of the kernel code in memory. + std::size_t kernel_end; ///< End address of the kernel code in memory. + elf_section_header_container::iterator + begin_kernel; ///< Iterator containing non-owning pointer to the first element of all kernel sections. + elf_section_header_container::iterator + end_kernel; ///< Iterator pointing to one past the last element of all kernel sections. std::size_t multiboot_start; ///< Start address of the multiboot code in memory. std::size_t multiboot_end; ///< End address of the multiboot code in memory. memory_area_container::iterator diff --git a/arch/x86_64/include/arch/memory/paging/active_page_table.hpp b/arch/x86_64/include/arch/memory/paging/active_page_table.hpp index 8e80b51..c183aff 100644 --- a/arch/x86_64/include/arch/memory/paging/active_page_table.hpp +++ b/arch/x86_64/include/arch/memory/paging/active_page_table.hpp @@ -17,8 +17,6 @@ namespace teachos::arch::memory::paging */ struct active_page_table { - typedef void (*function)(active_page_table & active_page_table); - /** * @brief Creates a single instance of an active level 4 page table table and returns the created instance or * alternatively returns the previously created instance instead. The instance is owned by this method and is 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 62c196f..df3ba00 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 @@ -9,7 +9,7 @@ namespace teachos::arch::memory::paging { struct inactive_page_table { - inactive_page_table(allocator::physical_frame frame, active_page_table active_page_table, + inactive_page_table(allocator::physical_frame frame, active_page_table & active_page_table, temporary_page temporary_page); allocator::physical_frame page_table_level_4_frame; 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 0583692..0e2411a 100644 --- a/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp +++ b/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp @@ -7,15 +7,80 @@ namespace teachos::arch::memory::paging { + namespace + { + std::size_t constexpr UNUSED_VIRTUAL_ADDRESS = 0xCAFEBABE; + } // namespace + + typedef shared::container<allocator::physical_frame_iterator> frame_container; + + template<allocator::FrameAllocator T> struct kernel_mapper { - kernel_mapper(active_page_table & active_table); + kernel_mapper(T & allocator, multiboot::memory_information const & mem_info) + : allocator(allocator) + , mem_info(mem_info) + { + // Nothing to do + } - auto with(inactive_page_table inactive_page_table, temporary_page temporary_page, - active_page_table::function f) -> void; + auto remap_kernel() -> void + { + temporary_page temp_page{virtual_page{UNUSED_VIRTUAL_ADDRESS}, allocator}; + auto & active_table = active_page_table::create_or_get(); + auto const frame = allocator.allocate_frame(); + exception_handling::assert(frame.has_value(), + "[Kernel Mapper] Frame could not be allocated and therefore kernel not mapped"); + auto const inactive_table = inactive_page_table{frame.value(), active_table, temp_page}; + map_elf_sections(inactive_table, temp_page, active_table); + } private: - active_page_table & active_table; + auto map_elf_sections(inactive_page_table inactive_page_table, temporary_page temporary_page, + active_page_table & active_table) -> void + { + auto const backup = allocator::physical_frame::containing_address(PAGE_TABLE_LEVEL_4_ADDRESS); + auto page_table_level4 = temporary_page.map_table_frame(backup, active_table); + + active_table.active_handle[511].set_entry(inactive_page_table.page_table_level_4_frame, + entry::PRESENT | entry::WRITABLE); + tlb_flush_all(); + map_kernel_sections(active_table); + + page_table_level4[511].set_entry(backup, entry::PRESENT | entry::WRITABLE); + tlb_flush_all(); + temporary_page.unmap(active_table); + } + + auto map_kernel_sections(active_page_table & active_table) -> void + { + multiboot::elf_section_header_container sections{mem_info.begin_kernel, mem_info.end_kernel}; + for (auto const & section : sections) + { + if (!section.flags.contains_flags(multiboot::elf_section_flags::OCCUPIES_MEMORY)) + { + continue; + } + exception_handling::assert(section.virtual_address % allocator::PAGE_FRAME_SIZE == 0U, + "[Kernel Mapper] Section must be page aligned"); + auto const start_frame = allocator::physical_frame::containing_address(section.virtual_address); + auto const end_frame = + allocator::physical_frame::containing_address(section.virtual_address + section.section_size); + + allocator::physical_frame_iterator const begin{start_frame}; + allocator::physical_frame_iterator const end{end_frame}; + frame_container frames{begin, end}; + + for (auto frame : frames) + { + // TODO: Use actual elf section flags, convert from one to the other flag type. + active_table.identity_map(allocator, frame, entry::WRITABLE); + } + } + } + + T & allocator; + multiboot::memory_information const & mem_info; }; } // namespace teachos::arch::memory::paging diff --git a/arch/x86_64/include/arch/shared/container.hpp b/arch/x86_64/include/arch/shared/container.hpp index 8ea0d08..bc2a5f6 100644 --- a/arch/x86_64/include/arch/shared/container.hpp +++ b/arch/x86_64/include/arch/shared/container.hpp @@ -20,6 +20,11 @@ namespace teachos::arch::shared using size_type = std::size_t; ///< Maximum size of this container. /** + * @brief Defaulted constructor. + */ + container() = default; + + /** * @brief Constructor. * * @param begin Iterator containing non-owning pointer to the first element of all memory areas. @@ -29,8 +34,7 @@ namespace teachos::arch::shared : begin_itr(begin) , end_itr(end) { - exception_handling::assert(begin != iterator{}, "[Memory Area] Attempted to pass nullptr as begin iterator"); - exception_handling::assert(end != iterator{}, "[Memory Area] Attempted to pass nullptr as end iterator"); + // Nothing to do } /** @@ -65,8 +69,8 @@ namespace teachos::arch::shared auto empty() const -> bool { return size() == 0; } private: - iterator begin_itr; ///< Pointer to the first element of the given template type. - iterator end_itr; ///< Pointer to one pas the last element of the given template type. + iterator begin_itr = {}; ///< Pointer to the first element of the given template type. + iterator end_itr = {}; ///< Pointer to one pas the last element of the given template type. }; } // namespace teachos::arch::shared diff --git a/arch/x86_64/include/arch/shared/random_access_iterator.hpp b/arch/x86_64/include/arch/shared/random_access_iterator.hpp index 13deb68..b1a800c 100644 --- a/arch/x86_64/include/arch/shared/random_access_iterator.hpp +++ b/arch/x86_64/include/arch/shared/random_access_iterator.hpp @@ -26,8 +26,7 @@ namespace teachos::arch::shared /** * @brief Constructor. * - * @param p Underlying address the iterator should point too, ensure to not pass an invalid pointer or the - * constructor will halt execution. + * @param p Underlying address the iterator should point too. */ explicit random_access_iterator(value_type * p) : ptr(p) @@ -144,14 +143,6 @@ namespace teachos::arch::shared auto operator==(random_access_iterator const & other) const -> bool = default; /** - * @brief Defaulted negated comparsion operator. Simply compares the memory address of both iterators. - * - * @param other Other iterator to compare to. - * @return Whether both iterators don't point to the same underlying address in memory. - */ - auto operator!=(random_access_iterator const & other) const -> bool = default; - - /** * @brief Defaulted threeway comparsion operator. Simply compares the memory address of both iterators. * * @param other Other iterator to compare to. diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index c89ae44..59e453a 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -3,6 +3,7 @@ #include "arch/exception_handling/assert.hpp" #include "arch/memory/allocator/area_frame_allocator.hpp" #include "arch/memory/multiboot/reader.hpp" +#include "arch/memory/paging/kernel_mapper.hpp" #include "arch/memory/paging/temporary_page.hpp" #include "arch/video/vga/text.hpp" @@ -27,6 +28,9 @@ namespace teachos::arch::kernel memory::paging::temporary_page temp_page{page, allocator}; temp_page.zero_entries(active_table); + memory::paging::kernel_mapper kernel(allocator, memory_information); + kernel.remap_kernel(); + // memory::paging::map_next_free_page_to_frame(allocator, page, 0U); // auto optional_frame = memory::paging::translate_page(page); // video::vga::text::newline(); diff --git a/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp b/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp index 1e87147..5d56a2a 100644 --- a/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp +++ b/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp @@ -8,7 +8,7 @@ namespace teachos::arch::memory::allocator { - area_frame_allocator::area_frame_allocator(multiboot::memory_information mem_info) + area_frame_allocator::area_frame_allocator(multiboot::memory_information const & mem_info) : next_free_frame(0U) , current_area(std::nullopt) , memory_areas(mem_info.begin_area, mem_info.end_area) diff --git a/arch/x86_64/src/memory/allocator/physical_frame.cpp b/arch/x86_64/src/memory/allocator/physical_frame.cpp index bef9322..9307602 100644 --- a/arch/x86_64/src/memory/allocator/physical_frame.cpp +++ b/arch/x86_64/src/memory/allocator/physical_frame.cpp @@ -14,4 +14,127 @@ namespace teachos::arch::memory::allocator } auto physical_frame::start_address() const -> physical_address { return frame_number * PAGE_FRAME_SIZE; } + + /** + * @brief Constructor. + * + * @param value Underlying value the iterator should point too + */ + physical_frame_iterator::physical_frame_iterator(physical_frame_iterator::value_type value) + : value(value) + { + // Nothing to do + } + + /** + * @brief Dereferences the initally given pointer to its value. + * + * @return Reference to the value. + */ + auto physical_frame_iterator::operator*() -> physical_frame_iterator::value_type & { return value; } + + /** + * @brief Get underlying value, which is the intially passed pointer. + * + * @return Underlying value passed intially. + */ + auto physical_frame_iterator::operator->() -> physical_frame_iterator::value_type * { return &value; } + + /** + * @brief Post increment operator. Returns a copy of the value. + * + * @return Copy of the incremented underlying address. + */ + auto physical_frame_iterator::operator++(int) -> physical_frame_iterator + { + physical_frame_iterator const old_value = *this; + ++value.frame_number; + return old_value; + } + + /** + * @brief Pre increment operator. Returns a reference to the changed value. + * + * @return Reference to the incremented underlying address. + */ + auto physical_frame_iterator::operator++() -> physical_frame_iterator & + { + ++value.frame_number; + return *this; + } + + /** + * @brief Addition assignment operator. Returns a reference to the changed value. + * + * @param operand Value we want to add to the underlying address. + * @return Reference to the changed underlying address. + */ + auto + physical_frame_iterator::operator+=(physical_frame_iterator::difference_type operand) -> physical_frame_iterator & + { + value.frame_number += operand; + return *this; + } + + /** + * @brief Subtraction assignment operator. Returns a reference to the changed value. + * + * @param operand Value we want to subtract from the underlying address. + * @return Reference to the changed underlying address. + */ + auto + physical_frame_iterator::operator-=(physical_frame_iterator::difference_type operand) -> physical_frame_iterator & + { + value.frame_number -= operand; + return *this; + } + + /** + * @brief Addition operator. Returns the changed value. + * + * @param operand Value we want to add to a copy of the underlying address. + * @return Copy of underlying address incremented by the given value. + */ + auto + physical_frame_iterator::operator+(physical_frame_iterator::difference_type operand) const -> physical_frame_iterator + { + return physical_frame_iterator{physical_frame_iterator::value_type{value.frame_number + operand}}; + } + + /** + * @brief Subtraction operator. Returns the changed value. + * + * @param operand Value we want to subtrcat from a copy of the underlying address. + * @return Copy of underlying address decremented by the given value. + */ + auto + physical_frame_iterator::operator-(physical_frame_iterator::difference_type operand) const -> physical_frame_iterator + { + return physical_frame_iterator{physical_frame_iterator::value_type{value.frame_number - operand}}; + } + + /** + * @brief Subtraction operator. Returns the size difference between two iterators. + * + * @param other Other iterator we want to substract the underlying address with ours. + * @return Size difference between the underlying address of this instance and the given iterator. + */ + auto physical_frame_iterator::operator-(const physical_frame_iterator & other) const + -> physical_frame_iterator::difference_type + { + return value.frame_number - other.value.frame_number; + } + + /** + * @brief Index operator overload. Returns a reference to the value at the given index. Simply returns the + * dereferenced underlying pointer incremented by the given index. + * + * @param index Index we want to access and get the value from. + * @return Reference to the value at the given index. + */ + auto physical_frame_iterator::operator[](physical_frame_iterator::difference_type index) const + -> physical_frame_iterator::value_type + { + return physical_frame_iterator::value_type{value.frame_number + index}; + } } // namespace teachos::arch::memory::allocator diff --git a/arch/x86_64/src/memory/multiboot/reader.cpp b/arch/x86_64/src/memory/multiboot/reader.cpp index c3a78df..e35baf3 100644 --- a/arch/x86_64/src/memory/multiboot/reader.cpp +++ b/arch/x86_64/src/memory/multiboot/reader.cpp @@ -34,8 +34,9 @@ namespace teachos::arch::memory::multiboot end_area = begin_area + number_of_entries; } - auto process_elf_sections(elf_symbols_section_header * symbol, uint64_t & kernel_start, - uint64_t & kernel_end) -> void + auto process_elf_sections(elf_symbols_section_header * symbol, std::size_t & kernel_start, std::size_t & kernel_end, + elf_section_header_container::iterator & begin_kernel, + elf_section_header_container::iterator & end_kernel) -> void { auto const expected_entry_size = symbol->entry_size; auto constexpr actual_entry_size = sizeof(elf_section_header); @@ -49,12 +50,12 @@ namespace teachos::arch::memory::multiboot exception_handling::assert(expected_total_size == actual_total_size, "[Multiboot Reader] Unexpected elf symbols section header total size"); - auto const begin = elf_section_header_container::iterator{reinterpret_cast<elf_section_header *>(&symbol->end)}; - auto const end = begin + symbol->number_of_sections; - exception_handling::assert(begin->is_null(), + begin_kernel = elf_section_header_container::iterator{reinterpret_cast<elf_section_header *>(&symbol->end)}; + end_kernel = begin_kernel + symbol->number_of_sections; + exception_handling::assert(begin_kernel->is_null(), "[Multiboot Reader] Elf symbols section not starting with SHT_NULL section"); - elf_section_header_container container{begin, end}; + elf_section_header_container container{begin_kernel, end_kernel}; auto const elf_section_with_lowest_virtual_address = std::ranges::min_element(container, [](elf_section_header const & a, elf_section_header const & b) { @@ -93,6 +94,8 @@ namespace teachos::arch::memory::multiboot { memory_information mem_info{UINT64_MAX, 0U, + elf_section_header_container::iterator{}, + elf_section_header_container::iterator{}, boot::multiboot_information_pointer, 0U, memory_area_container::iterator{}, @@ -108,7 +111,8 @@ namespace teachos::arch::memory::multiboot { case tag_type::ELF_SECTIONS: { auto const symbol = reinterpret_cast<elf_symbols_section_header *>(tag); - process_elf_sections(symbol, mem_info.kernel_start, mem_info.kernel_end); + process_elf_sections(symbol, mem_info.kernel_start, mem_info.kernel_end, mem_info.begin_kernel, + mem_info.end_kernel); break; } case tag_type::MEMORY_MAP: { 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 afba1f0..de0421d 100644 --- a/arch/x86_64/src/memory/paging/inactive_page_table.cpp +++ b/arch/x86_64/src/memory/paging/inactive_page_table.cpp @@ -2,7 +2,7 @@ namespace teachos::arch::memory::paging { - inactive_page_table::inactive_page_table(allocator::physical_frame frame, active_page_table active_page_table, + inactive_page_table::inactive_page_table(allocator::physical_frame frame, active_page_table & active_page_table, temporary_page temporary_page) : page_table_level_4_frame{frame} { diff --git a/arch/x86_64/src/memory/paging/kernel_mapper.cpp b/arch/x86_64/src/memory/paging/kernel_mapper.cpp deleted file mode 100644 index 07d55ff..0000000 --- a/arch/x86_64/src/memory/paging/kernel_mapper.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "arch/memory/paging/kernel_mapper.hpp" - -#include "arch/memory/allocator/physical_frame.hpp" -#include "arch/memory/paging/tlb.hpp" - -namespace teachos::arch::memory::paging -{ - kernel_mapper::kernel_mapper(active_page_table & active_table) - : active_table(active_table) - { - // Nothing to do - } - - auto kernel_mapper::with(inactive_page_table inactive_page_table, temporary_page temporary_page, - active_page_table::function f) -> void - { - auto backup = allocator::physical_frame::containing_address(PAGE_TABLE_LEVEL_4_ADDRESS); - auto page_table_level4 = temporary_page.map_table_frame(backup, active_table); - - active_table.active_handle[511].set_entry(inactive_page_table.page_table_level_4_frame, - entry::PRESENT | entry::WRITABLE); - tlb_flush_all(); - - f(active_table); - - page_table_level4[511].set_entry(backup, entry::PRESENT | entry::WRITABLE); - tlb_flush_all(); - - temporary_page.unmap(active_table); - } -} // namespace teachos::arch::memory::paging |
