Read memory map tags from multiboot
This commit is contained in:
parent
0b3648de7c
commit
80cc165957
@ -6,13 +6,6 @@
|
|||||||
#include <cpu.h>
|
#include <cpu.h>
|
||||||
#include <interrupts.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)
|
void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
||||||
{
|
{
|
||||||
serial_init(PORT_COM1);
|
serial_init(PORT_COM1);
|
||||||
@ -26,13 +19,10 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
|||||||
cpu_init();
|
cpu_init();
|
||||||
|
|
||||||
|
|
||||||
// Force and catch a divide by zero exception
|
uintptr_t start, end;
|
||||||
// ISR 0
|
uint32_t type, i=0;
|
||||||
bind_interrupt(0, divbyzero);
|
while(!multiboot_get_memory_area(i++, &start, &end, &type))
|
||||||
int a = 5, b = 0;
|
debug_printf("Mem %d 0x%x-0x%x\n", type, start, end);
|
||||||
int c = a/b;
|
|
||||||
|
|
||||||
debug("a: %d b:%d c:%d\n", a,b,c);
|
|
||||||
|
|
||||||
debug_ok("Boot \"Complete\"\n");
|
debug_ok("Boot \"Complete\"\n");
|
||||||
|
|
||||||
|
@ -15,14 +15,29 @@ struct tag {
|
|||||||
uint8_t data[];
|
uint8_t data[];
|
||||||
}__attribute__((packed));
|
}__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_COMMANDLINE 1
|
||||||
#define MBOOT2_BOOTLOADER 2
|
#define MBOOT2_BOOTLOADER 2
|
||||||
|
#define MBOOT2_MMAP 6
|
||||||
|
|
||||||
struct kernel_boot_data_st kernel_boot_data;
|
struct kernel_boot_data_st kernel_boot_data;
|
||||||
|
|
||||||
int parse_multiboot2(struct taglist *tags)
|
int parse_multiboot2(struct taglist *tags)
|
||||||
{
|
{
|
||||||
struct tag *tag = incptr(tags, sizeof(struct taglist));
|
struct tag *tag = incptr(tags, sizeof(struct taglist));
|
||||||
|
struct mmap *mmap;
|
||||||
while(tag->type)
|
while(tag->type)
|
||||||
{
|
{
|
||||||
switch(tag->type)
|
switch(tag->type)
|
||||||
@ -33,6 +48,10 @@ int parse_multiboot2(struct taglist *tags)
|
|||||||
case MBOOT2_COMMANDLINE:
|
case MBOOT2_COMMANDLINE:
|
||||||
kernel_boot_data.commandline = (char *)tag->data;
|
kernel_boot_data.commandline = (char *)tag->data;
|
||||||
break;
|
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:
|
default:
|
||||||
debug_warning("Unknown multiboot tag type:%d \n", tag->type);
|
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;
|
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));
|
ASSERT_EQ_STR(kernel_boot_data.bootloader, name, strlen(name));
|
||||||
free(tags);
|
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
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
struct kernel_boot_data_st
|
struct kernel_boot_data_st
|
||||||
{
|
{
|
||||||
int multiboot_version;
|
int multiboot_version;
|
||||||
char *bootloader;
|
char *bootloader;
|
||||||
char *commandline;
|
char *commandline;
|
||||||
|
size_t mmap_size;
|
||||||
|
void *mmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct kernel_boot_data_st kernel_boot_data;
|
extern struct kernel_boot_data_st kernel_boot_data;
|
||||||
|
|
||||||
int multiboot_init(uint64_t magic, void *mboot_info);
|
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