Read memory map tags from multiboot
This commit is contained in:
parent
0b3648de7c
commit
80cc165957
@ -6,13 +6,6 @@
|
||||
#include <cpu.h>
|
||||
#include <interrupts.h>
|
||||
|
||||
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");
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -1,12 +1,16 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user