aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMatteo Gmür <matteo.gmuer1@ost.ch>2024-10-28 10:15:18 +0000
committerMatteo Gmür <matteo.gmuer1@ost.ch>2024-10-28 10:15:18 +0000
commit04b0285d8329e45cea426aa1a8e69203685a4467 (patch)
tree00c55d9dffddf3724da38b07427cf3460f883b1e /arch
parent58d01f6aae80a66faa5163602c399c28dcf30cb6 (diff)
downloadteachos-04b0285d8329e45cea426aa1a8e69203685a4467.tar.xz
teachos-04b0285d8329e45cea426aa1a8e69203685a4467.zip
Move iterator and container into generic template classes. Use algorithms instead of raw pointer for loops
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/CMakeLists.txt1
-rw-r--r--arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp7
-rw-r--r--arch/x86_64/include/arch/memory/multiboot/memory_map.hpp178
-rw-r--r--arch/x86_64/include/arch/memory/multiboot/reader.hpp9
-rw-r--r--arch/x86_64/include/arch/shared/container.hpp73
-rw-r--r--arch/x86_64/include/arch/shared/random_access_iterator.hpp167
-rw-r--r--arch/x86_64/src/memory/allocator/area_frame_allocator.cpp4
-rw-r--r--arch/x86_64/src/memory/multiboot/memory_map.cpp73
-rw-r--r--arch/x86_64/src/memory/multiboot/reader.cpp79
9 files changed, 300 insertions, 291 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt
index 8658ed7..e1b7352 100644
--- a/arch/x86_64/CMakeLists.txt
+++ b/arch/x86_64/CMakeLists.txt
@@ -42,7 +42,6 @@ target_sources("_video" PRIVATE
target_sources("_memory" PRIVATE
"src/memory/multiboot/elf_symbols_section.cpp"
- "src/memory/multiboot/memory_map.cpp"
"src/memory/multiboot/reader.cpp"
"src/memory/allocator/area_frame_allocator.cpp"
"src/memory/allocator/physical_frame.cpp"
diff --git a/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp b/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp
index fc8cb15..c9989ae 100644
--- a/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp
+++ b/arch/x86_64/include/arch/memory/multiboot/elf_symbols_section.hpp
@@ -1,7 +1,10 @@
#ifndef TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP
#define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP
-#include "info.hpp"
+#include "arch/memory/multiboot/info.hpp"
+#include "arch/shared/container.hpp"
+#include "arch/shared/random_access_iterator.hpp"
+
#include <bitset>
#include <cstdint>
@@ -158,6 +161,8 @@ namespace teachos::arch::memory::multiboot
std::byte end; ///< Marks the end of the tag, used to mark the beginning of any additional data.
///< contained in the section, to ensure byte alignment is actually 4 byte.
};
+
+ typedef shared::container<shared::random_access_iterator<elf_section_header>> elf_section_header_container;
} // namespace teachos::arch::memory::multiboot
#endif // TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_ELF_SYBOLS_SECTION_HPP
diff --git a/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp b/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp
index f9c902a..910eecb 100644
--- a/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp
+++ b/arch/x86_64/include/arch/memory/multiboot/memory_map.hpp
@@ -1,9 +1,11 @@
#ifndef TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_MEMORY_MAP_HPP
#define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_MEMORY_MAP_HPP
-#include "info.hpp"
+#include "arch/memory/multiboot/info.hpp"
+#include "arch/shared/container.hpp"
+#include "arch/shared/random_access_iterator.hpp"
+
#include <cstdint>
-#include <iterator>
namespace teachos::arch::memory::multiboot
{
@@ -44,177 +46,7 @@ namespace teachos::arch::memory::multiboot
struct memory_area entries; ///< Specific memory regions.
};
- /**
- * @brief Random access iterator for memory areas.
- */
- struct memory_area_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 = memory_area; ///< Underlying value pointed to by this iterator.
-
- /**
- * @brief Defaulted constructor.
- */
- memory_area_iterator() = default;
-
- /**
- * @brief Constructor.
- *
- * @param p Underlying address the iterator should point too, ensure to not pass an invalid pointer or the
- * constructor will halt execution.
- */
- explicit memory_area_iterator(value_type * p);
-
- /**
- * @brief Dereferences the initally given pointer to its value.
- *
- * @return Reference to the value.
- */
- auto operator*() const -> value_type &;
-
- /**
- * @brief Get underlying value, which is the intially passed pointer.
- *
- * @return Underlying value passed intially.
- */
- auto operator->() const -> value_type *;
-
- /**
- * @brief Post increment operator. Returns a copy of the value.
- *
- * @return Copy of the incremented underlying address.
- */
- auto operator++(int) -> memory_area_iterator;
-
- /**
- * @brief Pre increment operator. Returns a reference to the changed value.
- *
- * @return Reference to the incremented underlying address.
- */
- auto operator++() -> memory_area_iterator &;
-
- /**
- * @brief Addition assignment operator. Returns a reference to the changed value.
- *
- * @param value Value we want to add to the underlying address.
- * @return Reference to the changed underlying address.
- */
- auto operator+=(difference_type value) -> memory_area_iterator &;
-
- /**
- * @brief Subtraction assignment operator. Returns a reference to the changed value.
- *
- * @param value Value we want to subtract from the underlying address.
- * @return Reference to the changed underlying address.
- */
- auto operator-=(difference_type value) -> memory_area_iterator &;
-
- /**
- * @brief Addition operator. Returns the changed value.
- *
- * @param value 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 value) const -> memory_area_iterator;
-
- /**
- * @brief Subtraction operator. Returns the changed value.
- *
- * @param value 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 value) const -> memory_area_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 memory_area_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==(memory_area_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<=>(memory_area_iterator const & other) const -> std::strong_ordering = default;
-
- private:
- value_type * ptr; ///< Underlying address the iterator is currently pointing too.
- };
-
- /**
- * @brief Read-only container for memory areas, that allow to easily use the memory_area_iterator in C++20 ranges
- * calls.
- */
- struct memory_area_container
- {
- using iterator = memory_area_iterator; ///< Iterators used by this container.
- using size_type = std::size_t; ///< Maximum size of this container.
-
- /**
- * @brief Constructor.
- *
- * @param begin Pointer to the first memory area, will be used to construct the begin iterator.
- * @param size Amount of entries in the container we want to construct.
- */
- memory_area_container(memory_area_iterator::value_type * begin, size_type size);
-
- /**
- * @brief Returns the iterator pointing to the first element of the memory area.
- * Allows using this class in the for each loop, because it follows the InputIterator template scheme.
- *
- * @return Iterator pointing to first element of the memory area.
- */
- auto begin() const -> iterator;
-
- /**
- * @brief Returns the iterator pointing to one past the last element of the memory area.
- * Allows using this class in the for each loop, because it follows the InputIterator template scheme.
- *
- * @return Iterator pointing to one past the last element of the memory area.
- */
- auto end() const -> iterator;
-
- /**
- * @brief Calculates the size of this container, simply subtracts the iterator pointing to the first element by the
- * last.
- *
- * @return Actual size of this container.
- */
- auto size() const -> size_type;
-
- /**
- * @brief Calcualtes the size and returns true if the size is 0 and the container therefore emtpy.
- *
- * @return Whether the container is empty, size being 0 or not
- */
- auto empty() const -> bool;
-
- private:
- iterator area_begin; ///< Pointer to the first element of all memory areas.
- iterator area_end; ///< Pointer to one pas the last element of all memory areas.
- };
+ typedef shared::container<shared::random_access_iterator<memory_area>> memory_area_container;
} // namespace teachos::arch::memory::multiboot
#endif // TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_MEMORY_MAP_HPP
diff --git a/arch/x86_64/include/arch/memory/multiboot/reader.hpp b/arch/x86_64/include/arch/memory/multiboot/reader.hpp
index 393db8b..baa49c9 100644
--- a/arch/x86_64/include/arch/memory/multiboot/reader.hpp
+++ b/arch/x86_64/include/arch/memory/multiboot/reader.hpp
@@ -1,8 +1,8 @@
#ifndef TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_READER_HPP
#define TEACHOS_ARCH_X86_64_MEMORY_MULTIBOOT_READER_HPP
-#include "elf_symbols_section.hpp"
-#include "memory_map.hpp"
+#include "arch/memory/multiboot/memory_map.hpp"
+
#include <cstdint>
namespace teachos::arch::memory::multiboot
@@ -17,8 +17,9 @@ namespace teachos::arch::memory::multiboot
std::size_t kernel_end; ///< End address of the kernel code in memory.
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 * memory_areas; ///< Non-owning pointer to the first element of all memory areas.
- uint8_t area_count; ///< Amount of total entries in the memory_areas array.
+ memory_area_container::iterator
+ begin_area; ///< Iterator containing non-owning pointer to the first element of all memory areas.
+ memory_area_container::iterator end_area; ///< Iterator pointing to one past the last element of all memory areas.
};
/**
diff --git a/arch/x86_64/include/arch/shared/container.hpp b/arch/x86_64/include/arch/shared/container.hpp
new file mode 100644
index 0000000..8ea0d08
--- /dev/null
+++ b/arch/x86_64/include/arch/shared/container.hpp
@@ -0,0 +1,73 @@
+#ifndef TEACHOS_ARCH_X86_64_SHARED_CONTAINER_HPP
+#define TEACHOS_ARCH_X86_64_SHARED_CONTAINER_HPP
+
+#include "arch/exception_handling/assert.hpp"
+
+#include <iterator>
+
+namespace teachos::arch::shared
+{
+ /**
+ * @brief Read-only container for given template type, that allow to easily use this container instance in C++20
+ * ranges calls.
+ *
+ * @tparam T Iterator the container uses to signal the start and end of it's data.
+ */
+ template<typename T>
+ struct container
+ {
+ using iterator = T; ///< Iterators used by this container.
+ using size_type = std::size_t; ///< Maximum size of this container.
+
+ /**
+ * @brief Constructor.
+ *
+ * @param begin Iterator containing non-owning pointer to the first element of all memory areas.
+ * @param end Iterator pointing to one past the last element of all memory areas.
+ */
+ container(iterator begin, iterator end)
+ : 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");
+ }
+
+ /**
+ * @brief Returns the iterator pointing to the first element of the memory area.
+ * Allows using this class in the for each loop, because it follows the InputIterator template scheme.
+ *
+ * @return Iterator pointing to first element of the memory area.
+ */
+ auto begin() const -> iterator { return begin_itr; }
+
+ /**
+ * @brief Returns the iterator pointing to one past the last element of the memory area.
+ * Allows using this class in the for each loop, because it follows the InputIterator template scheme.
+ *
+ * @return Iterator pointing to one past the last element of the memory area.
+ */
+ auto end() const -> iterator { return end_itr; }
+
+ /**
+ * @brief Calculates the size of this container, simply subtracts the iterator pointing to the first element by the
+ * last.
+ *
+ * @return Actual size of this container.
+ */
+ auto size() const -> size_type { return std::distance(begin(), end()); }
+
+ /**
+ * @brief Calcualtes the size and returns true if the size is 0 and the container therefore emtpy.
+ *
+ * @return Whether the container is empty, size being 0 or not
+ */
+ 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.
+ };
+} // namespace teachos::arch::shared
+
+#endif // TEACHOS_ARCH_X86_64_SHARED_CONTAINER_HPP
diff --git a/arch/x86_64/include/arch/shared/random_access_iterator.hpp b/arch/x86_64/include/arch/shared/random_access_iterator.hpp
new file mode 100644
index 0000000..392b925
--- /dev/null
+++ b/arch/x86_64/include/arch/shared/random_access_iterator.hpp
@@ -0,0 +1,167 @@
+#ifndef TEACHOS_ARCH_X86_64_SHARED_RANDOM_ACCESS_ITERATOR_HPP
+#define TEACHOS_ARCH_X86_64_SHARED_RANDOM_ACCESS_ITERATOR_HPP
+
+#include <iterator>
+
+namespace teachos::arch::shared
+{
+ /**
+ * @brief Generic random access iterator for given template type. Can be a nullptr, ensure to check when using this
+ * iterator. Allows to easily use this iterator instance in algorithm calls.
+ *
+ * @tparam T Value the iterator points too.
+ */
+ template<typename T>
+ struct random_access_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 = T; ///< Underlying value pointed to by this iterator.
+
+ /**
+ * @brief Defaulted constructor.
+ */
+ random_access_iterator() = default;
+
+ /**
+ * @brief Constructor.
+ *
+ * @param p Underlying address the iterator should point too, ensure to not pass an invalid pointer or the
+ * constructor will halt execution.
+ */
+ explicit random_access_iterator(value_type * p)
+ : ptr(p)
+ {
+ // Nothing to do
+ }
+
+ /**
+ * @brief Dereferences the initally given pointer to its value.
+ *
+ * @return Reference to the value.
+ */
+ auto operator*() const -> value_type & { return *ptr; }
+
+ /**
+ * @brief Get underlying value, which is the intially passed pointer.
+ *
+ * @return Underlying value passed intially.
+ */
+ auto operator->() const -> value_type * { return ptr; }
+
+ /**
+ * @brief Post increment operator. Returns a copy of the value.
+ *
+ * @return Copy of the incremented underlying address.
+ */
+ auto operator++(int) -> random_access_iterator
+ {
+ random_access_iterator old_value = *this;
+ ++ptr;
+ return old_value;
+ }
+
+ /**
+ * @brief Pre increment operator. Returns a reference to the changed value.
+ *
+ * @return Reference to the incremented underlying address.
+ */
+ auto operator++() -> random_access_iterator &
+ {
+ ++ptr;
+ return *this;
+ }
+
+ /**
+ * @brief Addition assignment operator. Returns a reference to the changed value.
+ *
+ * @param value Value we want to add to the underlying address.
+ * @return Reference to the changed underlying address.
+ */
+ auto operator+=(difference_type value) -> random_access_iterator &
+ {
+ ptr += value;
+ return *this;
+ }
+
+ /**
+ * @brief Subtraction assignment operator. Returns a reference to the changed value.
+ *
+ * @param value Value we want to subtract from the underlying address.
+ * @return Reference to the changed underlying address.
+ */
+ auto operator-=(difference_type value) -> random_access_iterator &
+ {
+ ptr -= value;
+ return *this;
+ }
+
+ /**
+ * @brief Addition operator. Returns the changed value.
+ *
+ * @param value 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 value) const -> random_access_iterator
+ {
+ return random_access_iterator{ptr + value};
+ }
+
+ /**
+ * @brief Subtraction operator. Returns the changed value.
+ *
+ * @param value 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 value) const -> random_access_iterator
+ {
+ return random_access_iterator{ptr - value};
+ }
+
+ /**
+ * @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 random_access_iterator & other) const -> difference_type { return ptr - other.ptr; }
+
+ /**
+ * @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 & { return *(ptr + index); }
+
+ /**
+ * @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==(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.
+ * @return Whether the given iterator is smaller or larger than this iterator.
+ */
+ auto operator<=>(random_access_iterator const & other) const -> std::strong_ordering = default;
+
+ private:
+ value_type * ptr = {}; ///< Underlying address the iterator is currently pointing too.
+ };
+} // namespace teachos::arch::shared
+
+#endif // TEACHOS_ARCH_X86_64_SHARED_RANDOM_ACCESS_ITERATOR_HPP
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 6ed4f28..e03c66a 100644
--- a/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp
+++ b/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp
@@ -9,9 +9,9 @@
namespace teachos::arch::memory::allocator
{
area_frame_allocator::area_frame_allocator(multiboot::memory_information mem_info)
- : next_free_frame(0)
+ : next_free_frame(0U)
, current_area(std::nullopt)
- , memory_areas(mem_info.memory_areas, mem_info.area_count)
+ , memory_areas(mem_info.begin_area, mem_info.end_area)
, kernel_start(physical_frame::containing_address(mem_info.kernel_start))
, kernel_end(physical_frame::containing_address(mem_info.kernel_end))
, multiboot_start(physical_frame::containing_address(mem_info.multiboot_start))
diff --git a/arch/x86_64/src/memory/multiboot/memory_map.cpp b/arch/x86_64/src/memory/multiboot/memory_map.cpp
deleted file mode 100644
index b5e2759..0000000
--- a/arch/x86_64/src/memory/multiboot/memory_map.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-#include "arch/memory/multiboot/memory_map.hpp"
-
-#include "arch/exception_handling/assert.hpp"
-
-namespace teachos::arch::memory::multiboot
-{
- memory_area_iterator::memory_area_iterator(value_type * p)
- : ptr(p)
- {
- exception_handling::assert(ptr, "[Memory Area] Attempted to pass nullptr as iterator");
- }
-
- auto memory_area_iterator::operator*() const -> value_type & { return *ptr; }
-
- auto memory_area_iterator::operator->() const -> value_type * { return ptr; }
-
- auto memory_area_iterator::operator++(int) -> memory_area_iterator
- {
- memory_area_iterator old_value = *this;
- ++ptr;
- return old_value;
- }
-
- auto memory_area_iterator::operator++() -> memory_area_iterator &
- {
- ++ptr;
- return *this;
- }
-
- auto memory_area_iterator::operator+=(difference_type value) -> memory_area_iterator &
- {
- ptr += value;
- return *this;
- }
-
- auto memory_area_iterator::operator-=(difference_type value) -> memory_area_iterator &
- {
- ptr -= value;
- return *this;
- }
-
- auto memory_area_iterator::operator+(difference_type value) const -> memory_area_iterator
- {
- return memory_area_iterator{ptr + value};
- }
-
- auto memory_area_iterator::operator-(difference_type value) const -> memory_area_iterator
- {
- return memory_area_iterator{ptr - value};
- }
-
- auto memory_area_iterator::operator-(const memory_area_iterator & other) const -> difference_type
- {
- return ptr - other.ptr;
- }
-
- auto memory_area_iterator::operator[](difference_type index) const -> value_type & { return *(ptr + index); }
-
- memory_area_container::memory_area_container(memory_area * begin, std::size_t size)
- : area_begin(begin)
- , area_end(begin + size)
- {
- // Nothing to do
- }
-
- auto memory_area_container::begin() const -> multiboot::memory_area_iterator { return area_begin; }
-
- auto memory_area_container::end() const -> multiboot::memory_area_iterator { return area_end; }
-
- auto memory_area_container::size() const -> size_type { return std::distance(begin(), end()); }
-
- auto memory_area_container::empty() const -> bool { return size() == 0; }
-} // namespace teachos::arch::memory::multiboot
diff --git a/arch/x86_64/src/memory/multiboot/reader.cpp b/arch/x86_64/src/memory/multiboot/reader.cpp
index c750ae1..228aa09 100644
--- a/arch/x86_64/src/memory/multiboot/reader.cpp
+++ b/arch/x86_64/src/memory/multiboot/reader.cpp
@@ -2,8 +2,11 @@
#include "arch/boot/pointers.hpp"
#include "arch/exception_handling/assert.hpp"
+#include "arch/memory/multiboot/elf_symbols_section.hpp"
#include "arch/memory/multiboot/info.hpp"
+#include <algorithm>
+
namespace teachos::arch::memory::multiboot
{
namespace
@@ -15,7 +18,8 @@ namespace teachos::arch::memory::multiboot
return reinterpret_cast<T>(reinterpret_cast<uint8_t *>(ptr) + ((size + 7) & ~7));
}
- auto process_memory_map(memory_map_header * mminfo, memory_area *& memory_areas, uint8_t & area_count) -> void
+ auto process_memory_map(memory_map_header * mminfo, memory_area_container::iterator & begin_area,
+ memory_area_container::iterator & end_area) -> void
{
auto expected_entry_size = mminfo->entry_size;
constexpr auto actual_entry_size = sizeof(memory_area);
@@ -26,8 +30,8 @@ namespace teachos::arch::memory::multiboot
auto total_entries_size = total_size - sizeof(memory_map_header) + actual_entry_size;
auto number_of_entries = total_entries_size / actual_entry_size;
- memory_areas = &mminfo->entries;
- area_count = number_of_entries;
+ begin_area = memory_area_container::iterator{&mminfo->entries};
+ end_area = begin_area + number_of_entries;
}
auto process_elf_sections(elf_symbols_section_header * symbol, uint64_t & kernel_start,
@@ -45,40 +49,30 @@ namespace teachos::arch::memory::multiboot
exception_handling::assert(expected_total_size == actual_total_size,
"[Multiboot Reader] Unexpected elf symbols section header total size");
- auto begin = reinterpret_cast<elf_section_header *>(&symbol->end);
+ auto begin = elf_section_header_container::iterator{reinterpret_cast<elf_section_header *>(&symbol->end)};
auto end = begin + symbol->number_of_sections;
exception_handling::assert(begin->is_null(),
"[Multiboot Reader] Elf symbols section not starting with SHT_NULL section");
- std::size_t symbol_table_section_count = 0U;
- std::size_t dynamic_section_count = 0U;
+ elf_section_header_container container{begin, end};
- for (auto section = begin; section != end; ++section)
- {
- if (section->virtual_address < kernel_start)
- {
- kernel_start = section->virtual_address;
- }
- auto virtual_address_end = section->virtual_address + section->section_size;
- if (virtual_address_end > kernel_end)
- {
- kernel_end = virtual_address_end;
- }
+ auto elf_section_with_lowest_virtual_address =
+ std::ranges::min_element(container, [](elf_section_header const & a, elf_section_header const & b) {
+ return a.virtual_address < b.virtual_address;
+ });
- switch (section->type)
- {
- case elf_section_type::DYNAMIC_SYMBOL_TABLE:
- case elf_section_type::SYMBOL_TABLE:
- symbol_table_section_count++;
- break;
- case elf_section_type::DYNAMIC:
- dynamic_section_count++;
- break;
- default:
- // All other cases are not important and can be ignored
- break;
- }
- }
+ auto elf_section_with_highest_virtual_address =
+ std::ranges::max_element(container, [](elf_section_header const & a, elf_section_header const & b) {
+ auto a_virtual_address_end = a.virtual_address + a.section_size;
+ auto b_virtual_address_end = b.virtual_address + b.section_size;
+ return a_virtual_address_end < b_virtual_address_end;
+ });
+
+ auto symbol_table_section_count = std::ranges::count_if(container, [](elf_section_header const & section) {
+ return section.type == elf_section_type::DYNAMIC_SYMBOL_TABLE || section.type == elf_section_type::SYMBOL_TABLE;
+ });
+ auto dynamic_section_count = std::ranges::count_if(
+ container, [](elf_section_header const & section) { return section.type == elf_section_type::DYNAMIC; });
exception_handling::assert(
symbol_table_section_count == 1U,
@@ -86,15 +80,26 @@ namespace teachos::arch::memory::multiboot
exception_handling::assert(
dynamic_section_count <= 1U,
"[Multiboot Reader] ELF Specifications allows only (1) or less dynamic sections, but got more");
+
+ auto lowest_elf_section = *elf_section_with_lowest_virtual_address;
+ kernel_start = lowest_elf_section.virtual_address;
+
+ auto highest_elf_section = *elf_section_with_highest_virtual_address;
+ kernel_end = highest_elf_section.virtual_address + highest_elf_section.section_size;
}
} // namespace
auto read_multiboot2() -> memory_information
{
- memory_information mem_info{UINT64_MAX, 0U, boot::multiboot_information_pointer, 0U, nullptr, 0U};
-
- auto * multiboot_information_pointer = reinterpret_cast<info_header *>(boot::multiboot_information_pointer);
- auto multiboot_tag = &(multiboot_information_pointer->tags);
+ memory_information mem_info{UINT64_MAX,
+ 0U,
+ boot::multiboot_information_pointer,
+ 0U,
+ memory_area_container::iterator{},
+ memory_area_container::iterator{}};
+
+ auto multiboot_information_pointer = reinterpret_cast<info_header *>(boot::multiboot_information_pointer);
+ auto multiboot_tag = &multiboot_information_pointer->tags;
mem_info.multiboot_end = mem_info.multiboot_start + multiboot_information_pointer->total_size;
for (auto tag = multiboot_tag; tag->type != tag_type::END; tag = align_to_8_byte_boundary(tag, tag->size))
@@ -108,11 +113,11 @@ namespace teachos::arch::memory::multiboot
}
case tag_type::MEMORY_MAP: {
auto mminfo = reinterpret_cast<memory_map_header *>(tag);
- process_memory_map(mminfo, mem_info.memory_areas, mem_info.area_count);
+ process_memory_map(mminfo, mem_info.begin_area, mem_info.end_area);
break;
}
default:
- // All other cases are not important and can be ignored
+ // All other cases are not important and can be ignored.
break;
}
}