aboutsummaryrefslogtreecommitdiff
path: root/kernel.cc
blob: 30453741b8fa6343fd11b7ccdf967ac3c0995ad4 (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
/* Check if the compiler thinks you are targeting the wrong operating system. */
#if defined(__linux__)
#error "You are not using a cross-compiler"
#endif

/* This tutorial will only work for the 32-bit ix86 targets. */
#if !defined(__i386__)
#error "This tutorial needs to be compiled with a ix86-elf compiler"
#endif

#include <stdlib.h>
#include <types.h>
#include "multiboot2.h"
#include "vga.h"

extern "C" void kernel_main(uint32_t mb_magic, uint32_t mb_addr) {
  VGA terminal;
  Console::set(&terminal);

  printk("Hello, kernel World!\n");

  printk("multiboot magic: ", uhex{mb_magic}, mb_magic == MULTIBOOT2_BOOTLOADER_MAGIC ? " valid" : " invalid", '\n');
  printk("multiboot  addr: ", uhex{mb_addr}, !(mb_addr & 7) ? " is aligned" : " is not aligned", '\n');

  struct multiboot_tag* tag;
  const uint32_t size = *(unsigned*)mb_addr;
  printk("Announced mbi size ", size, '\n');

  for (tag = (struct multiboot_tag*)(mb_addr + 8); tag->type != MULTIBOOT_TAG_TYPE_END;
       tag = (struct multiboot_tag*)((multiboot_uint8_t*)tag + ((tag->size + 7) & ~7))) {
    switch (tag->type) {
      case MULTIBOOT_TAG_TYPE_CMDLINE: {
        auto* t = reinterpret_cast<multiboot_tag_string*>(tag);
        printk("Command line = [", t->string, "]\n");
      } break;

      case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: {
        auto* t = reinterpret_cast<multiboot_tag_string*>(tag);
        printk("Boot loader name = [", t->string, "]\n");
      } break;

      case MULTIBOOT_TAG_TYPE_BOOTDEV: {
        auto* t = reinterpret_cast<multiboot_tag_bootdev*>(tag);
        printk("Boot device ", uhex{t->biosdev}, " slice ", t->slice, " part ", t->part, '\n');
      } break;

      case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: {
        auto* t = reinterpret_cast<multiboot_tag_basic_meminfo*>(tag);
        printk("mem_lower = ", t->mem_lower, "KB\n", "mem_upper = ", t->mem_upper, "KB\n");
      } break;

      case MULTIBOOT_TAG_TYPE_MMAP: {
        auto* t = reinterpret_cast<multiboot_tag_mmap*>(tag);
        multiboot_memory_map_t* mmap;

        printk("memory map\n");
        for (mmap = t->entries; (multiboot_uint8_t*)mmap < (multiboot_uint8_t*)tag + tag->size;
             mmap = (multiboot_memory_map_t*)((unsigned long)mmap + ((struct multiboot_tag_mmap*)tag)->entry_size)) {
          printk("  base_addr = ", uhex{(unsigned)(mmap->addr >> 32)}, ' ', uhex{(unsigned)(mmap->addr & 0xffffffff)});
          printk(" length = ", (unsigned)(mmap->len >> 32), ' ', (unsigned)(mmap->len & 0xffffffff));
          printk(" type = ", (unsigned)mmap->type, '\n');
        }
      } break;

      default:
        printk("Tag ", tag->type, ", Size ", tag->size, '\n');
        break;
    }  // switch(tag->type)
  }    // for(each tag)

  tag = (struct multiboot_tag*)((multiboot_uint8_t*)tag + ((tag->size + 7) & ~7));
  printk("Total mbi size ", (unsigned)tag - mb_addr, '\n');

  abort();
}