#include "arch/kernel/main.hpp" #include "arch/boot/pointers.hpp" #include "arch/memory/multiboot.hpp" #include "arch/video/vga/text.hpp" namespace teachos::arch::kernel { auto assert(bool condition) -> void { video::vga::text::write("Assert failed", video::vga::text::common_attributes::green_on_black); while (!condition) { // Trick the compiler into thinking the variable is changes at run time, // to prevent the while loop being optimized away // See // https://stackoverflow.com/questions/9495856/how-to-prevent-g-from-optimizing-out-a-loop-controlled-by-a-variable-that-can // for mroe information. asm volatile("" : "+g"(condition)); } } auto print_mem_info(arch::memory::memory_info * mem_info) -> void { video::vga::text::write("Memory info low: ", video::vga::text::common_attributes::green_on_black); video::vga::text::write_number(mem_info->mem_lower, video::vga::text::common_attributes::green_on_black); } auto print_memory_map(arch::memory::memory_map * mminfo) -> void { auto expected_entry_size = mminfo->entry_size; constexpr auto actual_entry_size = sizeof(arch::memory::memory_area); assert(expected_entry_size == actual_entry_size); auto remaining_size = mminfo->tag.size - (4 * sizeof(uint32_t)); auto entry_amount = remaining_size / mminfo->entry_size; auto begin = &mminfo->entries; auto end = begin + entry_amount; for (auto entry = begin; entry != end; ++entry) { video::vga::text::write("Looping Memory area", video::vga::text::common_attributes::green_on_black); } } auto print_elf_sections(arch::memory::elf_symbols_section * symbol) -> void { auto expected_entry_size = symbol->entry_size; constexpr auto actual_entry_size = sizeof(arch::memory::elf_section_header); assert(expected_entry_size == actual_entry_size); auto expected_total_size = symbol->tag.size; auto actual_total_entry_size = actual_entry_size * symbol->number_of_sections; constexpr auto actual_total_section_size = sizeof(arch::memory::elf_symbols_section) - actual_entry_size - sizeof(uint32_t); auto actual_total_size = actual_total_entry_size + actual_total_section_size; assert(expected_total_size == actual_total_size); auto begin = &symbol->sections; auto end = begin + symbol->number_of_sections; // TODO: Last value is completly wrong, should show 0 but shows huge value for size of entries in the table of the // SHT_NULL elf section entry. Memory around value also make no sense and look even worse? But according to api // value should be zero :( // assert(begin->is_null()); std::size_t symbol_table_section_count = 0U; std::size_t dynamic_section_count = 0U; for (auto section = begin; section != end; ++section) { if (section->type == arch::memory::elf_section_type::DYNAMIC_SYMBOL_TABLE || section->type == arch::memory::elf_section_type::SYMBOL_TABLE) { symbol_table_section_count++; } else if (section->type == arch::memory::elf_section_type::DYNAMIC) { dynamic_section_count++; } video::vga::text::write("Looping Code section", video::vga::text::common_attributes::green_on_black); } // TODO: Contains two symbol tables and 4 dynamic sections, that is definetly wrong, perhaps same reason as above? assert(symbol_table_section_count == 1U); assert(dynamic_section_count == 1U); } auto main() -> void { using namespace video::vga; text::clear(); text::cursor(false); text::write("TeachOS is starting up...", text::common_attributes::green_on_black); arch::memory::multi_boot_info * multiboot_information_pointer = (arch::memory::multi_boot_info *)arch::boot::multiboot_information_pointer; auto multiboot_tag = &(multiboot_information_pointer->tags); /* * Loop over the multiboot2 tags to access the information needed. * Tags are defined in the header file and are padded so that each * Tag starts at an 8-bytes aligned adress. * * The increment part aligns the size to an 8-byte address. */ for (auto tag = multiboot_tag; tag->type != arch::memory::multi_boot_tag_type::END; tag = (arch::memory::multi_boot_tag *)(((uint8_t *)tag) + ((tag->size + 7) & ~7))) { switch (tag->type) { case arch::memory::multi_boot_tag_type::BASIC_MEMORY_INFO: print_mem_info((arch::memory::memory_info *)tag); break; case arch::memory::multi_boot_tag_type::ELF_SECTIONS: print_elf_sections((arch::memory::elf_symbols_section *)tag); break; case arch::memory::multi_boot_tag_type::MEMORY_MAP: print_memory_map((arch::memory::memory_map *)tag); break; default: // All other cases are not important and can be ignored break; } } } } // namespace teachos::arch::kernel