[amd64] Get memory map/GRUB info from loader
This commit is contained in:
+2
-1
@@ -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
|
||||
|
||||
@@ -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));
|
||||
@@ -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);
|
||||
@@ -1,4 +1,6 @@
|
||||
.section .text
|
||||
// Args:
|
||||
// %rdi - Address of loader's information struct
|
||||
.global _start
|
||||
_start:
|
||||
cli
|
||||
|
||||
+31
-1
@@ -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();
|
||||
|
||||
@@ -88,6 +88,7 @@ long_entry:
|
||||
mov %ax, %ss
|
||||
|
||||
.code64
|
||||
leaq loader_data(%rip), %rdi
|
||||
movq 4(%rsp), %rax
|
||||
jmp *%rax
|
||||
.code32
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user