aboutsummaryrefslogtreecommitdiff
path: root/src/multiboot2.c
blob: d3e41754257e8bec372b4eeee053a0b8975afea9 (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
#include "mmap.h"

#define ADDR(x) ((unsigned)&x - 0xc0000000 + 0x2000)

boot_info_t info __attribute__((section(".init")));

__attribute__((section(".multiboot.text"))) void
multiboot_strncpy(char *dest, const char *src, unsigned n)
{
  for (unsigned i = 0; i < n && src[i] != '\0'; ++i) dest[i] = src[i];
}

__attribute__((section(".multiboot.text"))) void
multiboot2_module(struct multiboot_tag_module *tag, boot_info_t *info)
{
  info->module_start = tag->mod_start;
  info->module_end = tag->mod_end;
  multiboot_strncpy(info->module_cmdline, tag->cmdline, 64);
}

/**
 * parse multiboot2 structures
 */
__attribute__((section(".multiboot.text"))) void
__multiboot2(multiboot_uint32_t addr)
{
  boot_info_t *__info = (boot_info_t *)ADDR(info);

  struct multiboot_tag *tag;
  for (tag = (struct multiboot_tag *)(addr + 8); tag->type != MULTIBOOT_TAG_TYPE_END;
       tag = (struct multiboot_tag *)((multiboot_uint8_t *)tag + ((tag->size + 7u) & ~7u))) {

    switch (tag->type) {
    case MULTIBOOT_TAG_TYPE_CMDLINE:
      multiboot_strncpy(__info->cmdline, ((struct multiboot_tag_string *)tag)->string, 64);
      break;
    case MULTIBOOT_TAG_TYPE_MODULE:
      multiboot2_module((struct multiboot_tag_module *)tag, __info);
      break;
    case MULTIBOOT_TAG_TYPE_MMAP:
      multiboot2_mmap(((struct multiboot_tag_mmap *)tag)->entries,
                      ((struct multiboot_tag_mmap *)tag)->size / ((struct multiboot_tag_mmap *)tag)->entry_size,
                      __info->bitmap);
      break;
    default:
      break;
    } // switch
  }   // for
}