【UEFI基础】System Table(一)

System Table

System Table是UEFI软件架构中最重要的一个部分,基本的代码都离不开它。

下面是一个基本的UEFI模块中会包含的Entry Point,它就有一个参数是System Table:

typedef
EFI_STATUS
(EFIAPI *EFI_IMAGE_ENTRY_POINT) (
  IN EFI_HANDLE ImageHandle, 
  IN EFI_SYSTEM_TABLE *SystemTable 
);8254Timer这个模块为例,它的inf模块中有以下的代码:

[Defines]
  INF_VERSION                    = 0x00010005
  BASE_NAME                      = Timer
  MODULE_UNI_FILE                = Timer.uni
  FILE_GUID                      = f2765dec-6b41-11d5-8e71-00902707b35e
  MODULE_TYPE                    = DXE_DRIVER
  VERSION_STRING                 = 1.0
 
  ENTRY_POINT                    = TimerDriverInitialize

其中的ENTRY_POINT就指向了该模块的入口:

/**
  Initialize the Timer Architectural Protocol driver
  @param ImageHandle     ImageHandle of the loaded driver
  @param SystemTable     Pointer to the System Table
  @retval EFI_SUCCESS            Timer Architectural Protocol created
  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.
  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.
**/
EFI_STATUS
EFIAPI
TimerDriverInitialize (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{

后续的代码会使用到SystemTable中包含的内容。

System Table包含了一系列的指针,指向Console设备,指向Runtime Service Table,Boot Service Table、DXE Service Table和Configuration Table,前两张表包含了很多的基础函数,最后一张表包含了ACPI、SMBIOS等表。

参考目录\MdePkg\Include\Uefi\UefiSpec.h里面有system table的描述:

///
/// EFI System Table
///
typedef struct {
  ///
  /// The table header for the EFI System Table.
  ///
  EFI_TABLE_HEADER                  Hdr;
  ///
  /// A pointer to a null terminated string that identifies the vendor
  /// that produces the system firmware for the platform.
  ///
  CHAR16                            *FirmwareVendor;
  ///
  /// A firmware vendor specific value that identifies the revision
  /// of the system firmware for the platform.
  ///
  UINT32                            FirmwareRevision;
  ///
  /// The handle for the active console input device. This handle must support
  /// EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
  ///
  EFI_HANDLE                        ConsoleInHandle;
  ///
  /// A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL interface that is
  /// associated with ConsoleInHandle.
  ///
  EFI_SIMPLE_TEXT_INPUT_PROTOCOL    *ConIn;
  ///
  /// The handle for the active console output device.
  ///
  EFI_HANDLE                        ConsoleOutHandle;
  ///
  /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
  /// that is associated with ConsoleOutHandle.
  ///
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *ConOut;
  ///
  /// The handle for the active standard error console device.
  /// This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
  ///
  EFI_HANDLE                        StandardErrorHandle;
  ///
  /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
  /// that is associated with StandardErrorHandle.
  ///
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *StdErr;
  ///
  /// A pointer to the EFI Runtime Services Table.
  ///
  EFI_RUNTIME_SERVICES              *RuntimeServices;
  ///
  /// A pointer to the EFI Boot Services Table.
  ///
  EFI_BOOT_SERVICES                 *BootServices;
  ///
  /// The number of system configuration tables in the buffer ConfigurationTable.
  ///
  UINTN                             NumberOfTableEntries;
  ///
  /// A pointer to the system configuration tables.
  /// The number of entries in the table is NumberOfTableEntries.
  ///
  EFI_CONFIGURATION_TABLE           *ConfigurationTable;
} EFI_SYSTEM_TABLE;

System Table的建立

System Table的建立是在DXE阶段(所以在这之前的PEI阶段并没有,里面提供的基础函数也不能用),具体的代码在DxeMain.c中,下面列出简单的代码:

EFI_SYSTEM_TABLE mEfiSystemTableTemplate = {
  {
    EFI_SYSTEM_TABLE_SIGNATURE,                                           // Signature
    EFI_SYSTEM_TABLE_REVISION,                                            // Revision
    sizeof (EFI_SYSTEM_TABLE),                                            // HeaderSize
    0,                                                                    // CRC32
    0                                                                     // Reserved
  },
  NULL,                                                                   // FirmwareVendor
  0,                                                                      // FirmwareRevision
  NULL,                                                                   // ConsoleInHandle
  NULL,                                                                   // ConIn
  NULL,                                                                   // ConsoleOutHandle
  NULL,                                                                   // ConOut
  NULL,                                                                   // StandardErrorHandle
  NULL,                                                                   // StdErr
  NULL,                                                                   // RuntimeServices
  &mBootServices,                                                         // BootServices
  0,                                                                      // NumberOfConfigurationTableEntries
  NULL                                                                    // ConfigurationTable
};
  //
  // Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData
  // Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table
  //
  gDxeCoreST = AllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate);
  ASSERT (gDxeCoreST != NULL);
 
  gDxeCoreRT = AllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate);
  ASSERT (gDxeCoreRT != NULL);
 
  gDxeCoreST->RuntimeServices = gDxeCoreRT;

