#include "arch/memory/multiboot/reader.hpp" #include "arch/boot/pointers.hpp" #include "arch/exception_handling/assert.hpp" #include "multiboot2/information.hpp" // #include "arch/memory/multiboot/elf_symbols_section.hpp" // #include "arch/memory/multiboot/info.hpp" #include #include // namespace teachos::arch::memory::multiboot // { // namespace // { // template // requires std::is_pointer::value // auto align_to_8_byte_boundary(T ptr, uint32_t size) -> T // { // return reinterpret_cast(reinterpret_cast(ptr) + ((size + 7) & ~7)); // } // auto process_memory_map(memory_map_header * mminfo) -> memory_area_container // { // auto const expected_entry_size = mminfo->entry_size; // auto constexpr actual_entry_size = sizeof(memory_area); // exception_handling::assert(expected_entry_size == actual_entry_size, // "[Multiboot Reader] Unexpected memory area entry size"); // auto const total_size = mminfo->info.size; // auto const total_entries_size = total_size - sizeof(memory_map_header) + actual_entry_size; // auto const number_of_entries = total_entries_size / actual_entry_size; // auto const begin = memory_area_container::iterator{&mminfo->entries}; // auto const end = begin + number_of_entries; // return memory_area_container{begin, end}; // } // auto process_elf_sections(elf_symbols_section_header * symbol, std::size_t & kernel_start, std::size_t & // kernel_end) // -> elf_section_header_container // { // auto const expected_entry_size = symbol->entry_size; // auto constexpr actual_entry_size = sizeof(elf_section_header); // exception_handling::assert(expected_entry_size == actual_entry_size, // "[Multiboot Reader] Unexpected elf section header entry size"); // auto const expected_total_size = symbol->info.size; // auto const actual_total_entry_size = actual_entry_size * symbol->number_of_sections; // auto constexpr actual_total_section_size = sizeof(elf_symbols_section_header) - sizeof(uint32_t); // auto const actual_total_size = actual_total_entry_size + actual_total_section_size; // exception_handling::assert(expected_total_size == actual_total_size, // "[Multiboot Reader] Unexpected elf symbols section header total size"); // auto const begin = elf_section_header_container::iterator{reinterpret_cast(&symbol->end)}; auto const end = begin + symbol->number_of_sections; // exception_handling::assert(begin->is_null(), // "[Multiboot Reader] Elf symbols section not starting with SHT_NULL section"); // elf_section_header_container sections{begin, end}; // auto allocated_sections = sections | std::views::filter([](auto const & section) { // return section.flags.contains_flags(elf_section_flags::OCCUPIES_MEMORY); // }); // auto const elf_section_with_lowest_physical_address = std::ranges::min_element( // allocated_sections, [](auto const & a, auto const & b) { return a.physical_address < b.physical_address; // }); // auto const elf_section_with_highest_physical_address = // std::ranges::max_element(allocated_sections, [](auto const & a, auto const & b) { // auto a_physical_address_end = a.physical_address + a.section_size; // auto b_physical_address_end = b.physical_address + b.section_size; // return a_physical_address_end < b_physical_address_end; // }); // auto const symbol_table_section_count = std::ranges::count_if(sections, [](auto const & section) { // return section.type == elf_section_type::DYNAMIC_SYMBOL_TABLE || section.type == // elf_section_type::SYMBOL_TABLE; // }); // auto const dynamic_section_count = std::ranges::count_if( // sections, [](auto const & section) { return section.type == elf_section_type::DYNAMIC; }); // exception_handling::assert( // symbol_table_section_count == 1U, // "[Multiboot Reader] ELF Specifications allows only (1) symbol table section, but got more"); // exception_handling::assert( // dynamic_section_count <= 1U, // "[Multiboot Reader] ELF Specifications allows only (1) or less dynamic sections, but got more"); // auto const lowest_elf_section = *elf_section_with_lowest_physical_address; // kernel_start = lowest_elf_section.physical_address; // auto const highest_elf_section = *elf_section_with_highest_physical_address; // kernel_end = highest_elf_section.physical_address + highest_elf_section.section_size; // return sections; // } // } // namespace // auto read_multiboot2() -> memory_information // { // memory_information mem_info{UINT64_MAX, // 0U, // elf_section_header_container{}, // boot::multiboot_information_pointer, // 0U, // memory_area_container{}}; // auto const multiboot_information_pointer = reinterpret_cast(boot::multiboot_information_pointer); // auto const 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)) // { // switch (tag->type) // { // case tag_type::ELF_SECTIONS: { // auto const symbol = reinterpret_cast(tag); // mem_info.sections = process_elf_sections(symbol, mem_info.kernel_start, mem_info.kernel_end); // break; // } // case tag_type::MEMORY_MAP: { // auto const mminfo = reinterpret_cast(tag); // mem_info.areas = process_memory_map(mminfo); // break; // } // default: // // All other cases are not important and can be ignored. // break; // } // } // return mem_info; // } // } // namespace teachos::arch::memory::multiboot