summaryrefslogtreecommitdiff
path: root/purgatory/arch/i386/entry32-16.S
diff options
context:
space:
mode:
Diffstat (limited to 'purgatory/arch/i386/entry32-16.S')
-rw-r--r--purgatory/arch/i386/entry32-16.S25
1 files changed, 15 insertions, 10 deletions
diff --git a/purgatory/arch/i386/entry32-16.S b/purgatory/arch/i386/entry32-16.S
index aaf1273..c051aab 100644
--- a/purgatory/arch/i386/entry32-16.S
+++ b/purgatory/arch/i386/entry32-16.S
@@ -24,15 +24,20 @@
.balign 16
entry16:
.code32
- /* Compute where I am running at */
- movl $entry16, %ebx
+ /* Compute where I am running at (assumes esp valid) */
+ call 1f
+1: popl %ebx
+ subl $(1b - entry16), %ebx
/* Fixup my real mode segment */
movl %ebx, %eax
shrl $4, %eax
- movw %ax, 2 + realptr
+ movw %ax, (2 + realptr - entry16)(%ebx)
/* Fixup the gdt */
+ leal (gdt - entry16)(%ebx), %eax
+ movl %eax, (0x02 + gdt - entry16)(%ebx)
+
movl %ebx, %eax
shll $16, %eax
@@ -44,17 +49,17 @@ entry16:
andl $0xff000000, %edx
orl %edx, %ecx
- orl %eax, 0x08 + gdt
- orl %ecx, 0x0c + gdt
- orl %eax, 0x10 + gdt
- orl %ecx, 0x14 + gdt
+ orl %eax, (0x08 + gdt - entry16)(%ebx)
+ orl %ecx, (0x0c + gdt - entry16)(%ebx)
+ orl %eax, (0x10 + gdt - entry16)(%ebx)
+ orl %ecx, (0x14 + gdt - entry16)(%ebx)
/* Setup the classic BIOS interrupt table at 0x0 */
- lidt idtptr
+ lidt (idtptr - entry16)(%ebx)
/* Provide us with 16bit segments that we can use */
- lgdt gdt
+ lgdt (gdt - entry16)(%ebx)
/* Note we don't disable the a20 line, (this shouldn't be required)
* The code to do it is in kexec_test and it is a real pain.
@@ -147,7 +152,7 @@ idtptr:
gdt:
/* 0x00 unusable segment so used as the gdt ptr */
.word gdt_end - gdt - 1
- .long gdt
+ .long 0 /* gdt */
.word 0
/* 0x08 16 bit real mode code segment */