diff options
| author | Fabian Imhof <fabian.imhof@ost.ch> | 2024-10-15 08:23:39 +0000 |
|---|---|---|
| committer | Fabian Imhof <fabian.imhof@ost.ch> | 2024-10-15 08:23:39 +0000 |
| commit | 205934ca45d591924b4be6e7ae5a8849958e0cf6 (patch) | |
| tree | 5f0b193fa9620a253690f494405e5d407d97ca56 | |
| parent | 38e0b13ab9a4997fdf9f311fd125825919d2e6c7 (diff) | |
| download | teachos-205934ca45d591924b4be6e7ae5a8849958e0cf6.tar.xz teachos-205934ca45d591924b4be6e7ae5a8849958e0cf6.zip | |
continue implementing paging
| -rw-r--r-- | CMakeLists.txt | 10 | ||||
| -rw-r--r-- | arch/x86_64/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/exception_handling/assert.hpp | 11 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/frame_allocator.hpp | 7 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/paging.hpp | 99 | ||||
| -rw-r--r-- | arch/x86_64/src/exception_handling/assert.cpp | 24 | ||||
| -rw-r--r-- | arch/x86_64/src/kernel/main.cpp | 42 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/frame_allocator.cpp | 12 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/paging.cpp | 36 |
9 files changed, 113 insertions, 136 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f5cc7ea..3586669 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,13 +101,20 @@ add_library("_video" OBJECT) add_library("teachos::video" ALIAS "_video") #[============================================================================[ -# The memory Library +# THE Memory Library #]============================================================================] add_library("_memory" OBJECT) add_library("teachos::memory" ALIAS "_memory") #[============================================================================[ +# The Exception handling Library +#]============================================================================] + +add_library("_exception" OBJECT) +add_library("teachos::exception" ALIAS "_exception") + +#[============================================================================[ # The Kernel #]============================================================================] @@ -120,6 +127,7 @@ target_link_libraries("_kernel" PRIVATE "teachos::boot" "teachos::video" "teachos::memory" + "teachos::exception" ) #[============================================================================[ diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index 25f8634..603393c 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -47,6 +47,14 @@ target_sources("_memory" PRIVATE ) #[============================================================================[ +# The Exception handling Library +#]============================================================================] + +target_sources("_exception" PRIVATE + "src/exception_handling/assert.cpp" +) + +#[============================================================================[ # The Bootable ISO Image #]============================================================================] diff --git a/arch/x86_64/include/arch/exception_handling/assert.hpp b/arch/x86_64/include/arch/exception_handling/assert.hpp new file mode 100644 index 0000000..eba43ac --- /dev/null +++ b/arch/x86_64/include/arch/exception_handling/assert.hpp @@ -0,0 +1,11 @@ +namespace teachos::arch::exception_handling +{ + /** + * @brief assert a condition to be true, if not do not continue + * execution of the code and print message to screen + * + * @param condition + * @param message + */ + auto assert(bool condition, char const * message) -> void; +} // namespace teachos::arch::exception_handling
\ No newline at end of file diff --git a/arch/x86_64/include/arch/memory/frame_allocator.hpp b/arch/x86_64/include/arch/memory/frame_allocator.hpp index ab93231..69c108c 100644 --- a/arch/x86_64/include/arch/memory/frame_allocator.hpp +++ b/arch/x86_64/include/arch/memory/frame_allocator.hpp @@ -32,6 +32,13 @@ namespace teachos::arch::memory static auto containing_address(std::size_t address) -> physical_frame; /** + * @brief TODO + * + * @return uint64_t + */ + auto start_address() const -> uint64_t; + + /** * @brief Defaulted equals operator. */ constexpr auto operator==(const physical_frame & other) const -> bool = default; diff --git a/arch/x86_64/include/arch/memory/paging.hpp b/arch/x86_64/include/arch/memory/paging.hpp index a5408e1..1870c28 100644 --- a/arch/x86_64/include/arch/memory/paging.hpp +++ b/arch/x86_64/include/arch/memory/paging.hpp @@ -43,72 +43,6 @@ namespace teachos::arch::memory auto set_unused() -> void; /** - * @brief Whether the current page is in memory and therefore present or not. Read from bit index 0. - * - * @return Current page is in memory. - */ - auto present() const -> bool; - - /** - * @brief Whether it is possible to write to the current page or not. Read from bit index 1. - * - * @return Current page can be written too. - */ - auto writable() const -> bool; - - /** - * @brief Whether the current page can be accessed in user mode, or only in kernel mode code. Read from bit index 2. - * - * @return Current page can be accessed in user mode. - */ - auto user_accessible() const -> bool; - - /** - * @brief Whether any write to the current page go directly to memory instead of the cache or not. Read from bit - * index 3. - * - * @return Writes to the current page go directly to memory. - */ - auto write_through_caching() const -> bool; - - /** - * @brief Whether the current page uses caching or not. Read from bit index 4. - * - * @return Current page does not use caching. - */ - auto disabled_caching() const -> bool; - - /** - * @brief Whether the current page is currently being used or not. Read from bit index 5. - * - * @return Current page is currently being used. - */ - auto is_accessing() const -> bool; - - /** - * @brief Whether the current page has been writen too or not. Read from bit index 6. - * - * @return Current page has been writen too. - */ - auto is_diry() const -> bool; - - /** - * @brief Whether the current page is huge or not (2 MiB page size in P2 page table and 1 GiB in P3 page table, - * instead of 4 KiB). Has to be false for P1 and P4 page tables. Read from bit index 7. - * - * @return Current page is huge - */ - auto is_huge_page() const -> bool; - - /** - * @brief Whether the current page is not flushed from caches on address space switches or not (PGE bit of CR4 - * register has to be set). Read from bit index 8. - * - * @return Current page is not flushed from caches on address space switches. - */ - auto is_global() const -> bool; - - /** * @brief Whether the current page is forbidden from executing code or not (NXE bit in the EFER register has to be * set). Read from bit index 63. * @@ -124,6 +58,22 @@ namespace teachos::arch::memory */ auto calculate_pointed_to_frame() const -> std::optional<physical_frame>; + /** + * @brief TODO + * + * @param frame + */ + auto set(physical_frame frame) -> void; + + /** + * @brief TODO + * + * @param b + * @return true + * @return false + */ + auto contains_flags(std::bitset<64U> b) const -> bool; + private: /** * @brief Extracts the physical address from the underlying bitset read from bit index 12 - 51. Is a 52 bit page @@ -134,17 +84,18 @@ namespace teachos::arch::memory */ auto calculate_physical_address() const -> std::size_t; - /** - * @brief Checks the underlying std::bitset if the bit at the specific index is set, meaning a value of 1 - * - * @param index Specific index we want to check at - * @return Bit value 1 is set and will return true - */ - auto is_bit_set(uint8_t index) const -> bool; - std::bitset<64U> flags; ///< Underlying bitset used to read the flags from. Bits 9 - 11 and 52 - 62 can be freely ///< used for additional flagsby the operating system. }; + + /** + * @brief TODO + * + */ + struct page_table + { + entry entries[PAGE_TABLE_ENTRY_COUNT]; + }; } // namespace teachos::arch::memory #endif // TEACHOS_ARCH_X86_64_MEMORY_PAGING_HPP diff --git a/arch/x86_64/src/exception_handling/assert.cpp b/arch/x86_64/src/exception_handling/assert.cpp new file mode 100644 index 0000000..b55da49 --- /dev/null +++ b/arch/x86_64/src/exception_handling/assert.cpp @@ -0,0 +1,24 @@ +#include "arch/video/vga/text.hpp" + +namespace teachos::arch::exception_handling +{ + auto assert(bool condition, char const * message) -> void + { + if (condition) + { + return; + } + + video::vga::text::write("Assert failed: ", video::vga::text::common_attributes::green_on_black); + video::vga::text::write(message, video::vga::text::common_attributes::green_on_black); + for (;;) + { + // Trick the compiler into thinking the variable is changes at run time, + // to prevent the while loop being optimized away + // See + // https://stackoverflow.com/questions/9495856/how-to-prevent-g-from-optimizing-out-a-loop-controlled-by-a-variable-that-can + // for more information. + asm volatile("" : "+g"(condition)); + } + } +} // namespace teachos::arch::exception_handling
\ 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 7e4a336..c8981a8 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,6 +1,7 @@ #include "arch/kernel/main.hpp" #include "arch/boot/pointers.hpp" +#include "arch/exception_handling/assert.hpp" #include "arch/memory/frame_allocator.hpp" #include "arch/memory/multiboot.hpp" #include "arch/video/vga/text.hpp" @@ -9,31 +10,12 @@ namespace teachos::arch::kernel { - auto assert(bool condition) -> void - { - if (condition) - { - return; - } - - video::vga::text::write("Assert failed", video::vga::text::common_attributes::green_on_black); - for (;;) - { - // Trick the compiler into thinking the variable is changes at run time, - // to prevent the while loop being optimized away - // See - // https://stackoverflow.com/questions/9495856/how-to-prevent-g-from-optimizing-out-a-loop-controlled-by-a-variable-that-can - // for more information. - asm volatile("" : "+g"(condition)); - } - } - auto process_memory_map(arch::memory::memory_map * mminfo, arch::memory::memory_area *& memory_areas, uint8_t & area_count) -> void { auto expected_entry_size = mminfo->entry_size; constexpr auto actual_entry_size = sizeof(arch::memory::memory_area); - assert(expected_entry_size == actual_entry_size); + arch::exception_handling::assert(expected_entry_size == actual_entry_size, "Unexpected memoryarea entry size"); auto total_size = mminfo->tag.size; auto total_entries_size = total_size - sizeof(arch::memory::memory_map) + actual_entry_size; @@ -48,17 +30,18 @@ namespace teachos::arch::kernel { auto expected_entry_size = symbol->entry_size; constexpr auto actual_entry_size = sizeof(arch::memory::elf_section_header); - assert(expected_entry_size == actual_entry_size); + arch::exception_handling::assert(expected_entry_size == actual_entry_size, + "Unexpected elf_section_header entry size"); auto expected_total_size = symbol->tag.size; auto actual_total_entry_size = actual_entry_size * symbol->number_of_sections; constexpr auto actual_total_section_size = sizeof(arch::memory::elf_symbols_section) - sizeof(uint32_t); auto actual_total_size = actual_total_entry_size + actual_total_section_size; - assert(expected_total_size == actual_total_size); + arch::exception_handling::assert(expected_total_size == actual_total_size, "Unexpected elf_symbols total size"); auto begin = reinterpret_cast<arch::memory::elf_section_header *>(&symbol->end); auto end = begin + symbol->number_of_sections; - assert(begin->is_null()); + arch::exception_handling::assert(begin->is_null(), "Missing elf_section_header begin"); std::size_t symbol_table_section_count = 0U; std::size_t dynamic_section_count = 0U; @@ -115,8 +98,8 @@ namespace teachos::arch::kernel } } - assert(symbol_table_section_count == 1U); - assert(dynamic_section_count <= 1U); + arch::exception_handling::assert(symbol_table_section_count == 1U, "Unexpected symbol_table_count value"); + arch::exception_handling::assert(dynamic_section_count <= 1U, "Unexpected dynamic_section_count value"); } template<typename T> @@ -173,15 +156,6 @@ namespace teachos::arch::kernel } } - // Kernel start 0x100000 - // Kernel end 0x23E943 - // Kernel Size 0x13E943 -> 1'304'899 - // Multiboot start 0x241AA0 - // Multiboot end 0x242280 - // Multiboot Size 0x7E0 -> 2'016 - // Memory area start 0x241b10 - // - // Address of Frame: 0x203F00 auto allocator = arch::memory::area_frame_allocator(kernel_start, kernel_end, multiboot_start, multiboot_end, memory_areas, area_count); diff --git a/arch/x86_64/src/memory/frame_allocator.cpp b/arch/x86_64/src/memory/frame_allocator.cpp index 3733cc3..01dcc88 100644 --- a/arch/x86_64/src/memory/frame_allocator.cpp +++ b/arch/x86_64/src/memory/frame_allocator.cpp @@ -1,7 +1,11 @@ #include "arch/memory/frame_allocator.hpp" +#include "arch/exception_handling/assert.hpp" + namespace teachos::arch::memory { + uint64_t PAGE_SIZE; + physical_frame::physical_frame(std::size_t frame_number) : frame_number(frame_number) { @@ -13,6 +17,8 @@ namespace teachos::arch::memory return physical_frame{address / PAGE_FRAME_SIZE}; } + auto physical_frame::start_address() const -> uint64_t { return frame_number * PAGE_SIZE; } + memory_area_iterator::memory_area_iterator(memory_area * p) : ptr(p) { @@ -103,10 +109,8 @@ namespace teachos::arch::memory auto area_frame_allocator::deallocate_frame(physical_frame physical_frame) -> void { - // TODO: Fix, simply done because compiler will complain if physical_frame is unused and not compile - if (physical_frame.frame_number == 3) - { - } + arch::exception_handling::assert(false && physical_frame.frame_number == 0, + "[deallocate_frame] Not implemented Exception"); } auto area_frame_allocator::begin() -> memory_area_iterator { return area_begin; } diff --git a/arch/x86_64/src/memory/paging.cpp b/arch/x86_64/src/memory/paging.cpp index 555357c..90c4199 100644 --- a/arch/x86_64/src/memory/paging.cpp +++ b/arch/x86_64/src/memory/paging.cpp @@ -1,34 +1,16 @@ #include "arch/memory/paging.hpp" +#include "arch/exception_handling/assert.hpp" + namespace teachos::arch::memory { auto entry::is_unused() const -> bool { return flags == 0U; } auto entry::set_unused() -> void { flags = 0U; } - auto entry::present() const -> bool { return is_bit_set(0U); } - - auto entry::writable() const -> bool { return is_bit_set(1U); } - - auto entry::user_accessible() const -> bool { return is_bit_set(2U); } - - auto entry::write_through_caching() const -> bool { return is_bit_set(3U); } - - auto entry::disabled_caching() const -> bool { return is_bit_set(4U); } - - auto entry::is_accessing() const -> bool { return is_bit_set(5U); } - - auto entry::is_diry() const -> bool { return is_bit_set(6U); } - - auto entry::is_huge_page() const -> bool { return is_bit_set(7U); } - - auto entry::is_global() const -> bool { return is_bit_set(8U); } - - auto entry::executing_code_forbidden() const -> bool { return is_bit_set(63U); } - auto entry::calculate_pointed_to_frame() const -> std::optional<physical_frame> { - if (present()) + if (contains_flags(1)) { auto physical_address = calculate_physical_address(); return physical_frame::containing_address(physical_address); @@ -39,7 +21,7 @@ namespace teachos::arch::memory auto entry::calculate_physical_address() const -> std::size_t { constexpr std::size_t start_bit = 12U; - constexpr std::size_t end_bit = 51U; + constexpr std::size_t end_bit = 52U; size_t value = 0U; for (auto i = start_bit; i < end_bit; i++) @@ -49,5 +31,13 @@ namespace teachos::arch::memory return value; } - auto entry::is_bit_set(uint8_t index) const -> bool { return flags[index] == 1U; } + auto entry::set(physical_frame frame) -> void + { + arch::exception_handling::assert((frame.start_address() & ~0x000fffff'fffff000) == 0, + "Start address is not aligned with Page"); + flags = std::bitset<64U>(frame.start_address()) | flags; + } + + auto entry::contains_flags(std::bitset<64U> b) const -> bool { return (flags & b) == b; } + } // namespace teachos::arch::memory |