在System Table中需要特别介绍的就是Boot Service Table和Runtime Service Table,在UEFI开发中一定会用到其中提供的函数。

Boot Service Table

它主要分为以下的几类:

与事件相关的:

函数名类型函数描述
CreateEventBootCreates a general-purpose event structure
CreateEventExBootCreates an event structure as part of an event group
CloseEventBootCloses and frees an event structure
SignalEventBootSignals an event
WaitForEventBootStops execution until an event is signaled
CheckEventBootChecks whether an event is in the signaled state
SetTimerBootSets an event to be signaled at a particular time
RaiseTPLBootRaises the task priority level
RestoreTPLBootRestores/lowers the task priority level

与内存相关的:

函数名类型函数描述
AllocatePagesBootAllocates pages of a particular type.
FreePagesBootFrees allocated pages.
GetMemoryMapBootReturns the current boot services memory map and memory map key.
AllocatePoolBootAllocates a pool of a particular type.
FreePoolBootFrees allocated pool.

与Protocol相关的:

函数名类型函数描述
InstallProtocolInterfaceBootInstalls a protocol interface on a device handle.
UninstallProtocolInterfaceBootRemoves a protocol interface from a device handle.
ReinstallProtocolInterfaceBootReinstalls a protocol interface on a device handle.
RegisterProtocolNotifyBootRegisters an event that is to be signaled whenever an interface is installed for a specified protocol.
LocateHandleBootReturns an array of handles that support a specified protocol.
HandleProtocolBootQueries a handle to determine if it supports a specified protocol.
LocateDevicePathBootLocates all devices on a device path that support a specified protocol and returns the handle to the device that is closest to the path.
OpenProtocolBootAdds elements to the list of agents consuming a protocol interface.
CloseProtocolBootRemoves elements from the list of agents consuming a protocol interface.
OpenProtocolInformationBootRetrieve the list of agents that are currently consuming a protocol interface.
ConnectControllerBootUses a set of precedence rules to find the best set of drivers to manage a controller.
DisconnectControllerBootInforms a set of drivers to stop managing a controller.
ProtocolsPerHandleBootRetrieves the list of protocols installed on a handle. The return buffer is automatically allocated.
LocateHandleBufferBootRetrieves the list of handles from the handle database that meet the search criteria. The return buffer is automatically allocated.
LocateProtocolBootFinds the first handle in the handle database the supports the requested protocol.
InstallMultipleProtocolInterfacesBootInstalls one or more protocol interfaces onto a handle.
UninstallMultipleProtocolInterfacesBootUninstalls one or more protocol interfaces from a handle.

与Image相关的:

函数名类型函数描述
LoadImageBootLoads an EFI image into memory.
StartImageBootTransfers control to a loaded image’s entry point.
UnloadImageBootUnloads an image.
EFI_IMAGE_ENTRY_POINTBootPrototype of an EFI Image’s entry point.
ExitBootExits the image’s entry point.
ExitBootServicesBootTerminates boot services.

及其它:

函数名类型函数描述
SetWatchDogTimerBootResets and sets a watchdog timer used during boot services time.
StallBootStalls the processor.
CopyMemBootCopies the contents of one buffer to another buffer.
SetMemBootFills a buffer with a specified value.
GetNextMonotonicCountBootReturns a monotonically increasing count for the platform.
InstallConfigurationTableBootAdds, updates, or removes a configuration table from the EFI System Table.
CalculateCrc32BootComputes and returns a 32-bit CRC for a data buffer.

