diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86_64/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/allocator/tiny_frame_allocator.hpp | 14 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/paging/page_table.hpp | 18 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/paging/temporary_page.hpp | 68 | ||||
| -rw-r--r-- | arch/x86_64/src/kernel/main.cpp | 35 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/paging/page_table.cpp | 24 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/paging/temporary_page.cpp | 35 |
7 files changed, 156 insertions, 39 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index 496752f..8d64985 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -48,6 +48,7 @@ target_sources("_memory" PRIVATE "src/memory/allocator/physical_frame.cpp" "src/memory/paging/page_entry.cpp" "src/memory/paging/page_table.cpp" + "src/memory/paging/temporary_page.cpp" "src/memory/paging/virtual_page.cpp" "src/memory/paging/page_mapper.cpp" ) diff --git a/arch/x86_64/include/arch/memory/allocator/tiny_frame_allocator.hpp b/arch/x86_64/include/arch/memory/allocator/tiny_frame_allocator.hpp index a028e30..77d1b43 100644 --- a/arch/x86_64/include/arch/memory/allocator/tiny_frame_allocator.hpp +++ b/arch/x86_64/include/arch/memory/allocator/tiny_frame_allocator.hpp @@ -1,6 +1,7 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_TINY_FRAME_ALLOCATOR_HPP #define TEACHOS_ARCH_X86_64_MEMORY_ALLOCATOR_TINY_FRAME_ALLOCATOR_HPP +#include "arch/memory/allocator/area_frame_allocator.hpp" #include "arch/memory/allocator/concept.hpp" #include "arch/memory/allocator/physical_frame.hpp" @@ -16,10 +17,17 @@ namespace teachos::arch::memory::allocator /** * @brief Defaulted constructor. */ - template<FrameAllocator T> - tiny_frame_allocator(T & allocator) - : frames{allocator.allocate_frame(), allocator.allocate_frame(), allocator.allocate_frame()} + tiny_frame_allocator(area_frame_allocator & allocator) + : frames{} { + for (auto & frame : frames) + { + auto temp_frame = allocator.allocate_frame(); + if (temp_frame.has_value()) + { + frame.emplace(temp_frame.value()); + } + } // Nothing to do } diff --git a/arch/x86_64/include/arch/memory/paging/page_table.hpp b/arch/x86_64/include/arch/memory/paging/page_table.hpp index b9ea44b..9449ef2 100644 --- a/arch/x86_64/include/arch/memory/paging/page_table.hpp +++ b/arch/x86_64/include/arch/memory/paging/page_table.hpp @@ -41,10 +41,10 @@ namespace teachos::arch::memory::paging /** * @brief Constructor. * - * @param handle Underlying page table the handle should point to. - * @param handle_level Level the underlying page table is on, used to ensure safety. + * @param table Underlying page table the handle should point to. + * @param table_level Level the underlying page table is on, used to ensure safety. */ - page_table_handle(page_table * handle, level handle_level); + page_table_handle(page_table * table, level table_level); /** * @brief Set every entry of the page to unused. @@ -57,9 +57,9 @@ namespace teachos::arch::memory::paging auto is_empty() const -> bool; /** - * @brief Get the current handle level. + * @brief Get the current table level. * - * @return Current handle level. + * @return Current table level. */ auto get_level() const -> level; @@ -120,7 +120,7 @@ namespace teachos::arch::memory::paging auto operator[](std::size_t index) const -> entry const &; /** - * @brief Decrements the page table handle level enum by one, is defined so we can use it as a replacement for an + * @brief Decrements the page table level enum by one, is defined so we can use it as a replacement for an * int index in a range based for loop. * * @note Will halt execution if called with page_table_handle::LEVEL1, because there is no level below. Has to be @@ -137,9 +137,9 @@ namespace teachos::arch::memory::paging friend auto operator--(level & value) -> level &; private: - page_table * handle; ///< Handle to underlying page table, can never be null (invariant ensured by constructor) - level handle_level; ///< Level page table is currently on, depends on how often next_level was - ///< called successfully. + page_table * table; ///< Handle to underlying page table, can never be null (invariant ensured by constructor) + level table_level; ///< Level page table is currently on, depends on how often next_level was + ///< called successfully. }; } // namespace teachos::arch::memory::paging diff --git a/arch/x86_64/include/arch/memory/paging/temporary_page.hpp b/arch/x86_64/include/arch/memory/paging/temporary_page.hpp new file mode 100644 index 0000000..ae806c8 --- /dev/null +++ b/arch/x86_64/include/arch/memory/paging/temporary_page.hpp @@ -0,0 +1,68 @@ +#ifndef TEACHOS_ARCH_X86_64_MEMORY_PAGING_TEMPORARY_PAGE_HPP +#define TEACHOS_ARCH_X86_64_MEMORY_PAGING_TEMPORARY_PAGE_HPP + +#include "arch/memory/allocator/physical_frame.hpp" +#include "arch/memory/allocator/tiny_frame_allocator.hpp" +#include "arch/memory/paging/page_table.hpp" +#include "arch/memory/paging/virtual_page.hpp" + +namespace teachos::arch::memory::paging +{ + + /** + * @brief + * + */ + struct temporary_page + { + /** + * @brief Construct a new temporary page object + * + * @tparam T + * @param page + * @param allocator + */ + template<allocator::FrameAllocator T> + temporary_page(virtual_page page, T & allocator) + : page{page} + , allocator{allocator} + { + // Nothing to do + } + + /** + * @brief + * + * @param frame + */ + auto zero_entries() -> void; + + private: + /** + * @brief + * + * @param frame + * @return virtual_address + */ + auto map_to_frame(allocator::physical_frame frame) -> virtual_address; + + /** + * @brief + * + */ + auto unmap() -> void; + + /** + * @brief + * + * @param frame + * @return page_table_handle + */ + auto map_table_frame(allocator::physical_frame frame) -> page_table_handle; + + virtual_page page; + allocator::tiny_frame_allocator allocator; + }; +} // namespace teachos::arch::memory::paging + +#endif // TEACHOS_ARCH_X86_64_MEMORY_PAGING_TEMPORARY_PAGE_HPP
\ No newline at end of file diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 5c55213..a27631f 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -4,6 +4,7 @@ #include "arch/memory/allocator/area_frame_allocator.hpp" #include "arch/memory/multiboot/reader.hpp" #include "arch/memory/paging/page_mapper.hpp" +#include "arch/memory/paging/temporary_page.hpp" #include "arch/video/vga/text.hpp" #include <algorithm> @@ -22,22 +23,26 @@ namespace teachos::arch::kernel size_t address = 42 * memory::paging::PAGE_TABLE_ENTRY_COUNT * memory::paging::PAGE_TABLE_ENTRY_COUNT * memory::allocator::PAGE_FRAME_SIZE; // 42th P3 entry auto const page = memory::paging::virtual_page::containing_address(address); - memory::paging::map_next_free_page_to_frame(allocator, page, 0U); - auto optional_frame = memory::paging::translate_page(page); - video::vga::text::newline(); - video::vga::text::write("Mapped physical frame: ", video::vga::text::common_attributes::green_on_black); - video::vga::text::write_number(optional_frame.value().frame_number, - video::vga::text::common_attributes::green_on_black); - video::vga::text::write(" to virtual page: ", video::vga::text::common_attributes::green_on_black); - video::vga::text::write_number(page.page_number, video::vga::text::common_attributes::green_on_black); - memory::paging::unmap_page(allocator, page); - video::vga::text::newline(); - video::vga::text::write("Unapped virtual page from physical frame: ", - video::vga::text::common_attributes::green_on_black); - optional_frame = memory::paging::translate_page(page); - exception_handling::assert(!optional_frame.has_value(), "[Main] Ummapping failed"); - video::vga::text::write_number(page.page_number, video::vga::text::common_attributes::green_on_black); + memory::paging::temporary_page temp_page{page, allocator}; + temp_page.zero_entries(); + + // memory::paging::map_next_free_page_to_frame(allocator, page, 0U); + // auto optional_frame = memory::paging::translate_page(page); + // video::vga::text::newline(); + // video::vga::text::write("Mapped physical frame: ", video::vga::text::common_attributes::green_on_black); + // video::vga::text::write_number(optional_frame.value().frame_number, + // video::vga::text::common_attributes::green_on_black); + // video::vga::text::write(" to virtual page: ", video::vga::text::common_attributes::green_on_black); + // video::vga::text::write_number(page.page_number, video::vga::text::common_attributes::green_on_black); + + // memory::paging::unmap_page(allocator, page); + // video::vga::text::newline(); + // video::vga::text::write("Unapped virtual page from physical frame: ", + // video::vga::text::common_attributes::green_on_black); + // optional_frame = memory::paging::translate_page(page); + // exception_handling::assert(!optional_frame.has_value(), "[Main] Ummapping failed"); + // video::vga::text::write_number(page.page_number, video::vga::text::common_attributes::green_on_black); auto last_allocated = allocator.allocate_frame(); auto allocated = last_allocated; diff --git a/arch/x86_64/src/memory/paging/page_table.cpp b/arch/x86_64/src/memory/paging/page_table.cpp index 3ad1d54..3c9942a 100644 --- a/arch/x86_64/src/memory/paging/page_table.cpp +++ b/arch/x86_64/src/memory/paging/page_table.cpp @@ -88,33 +88,33 @@ namespace teachos::arch::memory::paging return std::nullopt; } - page_table_handle::page_table_handle(page_table * handle, page_table_handle::level handle_level) - : handle(handle) - , handle_level(handle_level) + page_table_handle::page_table_handle(page_table * table, page_table_handle::level table_level) + : table(table) + , table_level(table_level) { - exception_handling::assert(handle != nullptr, - "[Page Table] Attempted to pass nullptr as handle to page table handle method"); + exception_handling::assert(table != nullptr, + "[Page Table] Attempted to pass nullptr as table to page table table method"); } - auto page_table_handle::zero_entries() -> void { handle->zero_entries(); } + auto page_table_handle::zero_entries() -> void { table->zero_entries(); } - auto page_table_handle::is_empty() const -> bool { return handle->is_empty(); } + auto page_table_handle::is_empty() const -> bool { return table->is_empty(); } auto page_table_handle::next_table(std::size_t table_index) -> std::optional<page_table_handle> { - exception_handling::assert(handle_level != page_table_handle::LEVEL1, + exception_handling::assert(table_level != page_table_handle::LEVEL1, "[Page Table] Attempted to call next_table on level 1 page table"); - auto const next_table = handle->next_table(table_index); + auto const next_table = table->next_table(table_index); if (next_table.has_value()) { - return page_table_handle{next_table.value(), --handle_level}; + return page_table_handle{next_table.value(), --table_level}; } return std::nullopt; } - auto page_table_handle::get_level() const -> page_table_handle::level { return handle_level; } + auto page_table_handle::get_level() const -> page_table_handle::level { return table_level; } - auto page_table_handle::operator[](std::size_t index) -> entry & { return handle->operator[](index); } + auto page_table_handle::operator[](std::size_t index) -> entry & { return table->operator[](index); } auto operator--(page_table_handle::level & value) -> page_table_handle::level & { diff --git a/arch/x86_64/src/memory/paging/temporary_page.cpp b/arch/x86_64/src/memory/paging/temporary_page.cpp new file mode 100644 index 0000000..433f0ce --- /dev/null +++ b/arch/x86_64/src/memory/paging/temporary_page.cpp @@ -0,0 +1,35 @@ +#include "arch/memory/paging/temporary_page.hpp" + +#include "arch/memory/paging/page_entry.hpp" +#include "arch/memory/paging/page_mapper.hpp" + +namespace teachos::arch::memory::paging +{ + auto temporary_page::map_to_frame(allocator::physical_frame frame) -> virtual_address + { + exception_handling::assert(!translate_page(page).has_value(), "[Temporary page] Page is already mapped"); + + map_page_to_frame(allocator, page, frame, entry::WRITABLE); + return page.start_address(); + } + + auto temporary_page::unmap() -> void { unmap_page(allocator, page); } + + auto temporary_page::map_table_frame(allocator::physical_frame frame) -> page_table_handle + { + page_table_handle handle{reinterpret_cast<page_table *>(map_to_frame(frame)), page_table_handle::LEVEL1}; + return handle; + } + + auto temporary_page::zero_entries() -> void + { + auto frame = allocator.allocate_frame(); + exception_handling::assert(!frame.has_value(), "[Temporary Page] Tiny allocator could not allocate a frame"); + + page_table_handle handle = map_table_frame(frame.value()); + handle.zero_entries(); + handle[511].set_entry(frame.value(), entry::PRESENT | entry::WRITABLE); + + unmap(); + } +} // namespace teachos::arch::memory::paging
\ No newline at end of file |
