Core Module
這邊紀錄一下EDK2裡面4個phase的Core Module有哪些,大概看一下每個Entry裡面會幹嘛。
先複習一下Boot Flow
SecCore
## @file
# SecCore module that implements the SEC phase.
#
# This is the first module taking control of the platform upon power-on/reset.
# It implements the first phase of the security phase. The entry point function is
# _ModuleEntryPoint in PlatformSecLib. The entry point function will switch to
# protected mode, setup flat memory model, enable temporary memory and
# call into SecStartup().
##
[Defines]
BASE_NAME = SecCore
MODULE_TYPE = SEC
既然都說入口是_ModuleEntryPoint了,就來看一下吧(在SecEntry.nasm裡面)
;----------------------------------------------------------------------------
; Procedure: _ModuleEntryPoint
; Input: None
; Output: None
; Destroys: Assume all registers
; Description:
; Transition to non-paged flat-model protected mode from a
; hard-coded GDT that provides exactly two descriptors.
; This is a bare bones transition to protected mode only
; used for a while in PEI and possibly DXE.
;
; After enabling protected mode, a far jump is executed to
; transfer to PEI using the newly loaded GDT.
; Return: None
; MMX Usage:
; MM0 = BIST State
; MM5 = Save time-stamp counter value high32bit
; MM6 = Save time-stamp counter value low32bit.
;----------------------------------------------------------------------------
global ASM_PFX(ModuleEntryPoint)
- BIST->Load GDT table->cr0&cr4 to protected mode->set up Selectors for 32 bit
- FSP info->FV header->Ext Fv header->FFS header->section header
- 還有一些其他東西,不過就先不看了,接下來就call進SecStartup。
/**
Entry point to the C language phase of SEC. After the SEC assembly
code has initialized some temporary memory and set up the stack,
the control is transferred to this function.
**/
VOID
EFIAPI
SecStartup (
IN UINT32 SizeOfRam,
IN UINT32 TempRamBase,
IN VOID *BootFirmwareVolume,
IN PEI_CORE_ENTRY PeiCore,
IN UINT32 BootLoaderStack,
IN UINT32 ApiIdx
)
這邊的話看起來就是把IDT填好還有FSP初始化就進PEI了。
PeiCore
## @file
# PeiMain module is core module in PEI phase.
#
# It takes responsibilities of:
# 1) Initialize memory, PPI, image services etc, to establish PEIM runtime environment.
# 2) Dispatch PEIM from discovered FV.
# 3) Handoff control to DxeIpl to load DXE core and enter DXE phase.
##
[Defines]
BASE_NAME = PeiCore
MODULE_TYPE = PEI_CORE
ENTRY_POINT = PeiCore
PEI的話上面敘述好像都說完了,主要應該是剛剛SEC還在Stack裡面玩,現在要把剛剛的東西shadow到memory裡面,然後再從memory裡面重新開始執行PeiCore,從新執行就是跑上面說的那3點了。
然後要切到Dxe的時候,在PeiCore裡面最後會執行一個DxeLoadCore
/**
Main entry point to last PEIM.
This function finds DXE Core in the firmware volume and transfer the control to
DXE core.
**/
EFI_STATUS
EFIAPI
DxeLoadCore (
IN CONST EFI_DXE_IPL_PPI *This,
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_HOB_POINTERS HobList
)
在這裡面就會去看BootMode是什麼,
- S3的話就把data要回來然後就SwitchStack回去
- 如果是Recovery的話就LoadRecoveryCapsule
- Flash Update的話就LoadCapsuleOnDisk
- Normal的話就從Fv裡面load DxeCore出來,然後把HobList和DxeCore的位置準備好給SwitchStack帶過去。
DxeCore
## @file
# This is core module in DXE phase.
# It provides an implementation of DXE Core that is compliant with DXE CIS.
##
[Defines]
BASE_NAME = DxeCore
MODULE_TYPE = DXE_CORE
ENTRY_POINT = DxeMain
...
/**
Main entry point to DXE Core.
**/
VOID
EFIAPI
DxeMain (
IN VOID *HobStart
)
...
因為Memory好了,SystemTable, RuntimeServices, GCD Services都可以使用了,所以這邊有一部份是要把之前的東西移到Table裡,不過這邊最主要的還是Driver。
// Initialize the DXE Dispatcher
前面會先看是不是Fv,然後存進gEfiFirmwareVolume2ProtocolGuid裡面,接下來Initialize要做什麼咧
- 把Fv的Section讀出來看他有沒有Depex
- 沒有Depex的話放進CoreProcessFvImageFile排序裡
- 有的話放進CoreAddToDriverList排序裡
- 還有一些是你有設定Apriori的話會再調整順序
// Invoke the DXE Dispatcher
- LoadImage
- StartImage(supported->start)
- 調整List
//
// Transfer control to the BDS Architectural Protocol
//
gBds->Entry (gBds);
最後出現這行,看了DxeCore裡面沒這東西啊,才發現原來他是一個DXE_DRIVER阿,在所有Driver都裝好之後會去install gEfiBdsArchProtocolGuid procotol,這個protocol也就是上面gBds。
## @file
# BdsDxe module is core driver for BDS phase.
# When DxeCore dispatching all DXE driver, this module will produce architecture protocol
# gEfiBdsArchProtocolGuid. After DxeCore finish dispatching, DxeCore will invoke Entry
# interface of protocol gEfiBdsArchProtocolGuid, then BDS phase is entered.
##
[Defines]
BASE_NAME = BdsDxe
MODULE_TYPE = DXE_DRIVER
ENTRY_POINT = BdsInitialize
BdsEntry
就是透過上面gBds切進BDS phase的.................
/**
Service routine for BdsInstance->Entry(). Devices are connected, the
consoles are initialized, and the boot options are tried.
**/
VOID
EFIAPI
BdsEntry (
IN EFI_BDS_ARCH_PROTOCOL *This
)
看一下BootFlow,這邊簡單帶過
- BootOption
- ConIn
- BootManager
- signal gEfiEventReadyToBootGuid
- LoadImage
REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad));
Status = gBS->LoadImage (
TRUE,
gImageHandle,
FilePath,
FileBuffer,
FileSize,
&ImageHandle
);
:DONE
Ref
Beyond BIOS
EDK2-master