UEFI系統的啓動過程

UEFI系統的啓動過程(1)

UEFI系統的啓動遵循UEFI平臺初始化(PlatformInitialization)標準。UEFI系統從加電到關機可分爲7個階段:

SEC(安全驗證)→PEI(EFI前期初始化)→DXE(驅動執行環境)

→BDS(啓動設備選擇)→TSL(操作系統加載前期)

→RT(Run Time)

→AL(系統災難恢復期)

圖1-2展示了UEFI系統從加電到關機的7個階段(以圖中豎線爲界)。

前三個階段是UEFI初始化階段,DXE階段結束後UEFI環境已經準備完畢。

BDS和TSL是操作系統加載器作爲UEFI應用程序運行的階段。

操作系統加載器調用ExitBootServices()服務後進入RT階段,RT階段包括操作系統加載器後期和操作系統運行期。

當系統硬件或操作系統出現嚴重錯誤不能繼續正常運行時,固件會嘗試修復錯誤,這時系統進入AL期。但PI規範和UEFI規範都沒有規定AL期的行爲。“?”號表示其行爲由系統供應商自行定義。


 

1.SEC階段

SEC(Security Phase)階段是平臺初始化的第一個階段,計算機系統加電後進入這個階段。

(1)SEC階段的功能

UEFI系統開機或重啓進入SEC階段,從功能上說,它執行以下4種任務。

1)接收並處理系統啓動和重啓信號:系統加電信號、系統重啓信號、系統運行過程中的嚴重異常信號。

2)初始化臨時存儲區域:系統運行在SEC階段時,僅CPU和CPU內部資源被初始化,各種外部設備和內存都沒有被初始化,因而系統需要一些臨時RAM區域,用於代碼和數據的存取,我們將之稱爲臨時RAM,以示與內存的區別。這些臨時RAM只能位於CPU內部。最常用的臨時RAM是Cache,當Cache被配置爲no-eviction模式時,可以作爲內存使用,讀命中時返回Cache中的數據,讀缺失時不會向主存發出缺失事件;寫命中時將數據寫入Cahce,寫缺失時不會向主存發出缺失事件,這種技術稱爲CAR(Cache As Ram)。

3)作爲可信系統的根:作爲取得對系統控制權的第一部分,SEC階段是整個可信系統的根。SEC能被系統信任,以後的各個階段纔有被信任的基礎。通常,SEC在將控制權轉移給PEI之前,可以驗證PEI。

4)傳遞系統參數給下一階段(即PEI):SEC階段的一切工作都是爲PEI階段做準備,最終SEC要把控制權轉交給PEI,同時要將現階段的成果彙報給PEI。彙報的手段就是將如下信息作爲參數傳遞給PEI的入口函數。

系統當前狀態,PEI可以根據這些狀態判斷系統的健康狀況。

可啓動固件(Boot Firmware Volume)的地址和大小。

臨時RAM區域的地址和大小。

棧的地址和大小。

(2)SEC階段執行流程

上面介紹了SEC的功能,下面再來看看SEC的執行流程,如圖1-3所示。

 

UEFI系統的啓動過程(2)

以臨時RAM初始化爲界,SEC的執行又分爲兩大部分:臨時RAM生效之前稱爲Reset Vector階段,臨時RAM生效後調用SEC入口函數從而進入SEC功能區。

其中Reset Vector的執行流程如下。

1)進入固件入口。

2)從實模式轉換到32位平坦模式(包含模式)。

3)定位固件中的BFV(Boot Firmware Volume)。

4)定位BFV中的SEC映像。

5)若是64位系統,從32位模式轉換到64位模式。

6)調用SEC入口函數。

下面的代碼描述了從固件入口Reset Vector到SEC入口函數的執行過程:

在Reset Vector部分,因爲系統還沒有RAM,因而不能使用基於棧的程序設計,所有的函數調用都使用jmp指令模擬。OneTimeCall是宏,用於模擬call指令。例如,宏調用OneTimeCall EarlyInit16,如圖1-4所示。

進入SEC功能區後,首先利用CAR技術初始化棧,初始化IDT,初始化EFI_SEC_PEI_HAND_OFF,將控制權轉交給PEI,並將EFI_SEC_PEI_HAND_OFF傳遞給PEI。

不同的硬件平臺,SEC代碼會有不同的實現方式,但大致執行過程相似。下面以OVMF(具體介紹參見第2章)爲例,介紹SEC功能區的執行過程。


UEFI系統的啓動過程(3)

2.PEI階段

PEI(Pre-EFI Initialization)階段資源仍然十分有限,內存到了PEI後期才被初始化,其主要功能是爲DXE準備執行環境,將需要傳遞到DXE的信息組成HOB(Handoff Block)列表,最終將控制權轉交到DXE手中。PEI執行流程如圖1-5所示。

從功能上講,PEI可分爲以下兩部分。

PEI 內核(PEI Foundation):負責PEI基礎服務和流程。

PEIM(PEI Module)派遣器:主要功能是找出系統中的所有PEIM,並根據PEIM之間的依賴關係按順序執行PEIM。PEI階段對系統的初始化主要是由PEIM完成的。

每個PEIM是一個獨立的模塊,模塊的入口函數類型定義如下所示:

