2012-11-02 19:27:55 +01:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
;
|
2013-01-16 07:50:08 +01:00
|
|
|
; Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
|
2012-11-02 19:27:55 +01:00
|
|
|
;
|
2019-04-04 01:06:33 +02:00
|
|
|
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
2012-11-02 19:27:55 +01:00
|
|
|
;
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
|
2014-10-31 21:54:31 +01:00
|
|
|
DEFAULT REL
|
|
|
|
SECTION .text
|
2012-11-02 19:27:55 +01:00
|
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; VOID
|
|
|
|
; EFIAPI
|
|
|
|
; JumpToKernel (
|
|
|
|
; VOID *KernelStart, // rcx
|
|
|
|
; VOID *KernelBootParams // rdx
|
|
|
|
; );
|
|
|
|
;------------------------------------------------------------------------------
|
2014-10-31 21:54:31 +01:00
|
|
|
global ASM_PFX(JumpToKernel)
|
|
|
|
ASM_PFX(JumpToKernel):
|
2012-11-02 19:27:55 +01:00
|
|
|
|
OvmfPkg: LoadLinuxLib: Fix kernel entry for 64-bit OVMF
We currently just jump to offset 0x200 in the kernel image, in 64-bit
mode. This is completely broken. If it's a 32-bit kernel, we'll be
jumping into the compressed data payload.
If it's a 64-bit kernel, it'll work... but the 0x200 offset is
explicitly marked as 'may change in the future', has already changed
from 0x100 to 0x200 in the past with no fanfare, and bootloaders are
instructed that they should look at the ELF header to find the offset.
So although it does actually work today, it's still broken in the
"someone needs to whipped for doing it this way" sense of the word.
In fact, the same bug exists in other bootloaders so the 0x200 offset
probably *is* now set in stone. But still it's only valid to use it if
we *know* it's a 64-bit kernel. And we don't. There *is* no ELF header
that we can look at when we're booting a bzImage, and we can't rely on
it having a PE/COFF header either.
The 32-bit entry point is always guaranteed to work, and we need to
support it anyway. So let's just *always* use it, in 32-bit mode, and
then we don't have to make up some horrible heuristics for detecting
32-bit vs. 64-bit kernels.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14045 6f19259b-4bc3-4df7-8a09-765794883524
2013-01-14 04:10:57 +01:00
|
|
|
; Set up for executing kernel. BP in %esi, entry point on the stack
|
|
|
|
; (64-bit when the 'ret' will use it as 32-bit, but we're little-endian)
|
|
|
|
mov rsi, rdx
|
|
|
|
push rcx
|
|
|
|
|
|
|
|
; Jump into the compatibility mode CS
|
2014-10-31 21:54:31 +01:00
|
|
|
push 0x10
|
|
|
|
lea rax, [.0]
|
OvmfPkg: LoadLinuxLib: Fix kernel entry for 64-bit OVMF
We currently just jump to offset 0x200 in the kernel image, in 64-bit
mode. This is completely broken. If it's a 32-bit kernel, we'll be
jumping into the compressed data payload.
If it's a 64-bit kernel, it'll work... but the 0x200 offset is
explicitly marked as 'may change in the future', has already changed
from 0x100 to 0x200 in the past with no fanfare, and bootloaders are
instructed that they should look at the ELF header to find the offset.
So although it does actually work today, it's still broken in the
"someone needs to whipped for doing it this way" sense of the word.
In fact, the same bug exists in other bootloaders so the 0x200 offset
probably *is* now set in stone. But still it's only valid to use it if
we *know* it's a 64-bit kernel. And we don't. There *is* no ELF header
that we can look at when we're booting a bzImage, and we can't rely on
it having a PE/COFF header either.
The 32-bit entry point is always guaranteed to work, and we need to
support it anyway. So let's just *always* use it, in 32-bit mode, and
then we don't have to make up some horrible heuristics for detecting
32-bit vs. 64-bit kernels.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14045 6f19259b-4bc3-4df7-8a09-765794883524
2013-01-14 04:10:57 +01:00
|
|
|
push rax
|
2014-10-31 21:54:31 +01:00
|
|
|
DB 0x48, 0xcb ; retfq
|
OvmfPkg: LoadLinuxLib: Fix kernel entry for 64-bit OVMF
We currently just jump to offset 0x200 in the kernel image, in 64-bit
mode. This is completely broken. If it's a 32-bit kernel, we'll be
jumping into the compressed data payload.
If it's a 64-bit kernel, it'll work... but the 0x200 offset is
explicitly marked as 'may change in the future', has already changed
from 0x100 to 0x200 in the past with no fanfare, and bootloaders are
instructed that they should look at the ELF header to find the offset.
So although it does actually work today, it's still broken in the
"someone needs to whipped for doing it this way" sense of the word.
In fact, the same bug exists in other bootloaders so the 0x200 offset
probably *is* now set in stone. But still it's only valid to use it if
we *know* it's a 64-bit kernel. And we don't. There *is* no ELF header
that we can look at when we're booting a bzImage, and we can't rely on
it having a PE/COFF header either.
The 32-bit entry point is always guaranteed to work, and we need to
support it anyway. So let's just *always* use it, in 32-bit mode, and
then we don't have to make up some horrible heuristics for detecting
32-bit vs. 64-bit kernels.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14045 6f19259b-4bc3-4df7-8a09-765794883524
2013-01-14 04:10:57 +01:00
|
|
|
|
2014-10-31 21:54:31 +01:00
|
|
|
.0:
|
OvmfPkg: LoadLinuxLib: Fix kernel entry for 64-bit OVMF
We currently just jump to offset 0x200 in the kernel image, in 64-bit
mode. This is completely broken. If it's a 32-bit kernel, we'll be
jumping into the compressed data payload.
If it's a 64-bit kernel, it'll work... but the 0x200 offset is
explicitly marked as 'may change in the future', has already changed
from 0x100 to 0x200 in the past with no fanfare, and bootloaders are
instructed that they should look at the ELF header to find the offset.
So although it does actually work today, it's still broken in the
"someone needs to whipped for doing it this way" sense of the word.
In fact, the same bug exists in other bootloaders so the 0x200 offset
probably *is* now set in stone. But still it's only valid to use it if
we *know* it's a 64-bit kernel. And we don't. There *is* no ELF header
that we can look at when we're booting a bzImage, and we can't rely on
it having a PE/COFF header either.
The 32-bit entry point is always guaranteed to work, and we need to
support it anyway. So let's just *always* use it, in 32-bit mode, and
then we don't have to make up some horrible heuristics for detecting
32-bit vs. 64-bit kernels.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14045 6f19259b-4bc3-4df7-8a09-765794883524
2013-01-14 04:10:57 +01:00
|
|
|
; Now in compatibility mode.
|
|
|
|
|
2014-10-31 21:54:31 +01:00
|
|
|
DB 0xb8, 0x18, 0x0, 0x0, 0x0 ; movl $0x18, %eax
|
|
|
|
DB 0x8e, 0xd8 ; movl %eax, %ds
|
|
|
|
DB 0x8e, 0xc0 ; movl %eax, %es
|
|
|
|
DB 0x8e, 0xe0 ; movl %eax, %fs
|
|
|
|
DB 0x8e, 0xe8 ; movl %eax, %gs
|
|
|
|
DB 0x8e, 0xd0 ; movl %eax, %ss
|
OvmfPkg: LoadLinuxLib: Fix kernel entry for 64-bit OVMF
We currently just jump to offset 0x200 in the kernel image, in 64-bit
mode. This is completely broken. If it's a 32-bit kernel, we'll be
jumping into the compressed data payload.
If it's a 64-bit kernel, it'll work... but the 0x200 offset is
explicitly marked as 'may change in the future', has already changed
from 0x100 to 0x200 in the past with no fanfare, and bootloaders are
instructed that they should look at the ELF header to find the offset.
So although it does actually work today, it's still broken in the
"someone needs to whipped for doing it this way" sense of the word.
In fact, the same bug exists in other bootloaders so the 0x200 offset
probably *is* now set in stone. But still it's only valid to use it if
we *know* it's a 64-bit kernel. And we don't. There *is* no ELF header
that we can look at when we're booting a bzImage, and we can't rely on
it having a PE/COFF header either.
The 32-bit entry point is always guaranteed to work, and we need to
support it anyway. So let's just *always* use it, in 32-bit mode, and
then we don't have to make up some horrible heuristics for detecting
32-bit vs. 64-bit kernels.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14045 6f19259b-4bc3-4df7-8a09-765794883524
2013-01-14 04:10:57 +01:00
|
|
|
|
|
|
|
; Disable paging
|
2014-10-31 21:54:31 +01:00
|
|
|
DB 0xf, 0x20, 0xc0 ; movl %cr0, %eax
|
|
|
|
DB 0xf, 0xba, 0xf8, 0x1f ; btcl $31, %eax
|
|
|
|
DB 0xf, 0x22, 0xc0 ; movl %eax, %cr0
|
OvmfPkg: LoadLinuxLib: Fix kernel entry for 64-bit OVMF
We currently just jump to offset 0x200 in the kernel image, in 64-bit
mode. This is completely broken. If it's a 32-bit kernel, we'll be
jumping into the compressed data payload.
If it's a 64-bit kernel, it'll work... but the 0x200 offset is
explicitly marked as 'may change in the future', has already changed
from 0x100 to 0x200 in the past with no fanfare, and bootloaders are
instructed that they should look at the ELF header to find the offset.
So although it does actually work today, it's still broken in the
"someone needs to whipped for doing it this way" sense of the word.
In fact, the same bug exists in other bootloaders so the 0x200 offset
probably *is* now set in stone. But still it's only valid to use it if
we *know* it's a 64-bit kernel. And we don't. There *is* no ELF header
that we can look at when we're booting a bzImage, and we can't rely on
it having a PE/COFF header either.
The 32-bit entry point is always guaranteed to work, and we need to
support it anyway. So let's just *always* use it, in 32-bit mode, and
then we don't have to make up some horrible heuristics for detecting
32-bit vs. 64-bit kernels.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14045 6f19259b-4bc3-4df7-8a09-765794883524
2013-01-14 04:10:57 +01:00
|
|
|
|
|
|
|
; Disable long mode in EFER
|
2014-10-31 21:54:31 +01:00
|
|
|
DB 0xb9, 0x80, 0x0, 0x0, 0xc0 ; movl $0x0c0000080, %ecx
|
|
|
|
DB 0xf, 0x32 ; rdmsr
|
|
|
|
DB 0xf, 0xba, 0xf8, 0x8 ; btcl $8, %eax
|
|
|
|
DB 0xf, 0x30 ; wrmsr
|
OvmfPkg: LoadLinuxLib: Fix kernel entry for 64-bit OVMF
We currently just jump to offset 0x200 in the kernel image, in 64-bit
mode. This is completely broken. If it's a 32-bit kernel, we'll be
jumping into the compressed data payload.
If it's a 64-bit kernel, it'll work... but the 0x200 offset is
explicitly marked as 'may change in the future', has already changed
from 0x100 to 0x200 in the past with no fanfare, and bootloaders are
instructed that they should look at the ELF header to find the offset.
So although it does actually work today, it's still broken in the
"someone needs to whipped for doing it this way" sense of the word.
In fact, the same bug exists in other bootloaders so the 0x200 offset
probably *is* now set in stone. But still it's only valid to use it if
we *know* it's a 64-bit kernel. And we don't. There *is* no ELF header
that we can look at when we're booting a bzImage, and we can't rely on
it having a PE/COFF header either.
The 32-bit entry point is always guaranteed to work, and we need to
support it anyway. So let's just *always* use it, in 32-bit mode, and
then we don't have to make up some horrible heuristics for detecting
32-bit vs. 64-bit kernels.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14045 6f19259b-4bc3-4df7-8a09-765794883524
2013-01-14 04:10:57 +01:00
|
|
|
|
|
|
|
; Disable PAE
|
2014-10-31 21:54:31 +01:00
|
|
|
DB 0xf, 0x20, 0xe0 ; movl %cr4, %eax
|
|
|
|
DB 0xf, 0xba, 0xf8, 0x5 ; btcl $5, %eax
|
|
|
|
DB 0xf, 0x22, 0xe0 ; movl %eax, %cr4
|
OvmfPkg: LoadLinuxLib: Fix kernel entry for 64-bit OVMF
We currently just jump to offset 0x200 in the kernel image, in 64-bit
mode. This is completely broken. If it's a 32-bit kernel, we'll be
jumping into the compressed data payload.
If it's a 64-bit kernel, it'll work... but the 0x200 offset is
explicitly marked as 'may change in the future', has already changed
from 0x100 to 0x200 in the past with no fanfare, and bootloaders are
instructed that they should look at the ELF header to find the offset.
So although it does actually work today, it's still broken in the
"someone needs to whipped for doing it this way" sense of the word.
In fact, the same bug exists in other bootloaders so the 0x200 offset
probably *is* now set in stone. But still it's only valid to use it if
we *know* it's a 64-bit kernel. And we don't. There *is* no ELF header
that we can look at when we're booting a bzImage, and we can't rely on
it having a PE/COFF header either.
The 32-bit entry point is always guaranteed to work, and we need to
support it anyway. So let's just *always* use it, in 32-bit mode, and
then we don't have to make up some horrible heuristics for detecting
32-bit vs. 64-bit kernels.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14045 6f19259b-4bc3-4df7-8a09-765794883524
2013-01-14 04:10:57 +01:00
|
|
|
|
2014-10-31 21:54:31 +01:00
|
|
|
DB 0x31, 0xed ; xor %ebp, %ebp
|
|
|
|
DB 0x31, 0xff ; xor %edi, %edi
|
|
|
|
DB 0x31, 0xdb ; xor %ebx, %ebx
|
|
|
|
DB 0xc3 ; ret
|
2012-11-02 19:27:55 +01:00
|
|
|
|
2013-02-14 20:21:39 +01:00
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
; VOID
|
|
|
|
; EFIAPI
|
|
|
|
; JumpToUefiKernel (
|
|
|
|
; EFI_HANDLE ImageHandle, // rcx
|
|
|
|
; EFI_SYSTEM_TABLE *SystemTable, // rdx
|
|
|
|
; VOID *KernelBootParams // r8
|
|
|
|
; VOID *KernelStart, // r9
|
|
|
|
; );
|
|
|
|
;------------------------------------------------------------------------------
|
2014-10-31 21:54:31 +01:00
|
|
|
global ASM_PFX(JumpToUefiKernel)
|
|
|
|
ASM_PFX(JumpToUefiKernel):
|
2013-02-14 20:21:39 +01:00
|
|
|
|
|
|
|
mov rdi, rcx
|
|
|
|
mov rsi, rdx
|
|
|
|
mov rdx, r8
|
|
|
|
xor rax, rax
|
2014-10-31 21:54:31 +01:00
|
|
|
mov eax, [r8 + 0x264]
|
2013-02-14 20:21:39 +01:00
|
|
|
add r9, rax
|
2014-10-31 21:54:31 +01:00
|
|
|
add r9, 0x200
|
2013-02-14 20:21:39 +01:00
|
|
|
call r9
|
|
|
|
ret
|
|
|
|
|