EDK II之DXE Core框架簡介

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

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

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

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

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

3.經過加載各類模塊擴展其餘的功能;框架

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

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

內核提供的基本Service:spa

 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裏面的模塊舉例:

相關文章
相關標籤/搜索