boot: fix (?) memory corruption problems with EFI
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
[submodule "boot/yboot"]
|
||||
path = boot/yboot
|
||||
url = https://git.alnyan.me/yggdrasil/yboot.git
|
||||
@@ -24,7 +24,7 @@ _entry_common:
|
||||
kernel_pre_entry:
|
||||
// Full 64-bit now
|
||||
leaq kernel_stacks_bottom(%rip), %rsp
|
||||
addq $AMD64_KERNEL_STACK, %rsp
|
||||
addq $8192, %rsp
|
||||
|
||||
movq %rdi, %rbx
|
||||
call _init
|
||||
|
||||
+21
-22
@@ -1,37 +1,36 @@
|
||||
#include <config.h>
|
||||
#include <yboot/include/protocol.h>
|
||||
|
||||
.section .data.boot, "aw", %progbits
|
||||
#define BOOT_KERNEL_MAGIC 0xA197A9B007B007UL
|
||||
#define BOOT_LOADER_MAGIC 0x700B700B9A791AUL
|
||||
|
||||
.global yboot_data
|
||||
.type yboot_data, %object
|
||||
yboot_data:
|
||||
.quad BOOT_KERNEL_MAGIC // kernel_magic
|
||||
.quad 0 // loader_magic
|
||||
.quad YB_KERNEL_MAGIC_V1 // kernel_magic
|
||||
.quad 0 // loader_magic
|
||||
|
||||
.long 0 // memory_map_size
|
||||
.long 0 // memory_map_entsize
|
||||
.quad yboot_memory_map_data - 0xFFFFFF0000000000 // memory_map_data
|
||||
.long 32768 // memory_map_size
|
||||
.long 0 // memory_map_entsize
|
||||
|
||||
.long 1600 // video_width
|
||||
.long 900 // video_height
|
||||
.long 1 // video_format = BGR
|
||||
.long 0 // --
|
||||
.quad 0 // video_framebuffer
|
||||
.quad 0 // video_pitch
|
||||
.long 640 // video_width
|
||||
.long 480 // video_height
|
||||
.long 1 // video_format = BGR
|
||||
.long 0 // --
|
||||
.quad 0 // video_framebuffer
|
||||
.quad 0 // video_pitch
|
||||
|
||||
.quad 0 // elf_symtab_hdr
|
||||
.quad 0 // elf_symtab_data
|
||||
.quad 0 // elf_strtab_hdr
|
||||
.quad 0 // elf_strtab_data
|
||||
.quad 0 // elf_symtab_hdr
|
||||
.quad 0 // elf_symtab_data
|
||||
.quad 0 // elf_strtab_hdr
|
||||
.quad 0 // elf_strtab_data
|
||||
|
||||
.quad 0 // initrd_base
|
||||
.quad 0 // initrd_size
|
||||
.quad 0 // initrd_base
|
||||
.quad 0 // initrd_size
|
||||
|
||||
.quad 0 // rsdp
|
||||
.quad 0 // rsdp
|
||||
|
||||
.skip 256 // cmdline
|
||||
.skip 3072 // memory map data
|
||||
.skip YB_CMDLINE_SIZE // cmdline
|
||||
.size yboot_data, . - yboot_data
|
||||
|
||||
.section .text
|
||||
@@ -44,7 +43,7 @@ _entry_yboot:
|
||||
|
||||
// Validate loader signature
|
||||
movq 8(%rdi), %rax
|
||||
movabsq $BOOT_LOADER_MAGIC, %rsi
|
||||
movabsq $YB_LOADER_MAGIC_V1, %rsi
|
||||
cmp %rax, %rsi
|
||||
jne _bad_loader_magic
|
||||
|
||||
|
||||
+9
-42
@@ -1,3 +1,4 @@
|
||||
#include "yboot/include/protocol.h"
|
||||
#include "arch/amd64/multiboot2.h"
|
||||
#include "arch/amd64/hw/rs232.h"
|
||||
#include "arch/amd64/hw/vesa.h"
|
||||
@@ -17,6 +18,7 @@
|
||||
#include "sys/mem/phys.h"
|
||||
#include "sys/console.h"
|
||||
#include "sys/config.h"
|
||||
#include "sys/assert.h"
|
||||
#include "sys/kernel.h"
|
||||
#include "sys/random.h"
|
||||
#include "sys/string.h"
|
||||
@@ -35,6 +37,7 @@ static uintptr_t initrd_phys_start;
|
||||
static size_t initrd_size;
|
||||
|
||||
static struct boot_video_info boot_video_info = {0};
|
||||
char yboot_memory_map_data[32768];
|
||||
|
||||
// Descriptors for reserved physical memory regions
|
||||
static struct mm_phys_memory_map phys_memory_map;
|
||||
@@ -141,46 +144,8 @@ static void entry_multiboot(void) {
|
||||
offsetof(struct multiboot_tag_mmap, entries)) / multiboot_tag_mmap->entry_size;
|
||||
}
|
||||
|
||||
// TODO: move this header
|
||||
#define BOOT_KERNEL_MAGIC 0xA197A9B007B007UL
|
||||
#define BOOT_LOADER_MAGIC 0x700B700B9A791AUL
|
||||
|
||||
#define VIDEO_FORMAT_RGB32 0
|
||||
#define VIDEO_FORMAT_BGR32 1
|
||||
|
||||
#if !defined(__ASM__)
|
||||
struct boot_struct {
|
||||
uint64_t kernel_magic; // R
|
||||
uint64_t loader_magic; // W
|
||||
|
||||
uint32_t memory_map_size; // W
|
||||
uint32_t memory_map_entsize; // W
|
||||
|
||||
// Video mode settings
|
||||
uint32_t video_width; // RW
|
||||
uint32_t video_height; // RW
|
||||
uint32_t video_format; // RW
|
||||
uint32_t __pad0; // --
|
||||
uint64_t video_framebuffer; // W
|
||||
uint64_t video_pitch; // W
|
||||
|
||||
uint64_t elf_symtab_hdr; // W
|
||||
uint64_t elf_symtab_data; // W
|
||||
uint64_t elf_strtab_hdr; // W
|
||||
uint64_t elf_strtab_data; // W
|
||||
|
||||
uint64_t initrd_base; // W
|
||||
uint64_t initrd_size; // W
|
||||
|
||||
uint64_t rsdp; // W
|
||||
|
||||
char cmdline[256]; // W
|
||||
char memory_map_data[3072]; // W
|
||||
} __attribute__((packed));
|
||||
#endif
|
||||
|
||||
static void entry_yboot(void) {
|
||||
extern struct boot_struct yboot_data;
|
||||
extern struct yboot_v1 yboot_data;
|
||||
|
||||
if (yboot_data.rsdp == 0) {
|
||||
kwarn("Booted from UEFI and no RSDP was provided, will likely result in error\n");
|
||||
@@ -200,12 +165,14 @@ static void entry_yboot(void) {
|
||||
}
|
||||
|
||||
if (yboot_data.initrd_base) {
|
||||
kdebug("INITRD BASE: %p, INITRD SIZE: %S\n", yboot_data.initrd_base, yboot_data.initrd_size);
|
||||
initrd_phys_start = yboot_data.initrd_base;
|
||||
initrd_size = yboot_data.initrd_size;
|
||||
}
|
||||
|
||||
_assert(yboot_memory_map_data == (void *) MM_VIRTUALIZE(yboot_data.memory_map_data));
|
||||
phys_memory_map.format = MM_PHYS_MMAP_FMT_YBOOT;
|
||||
phys_memory_map.address = yboot_data.memory_map_data;
|
||||
phys_memory_map.address = yboot_memory_map_data;
|
||||
phys_memory_map.entry_size = yboot_data.memory_map_entsize;
|
||||
phys_memory_map.entry_count = yboot_data.memory_map_size / yboot_data.memory_map_entsize;
|
||||
}
|
||||
@@ -235,12 +202,12 @@ void kernel_early_init(uint64_t entry_method) {
|
||||
// Before anything is allocated, reserve:
|
||||
// 1. initrd pages
|
||||
// 2. multiboot tag pages
|
||||
mm_phys_reserve(&phys_reserve_kernel);
|
||||
mm_phys_reserve("Kernel", &phys_reserve_kernel);
|
||||
|
||||
if (initrd_phys_start) {
|
||||
phys_reserve_initrd.begin = initrd_phys_start & ~0xFFF;
|
||||
phys_reserve_initrd.end = (initrd_phys_start + initrd_size + 0xFFF) & ~0xFFF;
|
||||
mm_phys_reserve(&phys_reserve_initrd);
|
||||
mm_phys_reserve("Initrd", &phys_reserve_initrd);
|
||||
}
|
||||
|
||||
amd64_phys_memory_map(&phys_memory_map);
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ _kernel_base = 0xFFFFFF0000000000;
|
||||
* This will allow us to have initrds up to 32MiB
|
||||
* loaded below
|
||||
*/
|
||||
_kernel_base_phys = 0x400000;
|
||||
_kernel_base_phys = 0x200000;
|
||||
|
||||
SECTIONS {
|
||||
. = _kernel_base_phys + _kernel_base;
|
||||
|
||||
@@ -25,7 +25,8 @@ struct page *mm_pages = NULL;
|
||||
static size_t _total_pages, _pages_free;
|
||||
static size_t _alloc_pages[_PU_COUNT];
|
||||
static spin_t phys_spin = 0;
|
||||
static struct mm_phys_reserved phys_reserve_mm_pages;
|
||||
static struct mm_phys_reserved phys_reserve_mm_pages,
|
||||
phys_reserve_mmap;
|
||||
static LIST_HEAD(reserved_regions);
|
||||
|
||||
static int is_reserved(uintptr_t addr) {
|
||||
@@ -144,10 +145,10 @@ static int mmap_iter_next(struct mmap_iter *iter,
|
||||
return 1;
|
||||
}
|
||||
|
||||
void mm_phys_reserve(struct mm_phys_reserved *res) {
|
||||
void mm_phys_reserve(const char *use, struct mm_phys_reserved *res) {
|
||||
list_head_init(&res->link);
|
||||
list_add(&res->link, &reserved_regions);
|
||||
kdebug("#### Reserve region: %p .. %p\n", res->begin, res->end);
|
||||
kdebug("#### Reserve region (%s): %p .. %p\n", use, res->begin, res->end);
|
||||
}
|
||||
|
||||
void mm_phys_stat(struct mm_phys_stat *st) {
|
||||
@@ -265,8 +266,6 @@ static uintptr_t place_mm_pages(const struct mm_phys_memory_map *mmap, size_t re
|
||||
uintptr_t page_aligned_begin = (base + 0xFFF) & ~0xFFF;
|
||||
uintptr_t page_aligned_end = (base + size) & ~0xFFF;
|
||||
|
||||
kdebug("Region: %p .. %p\n", page_aligned_begin, page_aligned_end);
|
||||
|
||||
if (kind == MMAP_KIND_USABLE && page_aligned_end > page_aligned_begin) {
|
||||
// Something like mm_phys_alloc_contiguous does, but
|
||||
// we don't yet have it obviously
|
||||
@@ -300,6 +299,10 @@ void amd64_phys_memory_map(const struct mm_phys_memory_map *mmap) {
|
||||
size_t size;
|
||||
int kind;
|
||||
|
||||
phys_reserve_mmap.begin = (uintptr_t) MM_PHYS(mmap->address);
|
||||
phys_reserve_mmap.end = phys_reserve_mmap.begin + mmap->entry_count * mmap->entry_size;
|
||||
mm_phys_reserve("Memory map", &phys_reserve_mmap);
|
||||
|
||||
// Allocate space for mm_pages array
|
||||
size_t mm_pages_req_count = (PHYS_MAX_PAGES * sizeof(struct page) + 0xFFF) >> 12;
|
||||
uintptr_t mm_pages_addr = place_mm_pages(mmap, mm_pages_req_count);
|
||||
@@ -309,7 +312,7 @@ void amd64_phys_memory_map(const struct mm_phys_memory_map *mmap) {
|
||||
phys_reserve_mm_pages.begin = mm_pages_addr;
|
||||
phys_reserve_mm_pages.end = mm_pages_addr + mm_pages_req_count * MM_PAGE_SIZE;
|
||||
// TODO: also reserve memory map itself before screwing with it?
|
||||
mm_phys_reserve(&phys_reserve_mm_pages);
|
||||
mm_phys_reserve("mm_pages", &phys_reserve_mm_pages);
|
||||
|
||||
mm_pages = (struct page *) MM_VIRTUALIZE(mm_pages_addr);
|
||||
for (size_t i = 0; i < PHYS_MAX_PAGES; ++i) {
|
||||
@@ -317,8 +320,6 @@ void amd64_phys_memory_map(const struct mm_phys_memory_map *mmap) {
|
||||
mm_pages[i].refcount = (size_t) -1L;
|
||||
}
|
||||
|
||||
kdebug("Memory map @ %p\n", mmap);
|
||||
|
||||
_total_pages = 0;
|
||||
mmap_iter_init(mmap, &iter);
|
||||
|
||||
|
||||
Submodule
+1
Submodule boot/yboot added at 0d6477a1ec
+1
-1
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define AMD64_KERNEL_STACK 32768
|
||||
#define AMD64_KERNEL_STACK 65536
|
||||
#define AMD64_MAX_SMP 1
|
||||
|
||||
//#define SLAB_TRACE_ALLOC 1
|
||||
|
||||
+1
-3
@@ -142,9 +142,7 @@ include etc/KernelOptions.makefile
|
||||
KERNEL_GIT_VERSION=$(shell git describe --always --tags)
|
||||
KERNEL_CFLAGS=-Iinclude \
|
||||
-Iinclude/arch/amd64/acpica \
|
||||
-Iarch/amd64/efi/gnu-efi-3.0.12/inc \
|
||||
-Iarch/amd64/efi/gnu-efi-3.0.12/inc/protocol \
|
||||
-Iarch/amd64/efi/gnu-efi-3.0.12/inc/x86_64 \
|
||||
-Iboot \
|
||||
-fshort-wchar \
|
||||
-I$(O)/include \
|
||||
-ffreestanding \
|
||||
|
||||
@@ -46,7 +46,7 @@ struct mm_phys_stat {
|
||||
size_t pages_used_cache;
|
||||
};
|
||||
|
||||
void mm_phys_reserve(struct mm_phys_reserved *res);
|
||||
void mm_phys_reserve(const char *use, struct mm_phys_reserved *res);
|
||||
void mm_phys_stat(struct mm_phys_stat *st);
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user