Print this page
Rearrange multiboot2_entry.S so all data is first, code64 is second, code32 is third. (No more dual code64 sections.)
Use `iretq` method of jumping to 32-bit so VirtualBox (and maybe QEMU/KVM too?)
can cope and not get its `ljmp <mem48>` emulation bug(s) tickled.
@@ -1,9 +1,9 @@
/*
* Parts copyright Michael Brown <mbrown@fensystems.co.uk>
*
- * Copyright (c) 2019, Joyent, Inc.
+ * Copyright 2020 Joyent, Inc.
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
/* CR0: protection enabled */
@@ -28,11 +28,46 @@
#if defined(PXE_EFI) && defined(__x86_64__)
.section ".text", "ax", @progbits
+ .data
+
+entry_gdt:
+ /* null entry */
+ .word 0x0, 0x0
+ .byte 0x0, 0x0, 0x0, 0x0
+
+ /* 32 bit protected mode code segment */
+ .word 0xffff, 0x0
+ .byte 0x0, 0x9f, 0xcf, 0x0
+
+ /* 32 bit protected mode data segment */
+ .word 0xffff, 0x0
+ .byte 0x0, 0x93, 0xcf, 0x0
+
+entry_gdt_end:
+ .equ entry_gdt_length, entry_gdt_end - entry_gdt
+
+entry_gdtr:
+ .word entry_gdt_length - 1
+entry_gdt_base:
+ .quad 0
+
/*
+ * %rdi -> struct mb2 *
+ * %rsi -> stack pointer to switch to
+ * %rdx -> &multiboot2_enter_kernel
+ */
+ .code64
+ .globl multiboot2_bounce
+
+multiboot2_bounce:
+ movq %rsi, %rsp
+ jmp *%rdx
+
+ /*
* %rdi -> multiboot2 magic
* %rsi -> multiboot info pointer
* %rdx -> entry address (32 bits)
*
*
@@ -42,11 +77,10 @@
* off, and
*
* %eax -> multiboot2 magic
* %ebx -> multiboot info pointer (physical)
*/
- .align 16
.globl multiboot2_entry
multiboot2_entry:
cli
@@ -60,12 +94,20 @@
leaq entry_gdtr(%rip), %rax
lgdt (%rax)
/* Load our new %cs. */
- ljmp *newcs_vector
+ movq %rsp, %rax
+ pushq $GDTSEL_DATA
+ pushq %rax
+ pushf
+ pushq $GDTSEL_CODE
+ lea newcs(%rip), %rax
+ pushq %rax
+ iretq
+
.code32
newcs:
movw $GDTSEL_DATA, %ax
movw %ax, %ds
@@ -91,47 +133,6 @@
/* %ebx still has our infop */
movl %edi, %eax
jmp *%esi
- /*
- * %rdi -> struct mb2 *
- * %rsi -> stack pointer to switch to
- * %rdx -> &multiboot2_enter_kernel
- */
- .align 16
- .code64
- .globl multiboot2_bounce
-
-multiboot2_bounce:
- movq %rsi, %rsp
- jmp *%rdx
-
- .data
-
-newcs_vector:
- .long newcs, GDTSEL_CODE
-
- .align 16
-entry_gdt:
- /* null entry */
- .word 0x0, 0x0
- .byte 0x0, 0x0, 0x0, 0x0
-
- /* 32 bit protected mode code segment */
- .word 0xffff, 0x0
- .byte 0x0, 0x9f, 0xcf, 0x0
-
- /* 32 bit protected mode data segment */
- .word 0xffff, 0x0
- .byte 0x0, 0x93, 0xcf, 0x0
-
-entry_gdt_end:
- .equ entry_gdt_length, entry_gdt_end - entry_gdt
-
- .align 16
-entry_gdtr:
- .word entry_gdt_length - 1
-entry_gdt_base:
- .quad 0
-
#endif /* PXE_EFI && __x86_64__ */