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__ */