[amd64] Get memory map/GRUB info from loader

This commit is contained in:
Mark
2019-09-17 16:37:03 +03:00
parent 83fe3a58d8
commit a5c71af69c
8 changed files with 82 additions and 2 deletions
+2 -1
View File
@@ -17,7 +17,8 @@ OBJS+=$(O)/arch/amd64/kernel.o \
$(O)/arch/amd64/mm/map.o \
$(O)/arch/amd64/hw/timer.o \
$(O)/arch/amd64/acpi/tables.o \
$(O)/arch/amd64/acpi/hpet.o
$(O)/arch/amd64/acpi/hpet.o \
$(O)/arch/amd64/mm/phys.o
kernel_OBJS=$(O)/arch/amd64/entry.o \
$(OBJS)
kernel_LINKER=$(S)/arch/amd64/link.ld
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <stdint.h>
struct amd64_loader_data {
uint32_t multiboot_info_ptr;
// Just in case
uint8_t checksum;
} __attribute__((packed));
+5
View File
@@ -0,0 +1,5 @@
#pragma once
#include "arch/amd64/loader/multiboot.h"
#include <sys/types.h>
void amd64_phys_memory_map(const multiboot_memory_map_t *mmap, size_t length);
+2
View File
@@ -1,4 +1,6 @@
.section .text
// Args:
// %rdi - Address of loader's information struct
.global _start
_start:
cli
+31 -1
View File
@@ -1,23 +1,53 @@
#include "sys/mm.h"
#include "sys/debug.h"
#include "sys/panic.h"
#include "arch/amd64/hw/gdt.h"
#include "arch/amd64/hw/pic8259.h"
#include "arch/amd64/hw/ints.h"
#include "arch/amd64/hw/timer.h"
#include "arch/amd64/loader/data.h"
#include "arch/amd64/loader/multiboot.h"
#include "arch/amd64/mm/phys.h"
#include "arch/amd64/acpi/tables.h"
// TODO: move to some util header
#define __wfe() asm volatile ("sti; hlt")
void kernel_main(void) {
static struct amd64_loader_data *loader_data = 0;
static multiboot_info_t *multiboot_info;
static uint8_t amd64_loader_data_checksum(const struct amd64_loader_data *ld) {
uint8_t chk = 0;
for (size_t i = 0; i < sizeof(struct amd64_loader_data); ++i) {
chk += ((uint8_t *) ld)[i];
}
return chk;
}
static void amd64_loader_data_process(void) {
// Virtualize pointer locations, as the loader has passed their
// physical locations
multiboot_info = (multiboot_info_t *) MM_VIRTUALIZE(loader_data->multiboot_info_ptr);
}
void kernel_main(uintptr_t loader_info_phys_ptr) {
kdebug("Booting\n");
#if defined(KERNEL_TEST_MODE)
kdebug("Kernel testing mode enabled\n");
#endif
// Obtain boot information from loader
loader_data = (struct amd64_loader_data *) MM_VIRTUALIZE(loader_info_phys_ptr);
if (amd64_loader_data_checksum(loader_data)) {
panic("Loader data checksum is invalid\n");
}
// Process loader data
amd64_loader_data_process();
// Memory management
amd64_mm_init();
amd64_phys_memory_map((multiboot_memory_map_t *) MM_VIRTUALIZE(multiboot_info->mmap_addr), multiboot_info->mmap_length);
amd64_gdt_init();
pic8259_init();
acpi_tables_init();
+1
View File
@@ -88,6 +88,7 @@ long_entry:
mov %ax, %ss
.code64
leaq loader_data(%rip), %rdi
movq 4(%rsp), %rax
jmp *%rax
.code32
+13
View File
@@ -1,11 +1,13 @@
#include "arch/amd64/loader/multiboot.h"
#include "arch/amd64/loader/util.h"
#include "arch/amd64/loader/data.h"
#include "elf.h"
#define KERNEL_VIRT_BASE 0xFFFFFF0000000000
extern void long_entry(uint64_t v);
struct amd64_loader_data loader_data;
uint64_t pml4[512] __attribute__((aligned(0x1000)));
static uint64_t loader_pdpt[512] __attribute__((aligned(0x1000)));
static uint64_t kernel_pdpt[512] __attribute__((aligned(0x1000)));
@@ -85,6 +87,9 @@ void loader_main(uint32_t magic, struct multiboot_info *mb_info) {
panic("Invalid bootloader magic");
}
// Setup loader_data
loader_data.multiboot_info_ptr = (uint64_t) mb_info;
struct multiboot_mod_list *mod_list = (struct multiboot_mod_list *) mb_info->mods_addr;
if (mb_info->mods_count != 1) {
@@ -109,5 +114,13 @@ void loader_main(uint32_t magic, struct multiboot_info *mb_info) {
paging_init();
uint64_t entry = elf_load(mod_list[0].mod_start);
// Calculate checksum for loader_data
uint8_t checksum = 0;
for (size_t i = 0; i < sizeof(struct amd64_loader_data) - sizeof(uint8_t); ++i) {
checksum += ((uint8_t *) &loader_data)[i];
}
loader_data.checksum = -checksum;
long_entry(entry);
}
+20
View File
@@ -0,0 +1,20 @@
#include "arch/amd64/mm/phys.h"
#include "sys/debug.h"
void amd64_phys_memory_map(const multiboot_memory_map_t *mmap, size_t length) {
static const char *mmap_region_strings[6] = {
"Unknown", "Available", "Used", "ACPI", "Reserved", "Defective"
};
kdebug("Memory map @ %p\n", mmap);
uintptr_t curr_item = (uintptr_t) mmap;
uintptr_t mmap_end = length + curr_item;
while (curr_item < mmap_end) {
const multiboot_memory_map_t *entry = (const multiboot_memory_map_t *) (curr_item);
size_t type_index = (entry->type >= (sizeof(mmap_region_strings) / sizeof(mmap_region_strings[0]))) ? 0 : entry->type;
kdebug("%p - %p: %s\n", entry->addr, entry->addr + entry->size, mmap_region_strings[type_index]);
curr_item += entry->size + sizeof(uint32_t);
}
}