aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/include/arch/boot/multiboot.hpp86
-rw-r--r--arch/x86_64/src/kernel/main.cpp60
2 files changed, 120 insertions, 26 deletions
diff --git a/arch/x86_64/include/arch/boot/multiboot.hpp b/arch/x86_64/include/arch/boot/multiboot.hpp
index dfb289d..d3787f2 100644
--- a/arch/x86_64/include/arch/boot/multiboot.hpp
+++ b/arch/x86_64/include/arch/boot/multiboot.hpp
@@ -6,6 +6,14 @@ struct multiboot_tag
uint32_t size;
};
+struct basic_memory_info
+{
+ uint32_t type;
+ uint32_t size;
+ uint32_t mem_lower;
+ uint32_t mem_upper;
+};
+
struct multiboot_info
{
uint32_t total_size;
@@ -44,18 +52,72 @@ struct memory_map_info
struct memory_map_entry entries;
};
-struct elf64_section_header
+#define EI_NIDENT 16
+
+/* ELF standard typedefs (yet more proof that <stdint.h> was way overdue) */
+typedef uint16_t Elf64_Half;
+typedef int16_t Elf64_SHalf;
+typedef uint32_t Elf64_Word;
+typedef int32_t Elf64_Sword;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+
+typedef uint64_t Elf64_Off;
+typedef uint64_t Elf64_Addr;
+typedef uint16_t Elf64_Section;
+
+struct executable_header
+{
+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
+ Elf64_Half e_type; /* Object file type */
+ Elf64_Half e_machine; /* Architecture */
+ Elf64_Word e_version; /* Object file version */
+ Elf64_Addr e_entry; /* Entry point virtual address */
+ Elf64_Off e_phoff; /* Program header table file offset */
+ Elf64_Off e_shoff; /* Section header table file offset */
+ Elf64_Word e_flags; /* Processor-specific flags */
+ Elf64_Half e_ehsize; /* ELF header size in bytes */
+ Elf64_Half e_phentsize; /* Program header table entry size */
+ Elf64_Half e_phnum; /* Program header table entry count */
+ Elf64_Half e_shentsize; /* Section header table entry size */
+ Elf64_Half e_shnum; /* Section header table entry count */
+ Elf64_Half e_shstrndx; /* Section header string table index */
+};
+
+struct program_header
+{
+ Elf64_Word p_type; /* Segment type */
+ Elf64_Word p_flags; /* Segment flags */
+ Elf64_Off p_offset; /* Segment file offset */
+ Elf64_Addr p_vaddr; /* Segment virtual address */
+ Elf64_Addr p_paddr; /* Segment physical address */
+ Elf64_Xword p_filesz; /* Segment size in file */
+ Elf64_Xword p_memsz; /* Segment size in memory */
+ Elf64_Xword p_align; /* Segment alignment */
+};
+
+struct elf_section_header
+{
+ Elf64_Word sh_name; /* Section name (string tbl index) */
+ Elf64_Word sh_type; /* Section type */
+ Elf64_Xword sh_flags; /* Section flags */
+ Elf64_Addr sh_addr; /* Section virtual addr at execution */
+ Elf64_Off sh_offset; /* Section file offset */
+ Elf64_Xword sh_size; /* Section size in bytes */
+ Elf64_Word sh_link; /* Link to another section */
+ Elf64_Word sh_info; /* Additional section information */
+ Elf64_Xword sh_addralign; /* Section alignment */
+ Elf64_Xword sh_entsize; /* Entry size if section holds table */
+};
+
+struct elf_symbol
{
- uint32_t sh_name;
- uint32_t sh_type;
- uint64_t sh_flags;
- uint64_t sh_addr;
- uint64_t sh_offset;
- uint64_t sh_size;
- uint32_t sh_link;
- uint32_t sh_info;
- uint64_t sh_addralign;
- uint64_t sh_entsize;
+ Elf64_Word st_name; /* Symbol name (string tbl index) */
+ unsigned char st_info; /* Symbol type and binding */
+ unsigned char st_other; /* Symbol visibility */
+ Elf64_Section st_shndx; /* Section index */
+ Elf64_Addr st_value; /* Symbol value */
+ Elf64_Xword st_size; /* Symbol size */
};
struct elf_symbols_section
@@ -65,7 +127,7 @@ struct elf_symbols_section
uint16_t entsize;
uint16_t shndx;
uint16_t reserved;
- struct elf64_section_header sections;
+ struct elf_section_header sections;
};
/*
diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp
index 2040fe3..4deac6d 100644
--- a/arch/x86_64/src/kernel/main.cpp
+++ b/arch/x86_64/src/kernel/main.cpp
@@ -6,14 +6,28 @@
namespace teachos::arch::kernel
{
+ auto print_mem_info(basic_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(memory_map_info * mminfo) -> void
{
using namespace video::vga;
uint32_t const entry_size = mminfo->entry_size;
- uint32_t const entry_version = mminfo->entry_version;
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);
@@ -26,10 +40,13 @@ namespace teachos::arch::kernel
{
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(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);
}
@@ -42,9 +59,11 @@ namespace teachos::arch::kernel
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);
@@ -56,32 +75,41 @@ namespace teachos::arch::kernel
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 name: ", text::common_attributes::green_on_black);
+ 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 name: ", text::common_attributes::green_on_black);
+ 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 name: ", text::common_attributes::green_on_black);
+ 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 name: ", text::common_attributes::green_on_black);
+ 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 name: ", text::common_attributes::green_on_black);
+ 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 name: ", text::common_attributes::green_on_black);
+ 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 name: ", text::common_attributes::green_on_black);
+ text::write("Section entry size: ", text::common_attributes::green_on_black);
text::write_number(sh_entsize, text::common_attributes::green_on_black);
}
}
@@ -94,20 +122,24 @@ namespace teachos::arch::kernel
text::cursor(false);
text::write("TeachOS is starting up...", text::common_attributes::green_on_black);
- auto mip = arch::boot::multiboot_information_pointer;
-
- // Address of the first multiboot tag
- auto multiboot_tag = (struct multiboot_tag *)((uint8_t *)mip + 8);
+ multiboot_info * multiboot_information_pointer = (multiboot_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.
+ * 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 != MULTIBOOT_TAG_TYPE_END;
- tag = (struct multiboot_tag *)((uint8_t *)tag + ((tag->size + 7) & ~7)))
+ tag = (struct multiboot_tag *)(((uint8_t *)tag) + ((tag->size + 7) & ~7)))
{
switch (tag->type)
{
+ case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
+ print_mem_info((struct basic_memory_info *)tag);
+ break;
case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
print_elf_sections((struct elf_symbols_section *)tag);
break;