blob: 40b2fe54de4b26d1b0519299da188f10f1e539a4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#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
|