typedef EFI_STATUS(EFIAPI *EFI_PEIM_ENTRY_POINT2)(IN EFI_PEI_FILE_HANDLE FileHandle,IN CONST EFI_PEI_SERVICES  **PeiServices);


通過PeiServices,PEIM可以使用PEI階段提供的系統服務,通過這些系統服務,PEIM可以訪問PEI內核。PEIM之間的通信通過PPI(PEIM-to-PEIM Interfaces)完成。

PPI與DXE階段的Protocol類似,每個PPI是一個結構體,包含了函數指針和變量,例如:

struct _EFI_PEI_DECOMPRESS_PPI {EFI_PEI_DECOMPRESS_DECOMPRESS Decompress;}  
extern EFI_GUID   gEfiPeiDecompressPpiGuid; 


 

每個PPI都有一個GUID。根據GUID,通過PeiServices的LocatePpi服務可以得到GUID對應的PPI實例。

UEFI的一個重要特點是其模塊化的設計。模塊載入內存後生成Image。Image的入口函數爲_ModuleEntryPoint。PEI也是一個模塊,PEI Image的入口函數_ModuleEntryPoint,位於MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.c。_ModuleEntryPoint最終調用PEI模塊的入口函數PeiCore,位於MdeModulePkg/Core/Pei/PeiMain/PeiMain.c。進入PeiCore後,首先根據從SEC階段傳入的信息設置Pei Core Services,然後調用PeiDispatcher執行系統中的PEIM,當內存初始化後,系統會發生棧切換並重新進入PeiCore。重新進入PeiCore後使用的內存爲我們所熟悉的內存。所有PEIM都執行完畢後,調用PeiServices的LocatePpi服務得到DXE IPL PPI,並調用DXE IPL PPI的Entry服務,這個Entry服務實際上是DxeLoadCore,它找出DXE Image的入口函數,執行DXE Image的入口函數並將HOB列表傳遞給DXE。

3.DXE階段

DXE(Driver Execution Environment)階段執行大部分系統初始化工作,進入此階段時,內存已經可以被完全使用,因而此階段可以進行大量的複雜工作。從程序設計的角度講,DXE階段與PEI階段相似,執行流程如圖1-6所示。

UEFI系統的啓動過程(4)

與PEI類似,從功能上講,DXE可分爲以下兩部分。

DXE內核:負責DXE基礎服務和執行流程。

DXE派遣器:負責調度執行DXE 驅動,初始化系統設備。

DXE提供的基礎服務包括系統表、啓動服務、Run Time Services。

每個DXE驅動是一個獨立的模塊,模塊入口函數類型定義爲:

typedef EFI_STATUS(EFIAPI *EFI_IMAGE_ENTRY_POINT)(IN  EFI_HANDLE ImageHandle,  IN  EFI_SYSTEM_TABLE *SystemTable); 
 

DXE驅動之間通過Protocol通信。Protocol是一種特殊的結構體,每個Protocol對應一個GUID,利用系統BootServices的OpenProtocol,並根據GUID來打開對應的Protocol,進而使用這個Protocol提供的服務。

當所有的Driver都執行完畢後,系統完成初始化,DXE通過EFI_BDS_ARCH_PROTOCOL找到BDS並調用BDS的入口函數,從而進入BDS階段。從本質上講,BDS是一種特殊的DXE階段的應用程序。

4.BDS階段

BDS(Boot Device Selection)的主要功能是執行啓動策略,其主要功能包括:

初始化控制檯設備。

加載必要的設備驅動。

根據系統設置加載和執行啓動項。

如果加載啓動項失敗,系統將重新執行DXE dispatcher以加載更多的驅動,然後重新嘗試加載啓動項。

BDS策略通過全局NVRAM變量配置。這些變量可以通過運行時服務的GetVariable()讀取,通過SetVariable()設置。例如,變量BootOrder定義了啓動順序,變量Boot####定義了各個啓動項(####爲4個十六進制大寫符號)。

用戶選中某個啓動項(或系統進入默認的啓動項)後,OS Loader啓動,系統進入TSL階段。

5.TSL階段

TSL(Transient System Load)是操作系統加載器(OS Loader)執行的第一階段,在這一階段OS Loader作爲一個UEFI應用程序運行,系統資源仍然由UEFI內核控制。當啓動服務的ExitBootServices()服務被調用後,系統進入Run Time階段。

TSL階段之所以稱爲臨時系統,在於它存在的目的就是爲操作系統加載器準備執行環境。雖然是臨時系統,但其功能已經很強大,已經具備了操作系統的雛形,UEFI Shell是這個臨時系統的人機交互界面。正常情況下,系統不會進入UEFI Shell,而是直接執行操作系統加載器,只有在用戶干預下或操作系統加載器遇到嚴重錯誤時纔會進入UEFI Shell。

6.RT階段

系統進入RT(Run Time)階段後,系統的控制權從UEFI內核轉交到OS Loader手中,UEFI佔用的各種資源被回收到OS Loader,僅有UEFI運行時服務保留給OS Loader和OS使用。隨着OS Loader的執行,OS最終取得對系統的控制權。

7.AL階段

在RT階段,如果系統(硬件或軟件)遇到災難性錯誤,系統固件需要提供錯誤處理和災難恢復機制,這種機制運行在AL(After Life)階段。UEFI和UEFI PI標準都沒有定義此階段的行爲和規範。



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章