On Tue, 2013-01-08 at 09:41 +0000, David Woodhouse wrote:
> Note that OVMF is already broken for the case of booting a 32-bit kernel
> from 64-bit firmware, even for the legacy handover case which *ought* to
> work. We need to switch back into 32-bit mode before jumping to the
> 32-bit entry point. Rather than just jumping to the non-existent 64-bit
> entry point in a 32-bit kernel. I haven't addressed that here.

It turns out that it's fairly much impossible for the bootloader to tell
whether the 64-bit entry point at 0x200 actually exists. In theory I've
been told that you can look at the ELF payload of the bzImage payload
and its ELF class and the entry point in its headers. But that would
involve decompressing it first. With the compression method du jour of
the kernel. As far as I can tell, the 64-bit entry point (at the
undocumented offset 0x200) is completely unusable when booting a
bzImage. Vivek?

So let's *unconditionally* switch back to 32-bit mode and jump to the
32-bit entry point which *is* guaranteed to work, like grub does...

Does this look sane? It would need translating for JumpToKernel.asm.
And it's assuming that both kernel and bootparams are below 4GiB.

diff -u b/edk2/OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.S 
b/edk2/OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.S
--- b/edk2/OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.S
+++ b/edk2/OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.S
@@ -25,9 +25,39 @@
 #------------------------------------------------------------------------------
 ASM_PFX(JumpToKernel):
     movq    %rdx, %rsi
-    addq    $0x200, %rcx
-    callq   %rcx
-    ret
+    movq    %rcx, %rbx
+    movq    $0x10, %rax
+    shl     $32, %rax
+    orq     $1f, %rax
+    pushq   %rax
+    retf
+1:     // Now in compatibility mode
+.code32
+    movl    $0x18, %eax
+    movl    %eax, %ds
+    movl    %eax, %es
+    movl    %eax, %fs
+    movl    %eax, %gs
+    movl    %eax, %ss
+
+    // Disable paging
+    movl    %cr0, %eax
+    btcl    $31, %eax
+    movl    %eax, %cr0
+
+    // Disable long mode in EFER
+    movl    $0x0c0000080, %ecx
+    rdmsr
+    btcl    $8, %eax
+    wrmsr
+
+    // Disable PAE
+    movl    %cr0, %eax
+    btcl    $5, %eax
+    movl    %eax, %cr0
+
+    jmp     %ebx
+.code64
 
 #------------------------------------------------------------------------------
 # VOID
--- a/edk2/OvmfPkg/Library/LoadLinuxLib/LinuxGdt.c
+++ b/edk2/OvmfPkg/Library/LoadLinuxLib/LinuxGdt.c
@@ -83,7 +83,11 @@ STATIC GDT_ENTRIES GdtTemplate = {
     0x0,            // base 0
     0x0,
     0x09A,          // present, ring 0, data, expand-up, writable
+#ifdef MDE_CPU_IA32
     0x0CF,          // page-granular, 32-bit
+#else
+    0x0AF,          // compatibility mode
+#endif
     0x0,
   },
   //


-- 
dwmw2

Attachment: smime.p7s
Description: S/MIME cryptographic signature

------------------------------------------------------------------------------
Master SQL Server Development, Administration, T-SQL, SSAS, SSIS, SSRS
and more. Get SQL Server skills now (including 2012) with LearnDevNow -
200+ hours of step-by-step video tutorials by Microsoft MVPs and experts.
SALE $99.99 this month only - learn more at:
http://p.sf.net/sfu/learnmore_122512
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to