aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/include/arch/memory/multiboot.hpp146
-rw-r--r--arch/x86_64/include/arch/memory/paging.hpp47
-rw-r--r--arch/x86_64/src/kernel/main.cpp34
-rw-r--r--arch/x86_64/src/memory/multiboot.cpp36
-rw-r--r--arch/x86_64/src/memory/paging.cpp7
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