aboutsummaryrefslogtreecommitdiff
path: root/kernel.cc
blob: b2e2b01a52a319bbc0de902561c8a0a84723cfd6 (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
/* 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 "multiboot2.h"
#include "vga.h"
#include <stdlib.h>
#include <types.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: 0x", mb_magic,
         mb_magic == MULTIBOOT2_BOOTLOADER_MAGIC ? " is valid" : " is invalid",
         '\n');
  printk("multiboot addr: 0x", mb_addr, '\n');

  if (mb_addr & 7) {
    printk("unaligned mbi\n");
  }

  struct multiboot_tag *tag;
  const uint32_t size = *(unsigned *)mb_addr;
  printk("Announced mbi size 0x", 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:
      printk("Command line = [", ((struct multiboot_tag_string *)tag)->string,
             "]\n");
      break;
    case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
      printk("Boot loader name = [",
             ((struct multiboot_tag_string *)tag)->string, "]\n");
      break;
    case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
      printk("mem_lower = ",
             ((struct multiboot_tag_basic_meminfo *)tag)->mem_lower, "KB\n",
             "mem_upper = ",
             ((struct multiboot_tag_basic_meminfo *)tag)->mem_upper, "KB\n");
      break;
    case MULTIBOOT_TAG_TYPE_BOOTDEV:
      printk("Boot device 0x", ((struct multiboot_tag_bootdev *)tag)->biosdev,
             " slice ", ((struct multiboot_tag_bootdev *)tag)->slice, " part ",
             ((struct multiboot_tag_bootdev *)tag)->part, '\n');
      break;
    case MULTIBOOT_TAG_TYPE_MMAP: {
      multiboot_memory_map_t *mmap;

      printk("mmap\n");

      for (mmap = ((struct multiboot_tag_mmap *)tag)->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 = 0x", (unsigned)(mmap->addr >> 32), ' ',
               (unsigned)(mmap->addr & 0xffffffff), " length = 0x",
               (unsigned)(mmap->len >> 32), ' ',
               (unsigned)(mmap->len & 0xffffffff), " type = 0x",
               (unsigned)mmap->type, '\n');
    } break;
    default:
      printk("Tag 0x", tag->type, ", Size 0x", 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 0x", (unsigned)tag - mb_addr, '\n');

  abort();
}