前面提到了 Main.asm 中的 Main16 最后会跳转到 SecEntry.nasm 中,这次用实验来证明这一点。
在Main.asm跳转代码如下,前面找到的地址放在 rsi 中,然后直接跳转到该地址:
BITS 64
;
; Some values were calculated in 32-bit mode. Make sure the upper
; 32-bits of 64-bit registers are zero for these values.
;
mov rax, 0x00000000ffffffff
and rsi, rax
and rbp, rax
and rsp, rax
;
; RSI - SEC Core entry point
; RBP - Start of BFV
;
;
; Restore initial EAX value into the RAX register
;
mov rax, rsp
;
; Jump to the 64-bit SEC entry point
;
jmp rsi
这里加入代码,从0x402 Port输出 rsi的值:
;
; Restore initial EAX value into the RAX register
;
mov rax, rsp
mov rax,rsi
mov dx,0x402
; 7-0 Bits
out dx,al
; 15-8 Bits
shr rax,8
out dx,al
; 23-16 Bits
shr rax,8
out dx,al
; 31-24 Bits
shr rax,8
out dx,al
; 39-32 Bits
shr rax,8
out dx,al
; 47-40 Bits
shr rax,8
out dx,al
; 55-48 Bits
shr rax,8
out dx,al
; 63-56 Bits
shr rax,8
out dx,al
接下来在SecEntry.nasm添加代码,输出当前 rip 的值:
;
; SecCore Entry Point
;
; Processor is in flat protected mode
;
; @param[in] RAX Initial value of the EAX register (BIST: Built-in Self Test)
; @param[in] DI 'BP': boot-strap processor, or 'AP': application processor
; @param[in] RBP Pointer to the start of the Boot Firmware Volume
; @param[in] DS Selector allowing flat access to all addresses
; @param[in] ES Selector allowing flat access to all addresses
; @param[in] FS Selector allowing flat access to all addresses
; @param[in] GS Selector allowing flat access to all addresses
; @param[in] SS Selector allowing flat access to all addresses
;
; @return None This routine does not return
;
global ASM_PFX(_ModuleEntryPoint)
ASM_PFX(_ModuleEntryPoint):
lea rax,[$]
mov dx,0x402
; 7-0 Bits
out dx,al
; 15-8 Bits
shr rax,8
out dx,al
; 23-16 Bits
shr rax,8
out dx,al
; 31-24 Bits
shr rax,8
out dx,al
; 39-32 Bits
shr rax,8
out dx,al
; 47-40 Bits
shr rax,8
out dx,al
; 55-48 Bits
shr rax,8
out dx,al
; 63-56 Bits
shr rax,8
out dx,al
;
; Fill the temporary RAM with the initial stack value.
; The loop below will seed the heap as well, but that's harmless.
;
mov rax, (FixedPcdGet32 (PcdInitValueInTempStack) << 32) | FixedPcdGet32 (PcdInitValueInTempStack)
; qword to store
mov rdi, FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) ; base address,
; relative to
; ES
mov rcx, FixedPcdGet32 (PcdOvmfSecPeiTempRamSize) / 8 ; qword count
cld ; store from base
; up
rep stosq
在 QEMU 上运行后,用十六进制工具查看 debug.log:
可以看到输出的 0xFFFC C374, 这样可以证明跳转到 SecEntry.nasm 继续执行的。