EDK II之DXE Core框架簡介


本文旨在簡單的介紹一下DXE階段的工作原理:

UDK2015的開源代碼下載:https://github.com/tianocore/tianocore.github.io/wiki/EDK-II

DXE階段是UEFI系統的最主要的組成部分,

1.DXE階段主要由兩部分組成:DXE內核 + 模塊;

2.DXE內核提供了最基本的一些功能,比如Protocol的管理,事件的管理等等(DXE內核提供的基本功能稱為服務);

3.通過加載各種模塊擴展其他的功能;

4.DXE階段的核心概念:Service、Protocol、Handle(Handle和Protocol組成一個二維鏈表,protocol提供的接口類似於內核符號表中的函數;Service類似於linux kernel api);

5.DXE內核在post過程中會加載各種模塊,每個模塊會安裝不同的Protocol(Protocol類似於面向對象編程里面的類),用來擴展系統支持的功能;

內核提供的基本Service:

 1 //
 2 // DXE Core Module Variables
 3 //
 4 EFI_BOOT_SERVICES mBootServices = {
 5   {
 6     EFI_BOOT_SERVICES_SIGNATURE,                                                          // Signature
 7     EFI_BOOT_SERVICES_REVISION,                                                           // Revision
 8     sizeof (EFI_BOOT_SERVICES),                                                           // HeaderSize
 9     0,                                                                                    // CRC32
10     0                                                                                     // Reserved
11   },
19   (EFI_CREATE_EVENT)                            CoreCreateEvent,                          // CreateEvent
20   (EFI_SET_TIMER)                               CoreSetTimer,                             // SetTimer
21   (EFI_WAIT_FOR_EVENT)                          CoreWaitForEvent,                         // WaitForEvent
22   (EFI_SIGNAL_EVENT)                            CoreSignalEvent,                          // SignalEvent
23   (EFI_CLOSE_EVENT)                             CoreCloseEvent,                           // CloseEvent
24   (EFI_CHECK_EVENT)                             CoreCheckEvent,                           // CheckEvent
25   (EFI_INSTALL_PROTOCOL_INTERFACE)              CoreInstallProtocolInterface,             // InstallProtocolInterface
26   (EFI_REINSTALL_PROTOCOL_INTERFACE)            CoreReinstallProtocolInterface,           // ReinstallProtocolInterface
27   (EFI_UNINSTALL_PROTOCOL_INTERFACE)            CoreUninstallProtocolInterface,           // UninstallProtocolInterface
28   (EFI_HANDLE_PROTOCOL)                         CoreHandleProtocol,                       // HandleProtocol
29   (VOID *)                                      NULL,                                     // Reserved
30   (EFI_REGISTER_PROTOCOL_NOTIFY)                CoreRegisterProtocolNotify,               // RegisterProtocolNotify
31   ....
56 };

上面是DXE內核提供的功能。

但也有些Service,內核沒有提供具體的實現,只是聲明了接口:

EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = {
  {
    EFI_RUNTIME_SERVICES_SIGNATURE,                               // Signature
    EFI_RUNTIME_SERVICES_REVISION,                                // Revision
    sizeof (EFI_RUNTIME_SERVICES),                                // HeaderSize
    0,                                                            // CRC32
    0                                                             // Reserved
  },
  (EFI_GET_TIME)                    CoreEfiNotAvailableYetArg2,   // GetTime
  (EFI_SET_TIME)                    CoreEfiNotAvailableYetArg1,   // SetTime
  (EFI_GET_WAKEUP_TIME)             CoreEfiNotAvailableYetArg3,   // GetWakeupTime
  (EFI_SET_WAKEUP_TIME)             CoreEfiNotAvailableYetArg2,   // SetWakeupTime
  (EFI_SET_VIRTUAL_ADDRESS_MAP)     CoreEfiNotAvailableYetArg4,   // SetVirtualAddressMap
  (EFI_CONVERT_POINTER)             CoreEfiNotAvailableYetArg2,   // ConvertPointer
  (EFI_GET_VARIABLE)                CoreEfiNotAvailableYetArg5,   // GetVariable
  (EFI_GET_NEXT_VARIABLE_NAME)      CoreEfiNotAvailableYetArg3,   // GetNextVariableName
  (EFI_SET_VARIABLE)                CoreEfiNotAvailableYetArg5,   // SetVariable
  (EFI_GET_NEXT_HIGH_MONO_COUNT)    CoreEfiNotAvailableYetArg1,   // GetNextHighMonotonicCount
  (EFI_RESET_SYSTEM) CoreEfiNotAvailableYetArg4, // ResetSystem
  (EFI_UPDATE_CAPSULE)              CoreEfiNotAvailableYetArg3,   // UpdateCapsule
  (EFI_QUERY_CAPSULE_CAPABILITIES)  CoreEfiNotAvailableYetArg4,   // QueryCapsuleCapabilities
  (EFI_QUERY_VARIABLE_INFO)         CoreEfiNotAvailableYetArg4    // QueryVariableInfo
};

以EFI_RUNTIME_SERVICES->ResetSystem()為例,不同的平台(比如x86與ARM),重啟系統的實現方式是不一樣的,所以UDK代碼里面沒有給出具體的實現。在實際項目中,通過平台BSP代碼提供的模塊來安裝這個實現:

  //
  // Hook the runtime service table
  //
  SystemTable->RuntimeServices->ResetSystem = Cf9ResetSystem;
 1 VOID
 2 EFIAPI
 3 Cf9ResetSystem (
 4   IN EFI_RESET_TYPE   ResetType,
 5   IN EFI_STATUS       ResetStatus,
 6   IN UINTN            DataSize,
 7   IN CHAR16           *ResetData OPTIONAL
 8   )
 9 {
10     //不同平台的具體實現;
11
}

 UDK整個系統的代碼框架可描述如下:

1.內核聲明了整個系統必須實現的接口(依據UEFI/PI規范);

2.一部分(最最基本)的接口的實現由內核提供,一部分接口的實現因為跟平台有關,所以由平台代碼提供;

3.通過模塊安裝各種各樣的擴展功能(protocol);

4.整個代碼框架是微內核結構,內核只提供基本的功能,模塊通過安裝protocol來提供其它功能

5. 內核實現了框架,並提供API,驅動程序調用內核提供的API把自己實現的接口(protocol)安裝到系統中,系統使用統一的接口訪問不同的實現

6.DXE最后會把控制權交給BDS:

某個DXE driver會安裝下面的protocol,用來提供BDS的入口,DXE到BDS體現了內核通過統一接口訪問不同實現的思想。 

模塊舉例:

UDK里面的模塊舉例:(這里的模塊沒有follow UEFI Driver Model

UEFI Spec里面通過EFI_IMAGE_ENTRY_POINT 這個函數指針類型定義了 UEFI Image的入口點的形式(包括返回值和參數)

Linux里面的模塊舉例:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM