UEFI才整理一半, 發現本身PI因某原因, 必須要先看, 於是就轉到PI看起
以紀錄自己整理的心得與筆記為主,
若有不妥的敘述或了解, 還請不吝提出建議.
--------------------------------
在整個PI, 或是整個開機流程(Boot flow)中, 最先開始的就是SEC Phase.
1. 介紹:
在platform reset之後或是power-on之後開始執行, 確保韌體整合上是完整的.
SEC具有平台及處理器架構依賴性 (Mobile 或是 PC, 不同處理器, 組合語言的寫法也會有所不同)
儘管UEFI是以C語言來編寫, 但與底層硬體溝通, 還是需要組合語言
所以在SEC phase時, 大多都是以組合語言來編寫的
在初期開機階段, 資源都是很有限的, 所以在這邊盡可能需要最小化的code
因此開機速度快慢取決於處理器所能提供的資源而定 (Cache as RAM, 後面會提到)
(但因為SEC為最初階段, 當然應用在不同平台上速度有差, 但大多都是在1.xx秒, 或是0.xx秒在跑的) *1
2. 特點:
不管在哪一個有介紹到SEC的Spec中, 提到SEC的主要功能不外乎負責:
處理所有restart event.
建立一個暫時的記憶體空間
做為系統的root of trust
將handoff information交給PEI Foundation. (也是把控制權轉交到PEI Foundation)
1. Handling All Platform Restart Events
Applying power to the system from an unpowered state
Restarting the system from an active state
Receiving various exception conditions
上述三點就是剛開機, 重開機, 以及其他例外狀況
這些restart事件, 由SEC phase這個單位負責收集任何狀況資訊
讓部分PEIM可以根據這些不同的restart, 追溯處理器的health為何.
2. Creating a Temporary Memory Store
在初始階段並沒有記憶體能使用,
Pre-RAM code負責將CPU初始化, 在CPU cache裡建立個臨時的stack(堆疊)
將處理器的快取作為記憶體(Cache as RAM)
(真正將所有記憶體初始化完畢是在PEI phase尾端後)
(以x86處理器為例, 利用MTRRs來將cache設定成stack)
並且將快取設定成"no eviction mode"
所謂eviction(逐出, 收回)就是將cache的資料evicted into(註: 譯成"放進"較順)分配給cache用的實體RAM空間中
也就是存放到主記憶體裡, 於是cache就被"flushed"了(eviction), 可繼續作資料存取用, 來增加執行效率.
但在開機階段,
一來Cache的資料是必須用到的code, 而不是暫放轉存用的資料, 所以不能被evicted
二來主記憶體在此階段還沒有設定好, 若eviction則會造成平台錯誤.
因此設定no eviction mode, cache也因此沒有被"flushed"了(no eviction) *2
3. Serving As the Root of Trust in the System
SEC phase也作為系統的基礎, 在呼叫PEI Foundation之前, 驗證PEI Foundation.
4. Passing Handoff Information to the PEI Foundation
最後就是負責將handoff information交到PEI phase:
State of the platform
Location and size of the Boot Firmware Volume (BFV) (BFV指的是存放PEI Foundation的FV, 也可以放些PEIMs)
Location and size of the temporary RAM
Location and size of the stack
轉交的方式則是呼叫PEI Foundation的entry point, 同時也把控制權轉移出去
利用當中的定義的結構 EFI_SEC_PEI_HAND_OFF
把一些PPIs, BFV跟暫時記憶體的大小跟位置, PEI Foundation能使用的暫時記憶體的大小跟位置, 堆疊的大小跟位置等轉交到PEI Foundation
(見PI PEI Spec 5.2.1 相關定義, 有幾個是另用pointer指向過去.)
所謂的暫時記憶體(temporary RAM)可以是處理器的快取, SRAM, 或其他來源
這看平台上有何資源能使用, code決定要使用哪個資源. (在介紹中是以使用cache為例)
若大致再將Temporary RAM作區分, 則是分成Heap與Stack
(圖示參考EDK II module writer's guide 6.3.1)
3. 其他細節:
傳送Handoff information還能使用另一個optional的PPI, 稱作SEC_PLATFORM_INFORMATION_PPI
這個PPI則是存放在entry point中的另一個結構裡, 稱作EFI_PEI_PPI_DESCRIPTOR
(指向到PpiList, 這個清單列出一個或多個需要由PEI core初始安裝的PPI descriptors,
如果是空的則是有一個EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST的descriptor.
PEI Foundation會把這些SEC-hosted PPIs加到PPI database讓Foundation以及任何模組都能使用這些早期PPIs相關的service calls and/or code)
利用這個optional PPI則會abstracts(註: 翻"產生"比較好) platform-specific information, 讓PEI Foundation去找到從哪邊開始分派PEIMs.
這個PPI則存放到PPI list裡稱作EFI_PEI_STARTUP_DESCRIPTOR這個資料結構的final argument.
還有另一個flag, Health flag用來記錄由microcode, hardware, and/or Itanium處理器的PAL code產生的資訊, 關於reset後處理器的狀態.
這個EFI_HEALTH_FLAGS則定義在上述的PPI的function裡
在Itanium系統中, 在restarting過後Health flag從PAL-A傳出來給firmware(如PI).
這個資訊則與PI分開, 因為code是由不同vendors提供, PAL是由Intel所提供的, 而不同的OEMs則設計PI firmware.
這個flag, IA-32跟Itanium都有使用到, 不過只有Tested(Te)這個bit是一樣的, IA-32只有放built-in self-test (BIST)
然後沒有其他功能了
(若再進階了解, 還有四個1-bit的欄位 - Vm, Ia, Fp, Mf, 都是用來顯示該功能是否可用)
(而State是個2-bit的欄位, 在IA-32跟Itanium上格式定義都相同, 但有些bits在IA-32上並無實作, 故這些bits會顯示NULL)
(針對State值若是10 - Functionally Restricted, 則代表有些狀況達到, 見13.4.1)
4. 小結
最後總結兩個ISA處理器在SEC phase上的流程.
IA-32
定位PEI Foundation; 使用定義的handoff state傳送控制權; 初始化processor-controlled的記憶體資源,
像是processor data cache, 可以作為呼叫堆疊的記憶體線性延伸區(if supported)
在PEI Foundation前的步驟
Micorcode Startup and BIST -> IA-32 SEC Phase Processor Entry -> PEI Foundation
IPF
Itanium架構多在驗證PAL-A跟PAL-B code
processor的內部microcode從power-good reset開始找到第一層定位在BFV(使用pointer)的processor abstraction code(PAL-A)
確保PAL-A code layer沒有被竄改
接著驗證下一層.
Power Good -> Microcode Startup -> PAL-A Authenticate -> PAL-B Authenticate -> Framework SEC Phase Starts Up
5. 過程總結
參考Beyond BIOS pdf, 可以了解到整個SEC的細部過程.
1. Reset Vector
CPU上電後開始尋找ROM裡的第一條指令位置, 跳轉過去開始主要的初始化排程
也會先flush cache, 提供乾淨的初始狀態, 避免先前遺留在Cache裡的資料會產生問題.
2. Switch to Protect Mode
Protected Flath 32 bit mode.
3. Initialize MTRRs for BSP
初始化Memory Type Range Registers, 設定cache成需要使用的記憶體狀態.
4. Microcode Patch Update
執行所有現有CPUs的Microcode Path Update
5. Initialize No-Eviction Mode (NEM)
在平台記憶體初始化前(at end of PEI), 在CPU cache裡建立一data area
給初期初始化過程使用
6. Various Early BSP/AP Interactions
設定處理器內的初始化, Bootstrap Processocr, Application Processor
發送INIT interprocessor interrupt(IPI), Start-up IPI(SIPI)給所有APs
從APs收集BIST(Built-in Self Test)資料
7. Hand-off to PEI entry point.
這時候EFI_SEC_PEI_HAND_OFF這個資料結構完成之後, 即代表從組合語言轉向C語言執行環境的變換點
//SEC不是要Verify PEI Foundation嗎? 後續study後補上
-------------------------------------------------------------
*1
https://www-ssl.intel.com/content/www/us/en/architecture-and-technology/unified-extensible-firmware-interface/uefi-boot-time-optimization-windows7.html
(Page 17-19)
*2
http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=UEFI/PI_FAQ
(見中間的Q&A - How does No Evction Mode(NEM) work?)
(或見PI PEI Spec - 13.2.2)
參考來源:
http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=UEFI_EDKII_Learning_Dev
(See Lesson 1 - Course Introduction and Pre-EFI (PEI) and Security (SEC) Phases)
(內容是swf動畫檔, 下載Zip再解壓用瀏覽器開啟.swf檔, 會較快速)
http://blog.csdn.net/cstyle_0x007/article/details/9734551
( Cstyle的UEFI导读之SEC --- Reset Vector(上篇))
(介紹很詳細, 還有其下篇)
http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=PEI
(See Q - SEC phase完成甚麼, 以及BSP / AP的小問題)
Beyond BIOS
PEI Spec 1.3
留言列表