2020年5月16日 星期六

EDK2 Core Module List

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)
  1. BIST->Load GDT table->cr0&cr4 to protected mode->set up Selectors for 32 bit
  2. FSP info->FV header->Ext Fv header->FFS header->section header
  3. 還有一些其他東西,不過就先不看了,接下來就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是什麼,
  1. S3的話就把data要回來然後就SwitchStack回去
  2. 如果是Recovery的話就LoadRecoveryCapsule
  3. Flash Update的話就LoadCapsuleOnDisk
  4. 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要做什麼咧
  1. 把Fv的Section讀出來看他有沒有Depex
  2. 沒有Depex的話放進CoreProcessFvImageFile排序裡
  3. 有的話放進CoreAddToDriverList排序裡
  4. 還有一些是你有設定Apriori的話會再調整順序
  // Invoke the DXE Dispatcher
  1. LoadImage
  2. StartImage(supported->start)
  3. 調整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,這邊簡單帶過
  1. BootOption
  2. ConIn
  3. BootManager
  4. signal gEfiEventReadyToBootGuid
  5. LoadImage
      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad));
      Status = gBS->LoadImage (
                      TRUE,
                      gImageHandle,
                      FilePath,
                      FileBuffer,
                      FileSize,
                      &ImageHandle
                      );

:DONE

Ref

Beyond BIOS
EDK2-master

沒有留言:

張貼留言