From 713a219304e4fab4b4fa48220515ee2d363dde53 Mon Sep 17 00:00:00 2001
From: Philipp Oppermann <dev@phil-opp.com>
Date: Fri, 27 Jan 2023 18:23:02 +0100
Subject: [PATCH] Map BIOS stage-4 at lower address to avoid conflicts with the
 kernel

Parts of stage-4 need to be identity-mapped. This can lead to 'page already mapped' errors when the kernel already occupies the virtual address corresponding to the physical address of the stage-4. For example, a typical virtual start address of the kernel is 2MiB. This was where we placed the stage-4 in physical memory before. This commit avoids that conflict by keeping the stage-4 below the 2MiB boundary.
---
 bios/stage-2/src/main.rs     | 9 ++++++---
 bios/stage-4/stage-4-link.ld | 3 ++-
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/bios/stage-2/src/main.rs b/bios/stage-2/src/main.rs
index 4e873699..d07957c8 100644
--- a/bios/stage-2/src/main.rs
+++ b/bios/stage-2/src/main.rs
@@ -24,9 +24,12 @@ mod vesa;
 /// We use this partition type to store the second bootloader stage;
 const BOOTLOADER_SECOND_STAGE_PARTITION_TYPE: u8 = 0x20;
 
-const STAGE_3_DST: *mut u8 = 0x0010_0000 as *mut u8; // 1MiB (typically 14MiB accessible here)
-const STAGE_4_DST: *mut u8 = 0x0020_0000 as *mut u8; // 2MiB (typically still 13MiB accessible here)
-const KERNEL_DST: *mut u8 = 0x0100_0000 as *mut u8; // 16MiB
+// 1MiB (typically 14MiB accessible here)
+const STAGE_3_DST: *mut u8 = 0x0010_0000 as *mut u8;
+// must match the start address in bios/stage-4/stage-4-link.ld
+const STAGE_4_DST: *mut u8 = 0x0013_0000 as *mut u8;
+// 16MiB
+const KERNEL_DST: *mut u8 = 0x0100_0000 as *mut u8;
 
 static mut DISK_BUFFER: AlignedArrayBuffer<0x4000> = AlignedArrayBuffer {
     buffer: [0; 0x4000],
diff --git a/bios/stage-4/stage-4-link.ld b/bios/stage-4/stage-4-link.ld
index 6977f2d3..ff513922 100644
--- a/bios/stage-4/stage-4-link.ld
+++ b/bios/stage-4/stage-4-link.ld
@@ -1,7 +1,8 @@
 ENTRY(_start)
 
 SECTIONS {
-    . = 0x00200000;
+    # must match STAGE_4_DST address in bios/stage-2/src/main.rs
+    . = 0x00130000;
 
     .start : {
         *(.start)