背景知識還是參考:[我所認識的BIOS]系列 -- CPU的第一條指令。工作的緣故,我能接觸到Intel Comet Lake RVP board,同時也有IBV提供的Reference Code,所以本文不過是基於原作者的文章實操一遍。
Step 0:
Reference Code生成的Master Rom大小爲32MB,下圖是Master Rom佈局(用UEFITool打開Master ROM),其中BIOS塊位於Master Rom的尾部:
展開BIOS region,其尾部顯示爲Sec Core,包含4塊Section一個TE Image section和3個Raw section
這4個Section都可以被提取(選中Item--右鍵--"Extract body"--save),特別的TE image被提取後可以被IDA識別(因爲TE image是精簡版的PE文件,至於從源文件生成BIOS binary的過程,我會另起一篇文章分析):
IDA部分輸出如下:
它和SecEntry.asm文件開頭部份的代碼幾乎一致(內容不便貼出)。
UEFI啓動的第一階段是SEC階段,SecEntry.asm文件名中雖然含有"SecEntry"字眼,但是它並不是開機執行的第一個Section,更談不上開機時執行的第一條指令。另外,Master Rom最後16字節(即物理地址0xFFFFFFF0)的OPCode形如"0x90 0x90 0xE9",然而前面截圖中OpCode不具備這樣的特徵:
所以可以斷定SecEntry.asm所在的Section不包含開機執行的第一條指令,所以我們要將目光轉移到同屬同一個FFS的其他Section。看看最後一個Raw Section,提取並用IDA加載試試:
然而,IDA並不能識別其中的指令流,沒辦法只能用16進制編輯器打開:
看看嘛,偏移0x30處有"0x90 0x90 0xE9"這樣的OPCode。其實raw.bin偏移0x30處正好對應物理地址0xFFFFFFF0。還沒完,Raw.bin雖然小,但仔細挖掘一下內容不少,先參考UDK中UefiCpuPkg\ResetVector\FixupVtf\Vtf.nasmb文件,這是UDK的ResetVector:
BITS 16
ALIGN 16 ; 0xffffffd0
applicationProcessorEntryPoint:
;
; Application Processors entry point
;
; GenFv generates code aligned on a 4k boundary which will jump to this
; location. (0xffffffd0) This allows the Local APIC Startup IPI to be
; used to wake up the application processors.
;
jmp short resetVector
ALIGN 16 ; 0xffffffe0
peiCoreEntryPoint:
;
; PEI Core entry point
;
; GenFv fills the address of the PEI Core into this location
;
DD 0x12345678
ALIGN 16 ; 0xfffffff0
resetVector:
;
; Reset Vector
;
; This is where the processor will begin execution
;
nop
nop
jmp near $
ALIGN 8
ApStartupSegment:
DD 0x12345678
BootFvBaseAddress:
DD 0x12345678
ALIGN 16 ; 0x100000000
這份文件是Raw.bin的源文件,根據註釋,在0xFFFFFFD0-0xFFFFFFFF之間爲下列(僞)結構體:
struct
{
BYTE jmpReset[8];
DWORD pad0;
DWORD peiCoreEntryPoint;
DWORD pad1;
BYTE resetVector[8] = {0x90,0x90,0xe9,0x??,0x??};
DWORD ApStartupSegment;
DWORD BootFvBaseAddress;
};
其中peiCoreEntryPoint,ApStartupSegment,BootFvBaseAddress是在Build Master ROM階段確定。(peiCoreEntryPoint/BootFvBaseAddress是兩個地址值,是不是能inline-hook一把?)。resetVector的jmp指令使得BIOS跳去執行(IBV)FSP初始化相關的代碼,也就是前面提到的SecEntry.asm中的代碼。