aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/memory/multiboot/reader.cpp
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/x86_64/src/memory/multiboot/reader.cpp
parent58d01f6aae80a66faa5163602c399c28dcf30cb6 (diff)
downloadkernel-04b0285d8329e45cea426aa1a8e69203685a4467.tar.xz
kernel-04b0285d8329e45cea426aa1a8e69203685a4467.zip
Move iterator and container into generic template classes. Use algorithms instead of raw pointer for loops
Diffstat (limited to 'arch/x86_64/src/memory/multiboot/reader.cpp')
-rw-r--r--arch/x86_64/src/memory/multiboot/reader.cpp79
1 files changed, 42 insertions, 37 deletions
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;
}
}