summaryrefslogtreecommitdiff
path: root/i386
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2012-03-24 03:01:01 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2012-03-24 03:05:31 +0100
commitc74adfecd0b21ea84f7e98629549f7489c78edc9 (patch)
tree5680f6d3cc9436f2f7dfaecd67e6f483ecbda0db /i386
parent0ef8bca36fdf3c57c90c948a4894c4baf5e0c3fd (diff)
Relocate kernel at bootup
Grub is not able to map us at high addresses. We can however make it load us at low addresses (through the linker script mapping), then use segmentation to move ourselves to high addresses, and switch to C which uses high addresses (through _START definition). * i386/ldscript: Force mapping kernel at 0x100000, regardless of the value of _START. * i386/i386at/boothdr.S (boot_entry): Set up initial segments to project the bootstrap linear space to high addresses.
Diffstat (limited to 'i386')
-rw-r--r--i386/i386at/boothdr.S37
-rw-r--r--i386/ldscript1
2 files changed, 38 insertions, 0 deletions
diff --git a/i386/i386at/boothdr.S b/i386/i386at/boothdr.S
index 45cd599..567851e 100644
--- a/i386/i386at/boothdr.S
+++ b/i386/i386at/boothdr.S
@@ -39,6 +39,19 @@ boot_hdr:
#endif /* __ELF__ */
boot_entry:
+ /* use segmentation to offset ourself. */
+ lgdt boot_gdt_descr - KERNELBASE
+ ljmp $8,$0f
+0:
+ movw $0,%ax
+ movw %ax,%ds
+ movw %ax,%es
+ movw %ax,%fs
+ movw %ax,%gs
+ movw $16,%ax
+ movw %ax,%ds
+ movw %ax,%es
+ movw %ax,%ss
/* Switch to our own interrupt stack. */
movl $_intstack+INTSTACK_SIZE,%esp
@@ -80,3 +93,27 @@ iplt_done:
.comm _intstack,INTSTACK_SIZE
+.align 16
+ .word 0
+boot_gdt_descr:
+ .word 3*8+7
+ .long boot_gdt - KERNELBASE
+.align 16
+boot_gdt:
+ /* 0 */
+ .quad 0
+ /* boot CS = 8 */
+ .word 0xffff
+ .word (-KERNELBASE) & 0xffff
+ .byte ((-KERNELBASE) >> 16) & 0xff
+ .byte 0x9a
+ .byte 0xcf
+ .byte ((-KERNELBASE) >> 24) & 0xff
+ /* boot DS = 8 */
+ .word 0xffff
+ .word (-KERNELBASE) & 0xffff
+ .byte ((-KERNELBASE) >> 16) & 0xff
+ .byte 0x92
+ .byte 0xcf
+ .byte ((-KERNELBASE) >> 24) & 0xff
+
diff --git a/i386/ldscript b/i386/ldscript
index bbf5698..a63ff77 100644
--- a/i386/ldscript
+++ b/i386/ldscript
@@ -13,6 +13,7 @@ SECTIONS
*/
. = _START;
.text :
+ AT (0x00100000)
{
*(.text.start)
*(.text .stub .text.* .gnu.linkonce.t.*)