Runtime Service Table

在Boot Service中有一个ExitBootServices,还函数被调用后Boot Serice Table中的函数就不能再使用了,但是Runtime Service Table中的函数仍然可以使用,这些函数在OS中也仍旧可以调用,当然前提是OS支持。

Runtime Serivces有以下几类:

与变量相关的:

函数名类型函数描述
GetVariableRuntimeReturns the value of a variable.
GetNextVariableNameRuntimeEnumerates the current variable names.
SetVariableRuntimeSets the value of a variable.
QueryVariableInfoRuntimeReturns information about the EFI variables

与时间相关的:

函数名类型函数描述
GetTimeRuntimeReturns the current time and date, and the time-keeping capabilities of the platform.
SetTimeRuntimeSets the current local time and date information.
GetWakeupTimeRuntimeReturns the current wakeup alarm clock setting.
SetWakeupTimeRuntimeSets the system wakeup alarm clock time.

与虚拟内存相关的:

函数名类型函数描述
SetVirtualAddressMapRuntimeUsed by an OS loader to convert from physical addressing to virtual addressing.
ConvertPointerRuntimeUsed by EFI components to convert internal pointers when switching to virtual addressing.

及其它:

函数名类型函数描述
GetNextHighMonotonicCountRuntimeReturns the next high 32 bits of the platform’s monotonic counter.
ResetSystemRuntimeResets the entire platform.
UpdateCapsuleRuntimePass capsules to the firmware. The firmware may process the capsules immediately or return a value to be passed into ResetSystem() that will cause the capsule to be processed by the firmware as part of the reset process.
QueryCapsuleCapabilitiesRuntimeReturns if the capsule can be supported via UpdateCapsule()

Runtime Service与Boot Service不同,它并不是在DxeMain.c中直接建立好的,它刚开始基本上是一个空的表:

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
};

可以看到很多的CoreEfiNotAvailableYetxx。

Runtime Service需要在DXE阶段运行过程中一个个的填补。

比如关于时间的几个接口的初始化:

/**
  This is the declaration of an EFI image entry point. This can be the entry point to an application
  written to this specification, an EFI boot service driver, or an EFI runtime driver.
  @param  ImageHandle           Handle that identifies the loaded image.
  @param  SystemTable           System Table for this image.
  @retval EFI_SUCCESS           The operation completed successfully.
**/
EFI_STATUS
EFIAPI
InitializeRealTimeClock (
  IN EFI_HANDLE                            ImageHandle,
  IN EFI_SYSTEM_TABLE                      *SystemTable
  )
{
  EFI_STATUS  Status;
 
  LibRtcInitialize (ImageHandle, SystemTable);
 
  SystemTable->RuntimeServices->GetTime       = GetTime;
  SystemTable->RuntimeServices->SetTime       = SetTime;
  SystemTable->RuntimeServices->GetWakeupTime = GetWakeupTime;
  SystemTable->RuntimeServices->SetWakeupTime = SetWakeupTime;
 
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &mHandle,
                  &gEfiRealTimeClockArchProtocolGuid,
                  NULL,
                  NULL
                  );
 
  return Status;
}
再比如关于变量的几个接口:

EFI_STATUS
EFIAPI
VariableServiceInitialize (
  IN EFI_HANDLE                         ImageHandle,
  IN EFI_SYSTEM_TABLE                   *SystemTable
  )
{
  EFI_STATUS                            Status;
  EFI_EVENT                             ReadyToBootEvent;
  EFI_EVENT                             EndOfDxeEvent;
 
  Status = VariableCommonInitialize ();
  ASSERT_EFI_ERROR (Status);
 
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &mHandle,
                  &gEdkiiVariableLockProtocolGuid,
                  &mVariableLock,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);
 
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &mHandle,
                  &gEdkiiVarCheckProtocolGuid,
                  &mVarCheck,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);
 
  SystemTable->RuntimeServices->GetVariable         = VariableServiceGetVariable;
  SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;
  SystemTable->RuntimeServices->SetVariable         = VariableServiceSetVariable;
  SystemTable->RuntimeServices->QueryVariableInfo   = VariableServiceQueryVariableInfo;

————————————————
版权声明:本文为CSDN博主「jiangwei0512」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jiangwei0512/article/details/51627562

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值