summaryrefslogtreecommitdiff
path: root/boot/arch
diff options
context:
space:
mode:
authorChloe M. <chloe@aptel.org>2026-08-20 06:55:41 +0000
committerChloe M. <chloe@aptel.org>2026-08-20 07:08:43 +0000
commitc8bbd2e9eeecdd1160f0da7c2620c4b718eca915 (patch)
treea6ba9af1f463d94595d73c3326cf3ce1adc1988d /boot/arch
parent57f2ee84a8bbfe26ed880d03aa9ca96566e6b8f3 (diff)
boot/amd64: mbr: Relocate self to 0x7A00
Signed-off-by: Chloe M. <chloe@aptel.org>
Diffstat (limited to 'boot/arch')
-rw-r--r--boot/arch/amd64/mbr/mbr.S29
1 files changed, 24 insertions, 5 deletions
diff --git a/boot/arch/amd64/mbr/mbr.S b/boot/arch/amd64/mbr/mbr.S
index 236f9f1..4c8c993 100644
--- a/boot/arch/amd64/mbr/mbr.S
+++ b/boot/arch/amd64/mbr/mbr.S
@@ -1,19 +1,38 @@
/* Segment constants */
-#define BOOT_SEG 0x7C0 /* Segment we reside on startup */
+#define BOOT_SEG 0x7C0 /* Segment we reside on startup */
+#define BOOT_RELOC_SEG 0x7A0 /* Relocation segment */
.code16
_start:
/* Normalize CS + other selectors */
ljmp $BOOT_SEG,$1f
1: xor %ax, %ax
- mov %ax, %ds
mov %ax, %ss
- mov %ax, %es
mov %ax, %gs
mov %ax, %fs
-2: cli
+
+ /*
+ * The second stage bootloader expects to be loaded to 0x7C00 but since we are
+ * already executing at this address we'll need to relocate ourselves first before
+ * we clobber it.
+ */
+ mov $BOOT_SEG, %ax
+ mov %ax, %ds
+ mov $BOOT_RELOC_SEG, %ax
+ mov %ax, %es
+ xor %si, %si
+ xor %di, %di
+ mov $0x200, %cx
+ cld
+ rep movsb
+
+ /* Jump to our relocated self */
+ ljmp $BOOT_RELOC_SEG,$reloc
+
+reloc:
+ cli
hlt
- jmp 2b
+ jmp reloc
.org 510
.byte 0x55