aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/kernel/main.cpp
blob: 4d6296ae46e11bcf40caa45e95d5cdd91b8d1372 (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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#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 print_mem_info(arch::memory::memory_info * mem_info) -> void
  {
    using namespace video::vga;

    auto mem_lower = mem_info->mem_lower;
    text::write("Lower memory (kB): ", text::common_attributes::green_on_black);
    text::write_number(mem_lower, text::common_attributes::green_on_black);

    auto mem_upper = mem_info->mem_upper;
    text::write("Upper memory (kB): ", text::common_attributes::green_on_black);
    text::write_number(mem_upper, text::common_attributes::green_on_black);
  }

  auto print_memory_map(arch::memory::memory_map * mminfo) -> void
  {
    using namespace video::vga;

    uint32_t const entry_size = mminfo->entry_size;
    text::write("Entry Size: ", text::common_attributes::green_on_black);
    text::write_number(entry_size, text::common_attributes::green_on_black);

    uint32_t const entry_version = mminfo->entry_version;
    text::write("Version: ", text::common_attributes::green_on_black);
    text::write_number(entry_version, text::common_attributes::green_on_black);

    uint32_t const remaining_size = mminfo->tag.size - (4 * sizeof(uint32_t));
    uint32_t const entry_amount = remaining_size / entry_size;

    auto begin = &mminfo->entries;
    auto end = begin + entry_amount;
    for (auto entry = begin; entry != end; ++entry)
    {
      text::write("Base Address: ", text::common_attributes::green_on_black);
      text::write_number(entry->base_addr, text::common_attributes::green_on_black);

      text::write("Length: ", text::common_attributes::green_on_black);
      text::write_number(entry->length, text::common_attributes::green_on_black);

      text::write("Type: ", text::common_attributes::green_on_black);
      text::write_number(static_cast<std::underlying_type<arch::memory::memory_area_type>::type>(entry->type),
                         text::common_attributes::green_on_black);

      text::write("Reserved: ", text::common_attributes::green_on_black);
      text::write_number(entry->reserved, text::common_attributes::green_on_black);
    }
  }

  auto print_elf_sections(arch::memory::elf_symbols_section * symbol) -> void
  {
    using namespace video::vga;

    uint16_t const num = symbol->num;
    text::write("Number of entries: ", text::common_attributes::green_on_black);
    text::write_number(num, text::common_attributes::green_on_black);

    uint16_t const entsize = symbol->entsize;
    text::write("Entry Size: ", text::common_attributes::green_on_black);
    text::write_number(entsize, text::common_attributes::green_on_black);

    uint16_t const shndx = symbol->shndx;
    text::write("Section index: ", text::common_attributes::green_on_black);
    text::write_number(shndx, text::common_attributes::green_on_black);

    auto begin = &symbol->sections;
    auto end = begin + num;
    for (auto section = begin; section != end; ++section)
    {
      uint32_t const sh_name = section->sh_name;
      text::write("Section name: ", text::common_attributes::green_on_black);
      text::write_number(sh_name, text::common_attributes::green_on_black);

      uint32_t const sh_type = section->sh_type;
      text::write("Section type: ", text::common_attributes::green_on_black);
      text::write_number(sh_type, text::common_attributes::green_on_black);

      uint64_t const sh_flags = section->sh_flags;
      text::write("Section flags: ", text::common_attributes::green_on_black);
      text::write_number(sh_flags, text::common_attributes::green_on_black);

      uint64_t const sh_addr = section->sh_addr;
      text::write("Section address: ", text::common_attributes::green_on_black);
      text::write_number(sh_addr, text::common_attributes::green_on_black);

      uint64_t const sh_offset = section->sh_offset;
      text::write("Section offset: ", text::common_attributes::green_on_black);
      text::write_number(sh_offset, text::common_attributes::green_on_black);

      uint64_t const sh_size = section->sh_size;
      text::write("Section size: ", text::common_attributes::green_on_black);
      text::write_number(sh_size, text::common_attributes::green_on_black);

      uint32_t const sh_link = section->sh_link;
      text::write("Section link: ", text::common_attributes::green_on_black);
      text::write_number(sh_link, text::common_attributes::green_on_black);

      uint32_t const sh_info = section->sh_info;
      text::write("Section info: ", text::common_attributes::green_on_black);
      text::write_number(sh_info, text::common_attributes::green_on_black);

      uint64_t const sh_addralign = section->sh_addralign;
      text::write("Section address align: ", text::common_attributes::green_on_black);
      text::write_number(sh_addralign, text::common_attributes::green_on_black);

      uint64_t const sh_entsize = section->sh_entsize;
      text::write("Section entry size: ", text::common_attributes::green_on_black);
      text::write_number(sh_entsize, text::common_attributes::green_on_black);
    }
  }

  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);

    text::write("Multiboot Start: ", text::common_attributes::green_on_black);
    text::write_number(arch::boot::multiboot_information_pointer, text::common_attributes::green_on_black);
    text::write("Multiboot End: ", text::common_attributes::green_on_black);
    text::write_number(arch::boot::multiboot_information_pointer + multiboot_information_pointer->total_size,
                       text::common_attributes::green_on_black);

    /*
     * 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