summaryrefslogtreecommitdiff
path: root/boot/arch/amd64/mbr/mbr.S
diff options
context:
space:
mode:
Diffstat (limited to 'boot/arch/amd64/mbr/mbr.S')
-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