diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86_64/include/arch/memory/multiboot.hpp | 146 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/paging.hpp | 47 | ||||
| -rw-r--r-- | arch/x86_64/src/kernel/main.cpp | 34 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/multiboot.cpp | 36 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/paging.cpp | 7 |
5 files changed, 94 insertions, 176 deletions
diff --git a/arch/x86_64/include/arch/memory/multiboot.hpp b/arch/x86_64/include/arch/memory/multiboot.hpp index 93d214c..6fc10df 100644 --- a/arch/x86_64/include/arch/memory/multiboot.hpp +++ b/arch/x86_64/include/arch/memory/multiboot.hpp @@ -134,6 +134,35 @@ namespace teachos::arch::memory struct elf_section_flags { /** + * @brief Possible set bits in our underlying std::bitset and the meaning when they are set. + */ + enum bitset : uint32_t + { + WRITABLE = 1 << 0, ///< (SHF_WRITE) Section is writable at runtime. If it isn't then the section + ///< is assumed to be READONLY and only that flag is shown in the objdump. + OCCUPIES_MEMORY = 1 << 1, ///< (SHF_ALLOC) Section occupies memory during execution. + ///< ALLOC flag is shown in the objdump. + EXECUTABLE_CODE = 1 << 2, ///< (SHF_EXECINSTR) Section is executable. CODE flag is shown in the object dump. + DUPLICATE_DATA = 1 << 4, ///< (SHF_MERGE) Section might be merged with another section. + CONTAINS_STRING = 1 << 5, ///< (SHF_STRINGS) Section contains null-terminated strings. + SECTION_HEADER_INFO_IS_SECTION_HEADER_TABLE_INDEX = + 1 << 6, ///< (SHF_INFO_LINK) Section contains the section header table index in the (sh_info) + ///< additional_information variable. + PRESERVE_ORDERING_AFTER_COMBINATION = + 1 << 7, ///< (SHF_LINK_ORDER) Section preserves order after combining with another section. + REQUIRES_SPECIAL_OS_PROCESSING = + 1 << 8, ///< (SHF_OS_NONCONFORMING) Section requires non-standard OS specific handling of its code or + ///< data, which does not confirm to standard ELF specifications. + SECTION_GROUP_MEMBER = 1 << 9, ///< (SHF_GROUP) Section is a member of a section group. + HOLDS_THREAD_LOCAL_DATA = 1 << 10, ///< (SHF_TLS) Section holds thread-local data. + COMPRESSED = 1 << 11, ///< (SHF_COMPRESSED) Section contains compressed data. + SPECIAL_ORDERING_REQUIREMENTS = 1 << 30, ///< (SHF_ORDERED) Section has special ordering requirements, meaning it + ///< should be ordered in relation to other sections of the same type + EXCLUDED_UNLESS_REFERENCED_OR_ALLOCATED = 1 << 31, ///< (SHF_EXCLUDE)Section is excluded unless referenced or + ///< allocated, used for LTO (Link-Time Optimizations) + }; + + /** * @brief Constructor. * * @param flags Actual value read from the elf section header, which should be converted into a std::bitset, to @@ -146,109 +175,14 @@ namespace teachos::arch::memory } /** - * @brief (SHF_WRITE) Wether the current section is writable at runtime or not. If it isn't then the section is - * assumed to be READONLY and only that flag is shown in the objdump -h of the kernel file. Read from bit index - * 0. - * - * @return Current section is writable. - */ - auto writable() const -> bool; - - /** - * @brief (SHF_ALLOC) Whether the current section occupies memory during execution or not. ALLOC flag is shown in - * the objdump -h of the kernel file. Read from bit index 1. - * - * @return Current section occupies memory during execution. - */ - auto occupies_memory() const -> bool; - - /** - * @brief (SHF_EXECINSTR) Whether the current section is executable or not. CODE flag is shown in the object dump. - * Read from bit index 2. - * - * @return Current section is executable. - */ - auto is_executable() const -> bool; - - /** - * @brief (SHF_MERGE) Whether the current section might be merged with another section or not. Read from bit - * index 4. - * - * @return Current section might be merged with another section - */ - auto contains_duplicate_data() const -> bool; - - /** - * @brief (SHF_STRINGS) Whether the current section contains null-terminated strings or not. Read from bit - * index 5. - * - * @return Current section contains null-terminated strings - */ - auto contains_strings() const -> bool; - - /** - * @brief (SHF_INFO_LINK) Whether the current section contains the section header table index in the (sh_info) - * additional_information variable or not. Read from bit index 6. - * - * @return Current section contains the section header table index in the (sh_info) - * additional_information variable - */ - auto section_header_info_is_section_header_table_index() const -> bool; - - /** - * @brief (SHF_LINK_ORDER) Whether the current section preserves order after combining with another section or not. - * Read from bit index 7. + * @brief Checks if the given std::bitset is a subset or equivalent to the underlying std::bitset, meaning that all + * bits that are set in the given std::bitset also have to be set in the underlyng std::bitset. Any additional bits + * that are set are not relevant. * - * @return Current section preserves order after combining with another section + * @param flags Flags that we want to compare against and check if the underlying std::bitset has the same bits set. + * @return Whether the given flags are a subset or equivalent with the underlying std::bitset */ - auto preserve_ordering_after_combination() const -> bool; - - /** - * @brief (SHF_OS_NONCONFORMING) Whether the current section requires non-standard OS specific handling of its code - * or data, which does not confirm to standard ELF specifications. Read from bit index 8. - * - * @return Current section requires non-standard OS specific handling - */ - auto requires_special_os_processing() const -> bool; - - /** - * @brief (SHF_GROUP) Whether the current section is a member of a section group or not. Read from bit index 9. - * - * @return Current section is a member of a section group - */ - auto is_section_group_member() const -> bool; - - /** - * @brief (SHF_TLS) Whether the current section holds thread-local data or not. Read from bit - * index 10. - * - * @return Current section holds thread-local data - */ - auto holds_thread_local_data() const -> bool; - - /** - * @brief (SHF_COMPRESSED) Whether the current section contains compressed data or not. Read from bit - * index 11. - * - * @return Current section contains compressed data - */ - auto is_compressed() const -> bool; - - /** - * @brief (SHF_ORDERED) Whether the current section has special ordering requirements, meaning it should be ordered - * in relation to other sections of the same type. Read from bit index 30. - * - * @return current section has special ordering requirements - */ - auto has_special_ordering_requirements() const -> bool; - - /** - * @brief (SHF_EXCLUDE) Whether the current section is excluded unless refereenced or allocated, used for LTO - * (Link-Time Optimizations). Read from bit index 31. - * - * @return Current section is excluded unless refereenced or allocated - */ - auto is_excluded_unless_referenced_or_allocated() const -> bool; + auto contains_flags(std::bitset<64U> b) const -> bool; /** * @brief Allows to compare the underlying std::bitset of two instances @@ -256,17 +190,9 @@ namespace teachos::arch::memory * @param other Other instance that we want to compare with * @return Whether the underlying std::bitset of both types is the same */ - auto operator==(elf_section_flags const & other) const -> bool; + auto operator==(elf_section_flags const & other) const -> bool = default; private: - /** - * @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; }; diff --git a/arch/x86_64/include/arch/memory/paging.hpp b/arch/x86_64/include/arch/memory/paging.hpp index 43f13e0..aa20da7 100644 --- a/arch/x86_64/include/arch/memory/paging.hpp +++ b/arch/x86_64/include/arch/memory/paging.hpp @@ -31,6 +31,27 @@ namespace teachos::arch::memory struct entry { /** + * @brief Possible set bits in our underlying std::bitset and the meaning when they are set. + */ + enum bitset : uint64_t + { + PRESENT = 1 << 0, ///< Page is in memory and therefore present. + ///< is assumed to be READONLY and only that flag is shown in the objdump. + WRITABLE = 1 << 1, ///< It is possible to write to the page. + USER_ACCESIBLE = 1 << 2, ///< Page can be accessed in user mode instead of only in kernel mode code. + WRITE_THROUGH_CACHING = 1 << 3, ///< Write to the page go directly to memory instead of the cache. + DISABLED_CACHING = 1 << 4, ///< Page uses caching. + ACCESSED = 1 << 5, ///< Page is currently in use. + DIRTY = 1 << 6, ///< Page has been writen too. + HUGE_PAGE = 1 << 7, ///< Page is huge (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. + GLOBAL = 1 << 8, ///< Page is not flushed from caches on address space switches (PGE bit of CR4 register + ///< has to be set) + EXECUTING_CODE_FORBIDDEN = + 1 << 63, ///< Page is forbidden from executing code (NXE bit in the EFER register has to be set) + }; + + /** * @brief Whether the current page is unused, meaning the underlying std::bitset is 0. * * @return Current page is in memory. @@ -43,14 +64,6 @@ namespace teachos::arch::memory auto set_unused() -> void; /** - * @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. - * - * @return Current page is forbidden from executing code. - */ - auto executing_code_forbidden() const -> bool; - - /** * @brief Calculates the physical frame this entry is pointing too, can be null if the page is not present in * memory. * @@ -59,18 +72,20 @@ namespace teachos::arch::memory auto calculate_pointed_to_frame() const -> std::optional<physical_frame>; /** - * @brief TODO + * @brief Copies the address from the given physical frame into the underlying std::bitset so future calls to + * calculate_physical_address() will return the new address instead of the old one. * - * @param frame + * @param frame Physical frame that contains the address we want to copy into our underlying std::bitset. */ - auto set(physical_frame frame) -> void; + auto set_address(physical_frame frame) -> void; /** - * @brief TODO + * @brief Checks if the given std::bitset is a subset or equivalent to the underlying std::bitset, meaning that all + * bits that are set in the given std::bitset also have to be set in the underlyng std::bitset. Any additional bits + * that are set are not relevant. * - * @param b - * @return true - * @return false + * @param flags Flags that we want to compare against and check if the underlying std::bitset has the same bits set. + * @return Whether the given flags are a subset or equivalent with the underlying std::bitset */ auto contains_flags(std::bitset<64U> b) const -> bool; @@ -85,7 +100,7 @@ namespace teachos::arch::memory auto calculate_physical_address() const -> std::size_t; 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. + ///< used for additional flags by the operating system. }; /** diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index c8981a8..12498d0 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -48,21 +48,27 @@ namespace teachos::arch::kernel for (auto section = begin; section != end; ++section) { - bool const writable = section->flags.writable(); - bool const occupies_memory = section->flags.occupies_memory(); - bool const is_executable = section->flags.is_executable(); - bool const contains_duplicate_data = section->flags.contains_duplicate_data(); - bool const contains_strings = section->flags.contains_strings(); - bool const section_header_info_is_section_header_table_index = - section->flags.section_header_info_is_section_header_table_index(); - bool const preserve_ordering_after_combination = section->flags.preserve_ordering_after_combination(); - bool const requires_special_os_processing = section->flags.requires_special_os_processing(); - bool const is_section_group_member = section->flags.is_section_group_member(); - bool const holds_thread_local_data = section->flags.holds_thread_local_data(); - bool const is_compressed = section->flags.is_compressed(); - bool const has_special_ordering_requirements = section->flags.has_special_ordering_requirements(); + bool const writable = section->flags.contains_flags(arch::memory::elf_section_flags::WRITABLE); + bool const occupies_memory = section->flags.contains_flags(arch::memory::elf_section_flags::OCCUPIES_MEMORY); + bool const is_executable = section->flags.contains_flags(arch::memory::elf_section_flags::EXECUTABLE_CODE); + bool const contains_duplicate_data = + section->flags.contains_flags(arch::memory::elf_section_flags::DUPLICATE_DATA); + bool const contains_strings = section->flags.contains_flags(arch::memory::elf_section_flags::CONTAINS_STRING); + bool const section_header_info_is_section_header_table_index = section->flags.contains_flags( + arch::memory::elf_section_flags::SECTION_HEADER_INFO_IS_SECTION_HEADER_TABLE_INDEX); + bool const preserve_ordering_after_combination = + section->flags.contains_flags(arch::memory::elf_section_flags::PRESERVE_ORDERING_AFTER_COMBINATION); + bool const requires_special_os_processing = + section->flags.contains_flags(arch::memory::elf_section_flags::REQUIRES_SPECIAL_OS_PROCESSING); + bool const is_section_group_member = + section->flags.contains_flags(arch::memory::elf_section_flags::SECTION_GROUP_MEMBER); + bool const holds_thread_local_data = + section->flags.contains_flags(arch::memory::elf_section_flags::HOLDS_THREAD_LOCAL_DATA); + bool const is_compressed = section->flags.contains_flags(arch::memory::elf_section_flags::COMPRESSED); + bool const has_special_ordering_requirements = + section->flags.contains_flags(arch::memory::elf_section_flags::SPECIAL_ORDERING_REQUIREMENTS); bool const is_excluded_unless_referenced_or_allocated = - section->flags.is_excluded_unless_referenced_or_allocated(); + section->flags.contains_flags(arch::memory::elf_section_flags::EXCLUDED_UNLESS_REFERENCED_OR_ALLOCATED); if (writable && occupies_memory && is_executable && contains_duplicate_data && contains_strings && section_header_info_is_section_header_table_index && preserve_ordering_after_combination && diff --git a/arch/x86_64/src/memory/multiboot.cpp b/arch/x86_64/src/memory/multiboot.cpp index bd3b00b..b0432a9 100644 --- a/arch/x86_64/src/memory/multiboot.cpp +++ b/arch/x86_64/src/memory/multiboot.cpp @@ -2,40 +2,12 @@ namespace teachos::arch::memory { - auto elf_section_flags::writable() const -> bool { return is_bit_set(0U); } - - auto elf_section_flags::occupies_memory() const -> bool { return is_bit_set(1U); } - - auto elf_section_flags::is_executable() const -> bool { return is_bit_set(2U); } - - auto elf_section_flags::contains_duplicate_data() const -> bool { return is_bit_set(4U); } - - auto elf_section_flags::contains_strings() const -> bool { return is_bit_set(5U); } - - auto elf_section_flags::section_header_info_is_section_header_table_index() const -> bool { return is_bit_set(6U); } - - auto elf_section_flags::preserve_ordering_after_combination() const -> bool { return is_bit_set(7U); } - - auto elf_section_flags::requires_special_os_processing() const -> bool { return is_bit_set(8U); } - - auto elf_section_flags::is_section_group_member() const -> bool { return is_bit_set(9U); } - - auto elf_section_flags::holds_thread_local_data() const -> bool { return is_bit_set(10U); } - - auto elf_section_flags::is_compressed() const -> bool { return is_bit_set(11U); } - - auto elf_section_flags::has_special_ordering_requirements() const -> bool { return is_bit_set(30U); } - - auto elf_section_flags::is_excluded_unless_referenced_or_allocated() const -> bool { return is_bit_set(31U); } - - auto elf_section_flags::operator==(elf_section_flags const & other) const -> bool { return flags == other.flags; } - - auto elf_section_flags::is_bit_set(uint8_t index) const -> bool { return flags[index] == 1U; } + auto elf_section_flags::contains_flags(std::bitset<64U> b) const -> bool { return (flags & b) == b; } auto elf_section_header::is_null() const -> bool { - return name_table_index == 0U && type == elf_section_type::INACTIVE && - flags == teachos::arch::memory::elf_section_flags{0U} && virtual_address == 0U && file_offset == 0U && - additional_information == 0U && address_alignment == 0U && fixed_table_entry_size == 0U; + return name_table_index == 0U && type == elf_section_type::INACTIVE && flags == elf_section_flags(0U) && + virtual_address == 0U && file_offset == 0U && additional_information == 0U && address_alignment == 0U && + fixed_table_entry_size == 0U; } } // namespace teachos::arch::memory diff --git a/arch/x86_64/src/memory/paging.cpp b/arch/x86_64/src/memory/paging.cpp index 58a2b99..6fef339 100644 --- a/arch/x86_64/src/memory/paging.cpp +++ b/arch/x86_64/src/memory/paging.cpp @@ -31,15 +31,15 @@ namespace teachos::arch::memory return value; } - auto entry::set(physical_frame frame) -> void + auto entry::contains_flags(std::bitset<64U> b) const -> bool { return (flags & b) == b; } + + auto entry::set_address(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; } - auto page_table::zero_entries() -> void { auto begin = &entries[0]; @@ -50,5 +50,4 @@ namespace teachos::arch::memory entry->set_unused(); } } - } // namespace teachos::arch::memory |
