From 80cc165957204c879c84fe854d82e7cfc96105e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Tue, 19 Dec 2017 22:51:11 +0100 Subject: [PATCH] Read memory map tags from multiboot --- src/kernel/boot/kmain.c | 18 ++------- src/kernel/boot/multiboot.c | 33 ++++++++++++++++ src/kernel/boot/multiboot.tt | 72 ++++++++++++++++++++++++++++++++++ src/kernel/include/multiboot.h | 4 ++ 4 files changed, 113 insertions(+), 14 deletions(-) diff --git a/src/kernel/boot/kmain.c b/src/kernel/boot/kmain.c index 025dc2c..ebdbd03 100644 --- a/src/kernel/boot/kmain.c +++ b/src/kernel/boot/kmain.c @@ -6,13 +6,6 @@ #include #include -registers *divbyzero(registers *r) -{ - debug_error("Divide by zero error!\n"); - debug_print_registers(r); - for(;;); -} - void kmain(uint64_t multiboot_magic, void *multiboot_data) { serial_init(PORT_COM1); @@ -26,13 +19,10 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data) cpu_init(); - // Force and catch a divide by zero exception - // ISR 0 - bind_interrupt(0, divbyzero); - int a = 5, b = 0; - int c = a/b; - - debug("a: %d b:%d c:%d\n", a,b,c); + uintptr_t start, end; + uint32_t type, i=0; + while(!multiboot_get_memory_area(i++, &start, &end, &type)) + debug_printf("Mem %d 0x%x-0x%x\n", type, start, end); debug_ok("Boot \"Complete\"\n"); diff --git a/src/kernel/boot/multiboot.c b/src/kernel/boot/multiboot.c index cfb8bbd..8dc2822 100644 --- a/src/kernel/boot/multiboot.c +++ b/src/kernel/boot/multiboot.c @@ -15,14 +15,29 @@ struct tag { uint8_t data[]; }__attribute__((packed)); +struct mmap_entry{ + uint64_t base; + uint64_t len; + uint32_t type; + uint32_t reserved; +}__attribute__((packed)); + +struct mmap { + uint32_t entry_size; + uint32_t entry_version; + struct mmap_entry entries[]; +}__attribute__((packed)); + #define MBOOT2_COMMANDLINE 1 #define MBOOT2_BOOTLOADER 2 +#define MBOOT2_MMAP 6 struct kernel_boot_data_st kernel_boot_data; int parse_multiboot2(struct taglist *tags) { struct tag *tag = incptr(tags, sizeof(struct taglist)); + struct mmap *mmap; while(tag->type) { switch(tag->type) @@ -33,6 +48,10 @@ int parse_multiboot2(struct taglist *tags) case MBOOT2_COMMANDLINE: kernel_boot_data.commandline = (char *)tag->data; break; + case MBOOT2_MMAP: + mmap = kernel_boot_data.mmap = (void *)tag->data; + kernel_boot_data.mmap_size = (tag->size - 8)/mmap->entry_size; + break; default: debug_warning("Unknown multiboot tag type:%d \n", tag->type); } @@ -54,3 +73,17 @@ int multiboot_init(uint64_t magic, void *mboot_info) return 0; } + +int multiboot_get_memory_area(size_t count, uintptr_t *start, uintptr_t *end, uint32_t *type) +{ + if(count >= kernel_boot_data.mmap_size) return 1; + + struct mmap *mmap = kernel_boot_data.mmap; + struct mmap_entry *entry = mmap->entries; + entry = incptr(entry, count*mmap->entry_size); + + *start = entry->base; + *end = entry->base + entry->len; + *type = entry->type; + return 0; +} diff --git a/src/kernel/boot/multiboot.tt b/src/kernel/boot/multiboot.tt index 8f903fc..61e8366 100644 --- a/src/kernel/boot/multiboot.tt +++ b/src/kernel/boot/multiboot.tt @@ -149,3 +149,75 @@ TEST(reads_multiple_tags_4) ASSERT_EQ_STR(kernel_boot_data.bootloader, name, strlen(name)); free(tags); } + +TEST(reads_mmap_tag) +{ + uint32_t mmap[] = {24, 0, + 0x90ABCDEF, 0x12345678, 0x00010000, 0x00000000, 0x1, 0x0 + }; + void *tags = generate_taglist(2, + generate_tag(6, mmap, 32), + generate_tag(0,0,0) + ); + multiboot_init(MAGIC, tags); + + ASSERT_EQ_INT(kernel_boot_data.mmap_size, 1); + free(tags); +} +void setup_memory_areas() +{ + uint32_t mmap[] = {24, 0, + 0x90ABCDEF, 0x12345678, 0x00010000, 0x00000000, 0x1, 0x0, + 0x0ABCDEF1, 0x23456789, 0x00010000, 0x00000000, 0x1, 0x0 + }; + void *tags = generate_taglist(2, + generate_tag(6, mmap, 56), + generate_tag(0,0,0) + ); + multiboot_init(MAGIC, tags); +} +TEST(reads_multiple_mmap_tags) +{ + setup_memory_areas(); + ASSERT_EQ_INT(kernel_boot_data.mmap_size, 2); +} +TEST(returns_memory_area_start) +{ + setup_memory_areas(); + uintptr_t start, end; + uint32_t type; + multiboot_get_memory_area(0, &start, &end, &type); + ASSERT_EQ_PTR(start, 0x1234567890ABCDEF); +} +TEST(returns_memory_area_end) +{ + setup_memory_areas(); + uintptr_t start, end; + uint32_t type; + multiboot_get_memory_area(0, &start, &end, &type); + ASSERT_EQ_PTR(end, 0x1234567890ACCDEF); +} +TEST(returns_memory_area_type) +{ + setup_memory_areas(); + uintptr_t start, end; + uint32_t type; + multiboot_get_memory_area(0, &start, &end, &type); + ASSERT_EQ_INT(type, 1); +} +TEST(returns_second_memory_area_start) +{ + setup_memory_areas(); + uintptr_t start, end; + uint32_t type; + multiboot_get_memory_area(1, &start, &end, &type); + ASSERT_EQ_PTR(start, 0x234567890ABCDEF1); +} +TEST(does_not_return_too_many_areas) +{ + setup_memory_areas(); + uintptr_t start, end; + uint32_t type; + int retval = multiboot_get_memory_area(2, &start, &end, &type); + ASSERT_NEQ_INT(retval, 0); +} diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index b1d2314..03ff3dd 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -1,12 +1,16 @@ #pragma once #include +#include struct kernel_boot_data_st { int multiboot_version; char *bootloader; char *commandline; + size_t mmap_size; + void *mmap; }; extern struct kernel_boot_data_st kernel_boot_data; int multiboot_init(uint64_t magic, void *mboot_info); +int multiboot_get_memory_area(size_t count, uintptr_t *start, uintptr_t *end, uint32_t *type);