diff options
Diffstat (limited to 'OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.asm')
-rw-r--r-- | OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.asm | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.asm b/OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.asm index ed53321..4df9c72 100644 --- a/OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.asm +++ b/OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.asm @@ -24,10 +24,47 @@ ;------------------------------------------------------------------------------
JumpToKernel PROC
- mov rsi, rdx
- add rcx, 200h
- call rcx
- ret
+ ; 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
+ push 10h
+ lea rax, @F
+ push rax
+ DB 048h, 0cbh ; retfq
+
+@@:
+ ; Now in compatibility mode.
+
+ DB 0b8h, 018h, 000h, 000h, 000h ; movl $0x18, %eax
+ DB 08eh, 0d8h ; movl %eax, %ds
+ DB 08eh, 0c0h ; movl %eax, %es
+ DB 08eh, 0e0h ; movl %eax, %fs
+ DB 08eh, 0e8h ; movl %eax, %gs
+ DB 08eh, 0d0h ; movl %eax, %ss
+
+ ; Disable paging
+ DB 00fh, 020h, 0c0h ; movl %cr0, %eax
+ DB 00fh, 0bah, 0f8h, 01fh ; btcl $31, %eax
+ DB 00fh, 022h, 0c0h ; movl %eax, %cr0
+
+ ; Disable long mode in EFER
+ DB 0b9h, 080h, 000h, 000h, 0c0h ; movl $0x0c0000080, %ecx
+ DB 00fh, 032h ; rdmsr
+ DB 00fh, 0bah, 0f8h, 008h ; btcl $8, %eax
+ DB 00fh, 030h ; wrmsr
+
+ ; Disable PAE
+ DB 00fh, 020h, 0e0h ; movl %cr4, %eax
+ DB 00fh, 0bah, 0f8h, 005h ; btcl $5, %eax
+ DB 00fh, 022h, 0e0h ; movl %eax, %cr4
+
+ DB 031h, 0edh ; xor %ebp, %ebp
+ DB 031h, 0ffh ; xor %edi, %edi
+ DB 031h, 0dbh ; xor %ebx, %ebx
+ DB 0c3h ; ret
JumpToKernel ENDP
|