From 2e537412d3a857c14af92e6104dd332866fe4bfa Mon Sep 17 00:00:00 2001 From: mintsuki Date: Fri, 11 Sep 2020 16:17:55 +0200 Subject: [PATCH] Improve the way stivale paging is set up --- src/Makefile | 2 +- src/protos/stivale.c | 30 +++++++++++++++++++++++++----- src/protos/stivale.h | 4 +++- src/protos/stivale2.c | 9 ++++++--- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/Makefile b/src/Makefile index f9d00071..2a10aaf7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -34,7 +34,7 @@ limine.bin: $(BC) $(ASM_OBJ) clang --target=i386-elf -O$(OPT_LEVEL) -c optimised_bundle.bc -o optimised_bundle.o ld.lld optimised_bundle.o $(ASM_OBJ) $(INTERNAL_LDFLAGS) -o stage2.elf llvm-objcopy -O binary stage2.elf stage2.bin - gzip -9 stage2.bin + gzip -9 < stage2.bin > stage2.bin.gz $(MAKE) -C decompressor cd bootsect && nasm bootsect.asm -fbin -o ../limine.bin diff --git a/src/protos/stivale.c b/src/protos/stivale.c index b0583ff8..b964b9b3 100644 --- a/src/protos/stivale.c +++ b/src/protos/stivale.c @@ -243,11 +243,13 @@ void stivale_load(char *cmdline, int boot_drive) { stivale_struct.memory_map_addr = (uint64_t)(size_t)memmap; stivale_spinup(bits, level5pg && (stivale_hdr.flags & (1 << 1)), - entry_point, &stivale_struct, stivale_hdr.stack); + entry_point, &stivale_struct, stivale_hdr.stack, + memmap, memmap_entries); } __attribute__((noreturn)) void stivale_spinup(int bits, bool level5pg, - uint64_t entry_point, void *stivale_struct, uint64_t stack) { + uint64_t entry_point, void *stivale_struct, uint64_t stack, + struct e820_entry_t *memmap, size_t memmap_entries) { if (bits == 64) { // If we're going 64, we might as well call this BIOS interrupt // to tell the BIOS that we are entering Long Mode, since it is in @@ -272,16 +274,34 @@ __attribute__((noreturn)) void stivale_spinup(int bits, bool level5pg, } pagemap_t pagemap = new_pagemap(level5pg ? 5 : 4); + uint64_t higher_half_base = level5pg ? 0xff00000000000000 : 0xffff800000000000; // Map 0 to 2GiB at 0xffffffff80000000 for (uint64_t i = 0; i < 0x80000000; i += PAGE_SIZE) { - map_page(pagemap, i + 0xffffffff80000000, i, 0x03); + map_page(pagemap, 0xffffffff80000000 + i, i, 0x03); } - // Map 0 to 4GiB at 0xffff800000000000 and 0 + // Map 0 to 4GiB at higher half base and 0 for (uint64_t i = 0; i < 0x100000000; i += PAGE_SIZE) { map_page(pagemap, i, i, 0x03); - map_page(pagemap, i + 0xffff800000000000, i, 0x03); + map_page(pagemap, higher_half_base + i, i, 0x03); + } + + // Map any other region of memory from the memmap + for (size_t i = 0; i < memmap_entries; i++) { + uint64_t base = memmap[i].base; + uint64_t length = memmap[i].length; + uint64_t top = base + length; + + uint64_t aligned_base = ALIGN_DOWN(base, PAGE_SIZE); + uint64_t aligned_top = ALIGN_UP(top, PAGE_SIZE); + uint64_t aligned_length = aligned_top - aligned_base; + + for (uint64_t i = 0; i < aligned_length; i += PAGE_SIZE) { + uint64_t page = aligned_base + i; + map_page(pagemap, page, page, 0x03); + map_page(pagemap, higher_half_base + page, page, 0x03); + } } ASM( diff --git a/src/protos/stivale.h b/src/protos/stivale.h index 5a6fdaa6..ae7ed101 100644 --- a/src/protos/stivale.h +++ b/src/protos/stivale.h @@ -3,9 +3,11 @@ #include #include +#include void stivale_load(char *cmdline, int boot_drive); __attribute__((noreturn)) void stivale_spinup(int bits, bool level5pg, - uint64_t entry_point, void *stivale_struct, uint64_t stack); + uint64_t entry_point, void *stivale_struct, uint64_t stack, + struct e820_entry_t *memmap, size_t memmap_entries); #endif diff --git a/src/protos/stivale2.c b/src/protos/stivale2.c index 36c62adc..3c56edac 100644 --- a/src/protos/stivale2.c +++ b/src/protos/stivale2.c @@ -387,6 +387,9 @@ void stivale2_load(char *cmdline, int boot_drive) { } } + size_t memmap_entries; + struct e820_entry_t *memmap; + ////////////////////////////////////////////// // Create memmap struct tag ////////////////////////////////////////////// @@ -394,8 +397,7 @@ void stivale2_load(char *cmdline, int boot_drive) { struct stivale2_struct_tag_memmap *tag = balloc(sizeof(struct stivale2_struct_tag_memmap)); tag->tag.identifier = STIVALE2_STRUCT_TAG_MEMMAP_ID; - size_t memmap_entries; - struct e820_entry_t *memmap = get_memmap(&memmap_entries); + memmap = get_memmap(&memmap_entries); tag->entries = (uint64_t)memmap_entries; @@ -409,5 +411,6 @@ void stivale2_load(char *cmdline, int boot_drive) { bool level5pg_requested = get_tag(&stivale2_hdr, STIVALE2_HDR_TAG_5LV_PAGING_ID) ? true : false; stivale_spinup(bits, level5pg && level5pg_requested, - entry_point, &stivale2_struct, stivale2_hdr.stack); + entry_point, &stivale2_struct, stivale2_hdr.stack, + memmap, memmap_entries); }