diff options
Diffstat (limited to 'kernel/multiboot2.c')
-rw-r--r-- | kernel/multiboot2.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/kernel/multiboot2.c b/kernel/multiboot2.c new file mode 100644 index 0000000..bd6250f --- /dev/null +++ b/kernel/multiboot2.c @@ -0,0 +1,50 @@ +#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) +{ + unsigned i; + for (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 *tag_info) +{ + tag_info->module_start = tag->mod_start; + tag_info->module_end = tag->mod_end; + multiboot_strncpy(tag_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; + } + } +} |