UEFI基础概念1——EFI SYSTEM TABLE

一、系统表介绍

对UEFI应用程序和驱动程序开发人员来讲,系统表是最重要的数据结构之一,它是用户空间通往内核空间的通道。有了它,UEFI应用程序和驱动才可以访问UEFI内核、硬件资源和输入/输出设备。

(1)在应用程序和驱动中如何访问系统表

        计算机系统进入DXE阶段后系统表被初始化,因而系统表只能用于DXE阶段以及以后的应用程序和驱动中。系统表是UEFI内核的一个全局结构体,其指针作为程序映像(Image)入口函数的参数传递到用户空间。程序映像(包括UEFI应用程序、DXE驱动程序以及UEFI驱动程序)的入口函数有统一的格式,函数原型如下:

EFI_STATUS
EFIAPI
*EFI_IMAGE_ENTRY_POINT(
  IN EFI_HANDLE        ImageHandle, //程序映像Image的句柄
  IN EFI_SYSTEM_TABLE  *SystemTable //系统表指针
);

(2)系统表指针从内核传递到用户空间的过程

通常,程序映像的入口函数是_ModuleEntryPoint,当应用程序被加载到内存形成Image后,_ModuleEntryPoint函数地址被赋值给Image对象的EntryPoint,然后Image ->EntryPoint(ImageHandle, SystemTable)会被执行,最终会从Image的入口函数_ModuleEntryPoint执行到模块的入口函数(模块的入口函数是通过.inf文件中的ENTRY_POINT指定的那个函数)。

传递给映像的最重要的参数就是系统表(system table),这是进入一个UEFI映像的入口。系统表包含了指向各种控制设备的指针,指向引导服务表的指针和指向运行服务的指针,指向系统配置表(如ACPI、SMBIOS,SAL系统表)的指针。

EFI System Table的数据结构为:

typedef struct {
  EFI_TABLE_HEADER                   Hdr; //EFI System Table的表头
  CHAR16                             *FirmwareVendor; //指向一个以null结尾地字符串,标识系统固件的供应商
  UINT32                             FirmwareRevision; //特定于固件供应商,用于表示固件平台的版本
  EFI_HANDLE                         ConsoleInHandle; //控制输入控制设备的句柄
  EFI_SIMPLE_TEXT_INPUT_PROTOCOL     *ConIn; //指向与ConsoleInHandle相关联的EFI_SIMPLE_TEXT_INPUT_PROTOCOL接口的指针。
  EFI_HANDLE                         ConsoleOutHandle;
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *ConOut;
  EFI_HANDLE                         StandardErrorHandle; //指向标准错误控制台的指针
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *StdErr;
  EFI_RUNTIME_SERVICES               *RuntimeServices; //指向运行时服务的指针
  EFI_BOOT_SERVICES                  *BootServices; //指向引导服务的指针
  UINTN                              NumberOfTableEntries; //缓冲区系统配置表的数量
  EFI_CONFIGURATION_TABLE            *ConfigurationTable; //指向系统配置表的指针
} EFI_SYSTEM_TABLE;

1、在用户空间使用系统表

在模块的入口函数中,系统表的地址可以通过模块入口函数的参数得到

2、在用户空间使用gST访问系统表

在其它函数中可以使用gST变量访问系统表。EDK2为例方便开发者,提供了UefiBootServicesTableLib,在UefiLib中定义了全局变量gST(指向System Table)、gBS(指向SystemTable->BootServices)和gImageHandle(指向ImageHandle)。

 二、启动服务表

EFI启动服务表,表中的每一项是一个函数指针,这个函数用于提供一项服务。当操作系统加载器彻底取得对计算机系统的控制权之后,启动服务也就完成了它的使命,启动服务占用的系统资源也需要转交给操作系统加载器。此时需要调用gBS->ExitBootServices,其作用是结束启动服务、释放启动服务占用的资源以及使用启动服务分配得到的启动期资源,将控制权交给操作系统加载器。

extern EFI_BOOT_SERVICES  *gBS;

gBS是一个指向启动服务的指针,EFI_BOOT_SERVICES是一个提供一组启动服务的数据结构,其提供的服务有:

Event、Timer、Task Priority Services服务

内存分配服务

Protocol处理服务

Image服务

typedef struct {
  EFI_TABLE_HEADER                              Hdr;  //表头

  // Task Priority Services 任务优先级服务
  EFI_RAISE_TPL                                 RaiseTPL;
  EFI_RESTORE_TPL                               RestoreTPL;

  // Memory Services 内存服务
  EFI_ALLOCATE_PAGES                            AllocatePages;
  EFI_FREE_PAGES                                FreePages;
  EFI_GET_MEMORY_MAP                            GetMemoryMap;
  EFI_ALLOCATE_POOL                             AllocatePool;
  EFI_FREE_POOL                                 FreePool;

  // Event & Timer Services 事件和定时器服务
  EFI_CREATE_EVENT                              CreateEvent;
  EFI_SET_TIMER                                 SetTimer;
  EFI_WAIT_FOR_EVENT                            WaitForEvent;
  EFI_SIGNAL_EVENT                              SignalEvent;
  EFI_CLOSE_EVENT                               CloseEvent;
  EFI_CHECK_EVENT                               CheckEvent;

  // Protocol Handler Services 协议处理服务
  EFI_INSTALL_PROTOCOL_INTERFACE                InstallProtocolInterface;
  EFI_REINSTALL_PROTOCOL_INTERFACE              ReinstallProtocolInterface;
  EFI_UNINSTALL_PROTOCOL_INTERFACE              UninstallProtocolInterface;
  EFI_HANDLE_PROTOCOL                           HandleProtocol;
  VOID                                          *Reserved;
  EFI_REGISTER_PROTOCOL_NOTIFY                  RegisterProtocolNotify;
  EFI_LOCATE_HANDLE                             LocateHandle;
  EFI_LOCATE_DEVICE_PATH                        LocateDevicePath;
  EFI_INSTALL_CONFIGURATION_TABLE               InstallConfigurationTable;

  // Image Services 映像服务
  EFI_IMAGE_LOAD                                LoadImage;
  EFI_IMAGE_START                               StartImage;
  EFI_EXIT                                      Exit;
  EFI_IMAGE_UNLOAD                              UnloadImage;
  EFI_EXIT_BOOT_SERVICES                        ExitBootServices;

  // Miscellaneous Services 杂项服务
  EFI_GET_NEXT_MONOTONIC_COUNT                  GetNextMonotonicCount;
  EFI_STALL                                     Stall;
  EFI_SET_WATCHDOG_TIMER                        SetWatchdogTimer;

  // DriverSupport Services 驱动支持服务
  EFI_CONNECT_CONTROLLER                        ConnectController;
  EFI_DISCONNECT_CONTROLLER                     DisconnectController;

  // Open and Close Protocol Services 开启和关闭Protocol服务
  EFI_OPEN_PROTOCOL                             OpenProtocol;
  EFI_CLOSE_PROTOCOL                            CloseProtocol;
  EFI_OPEN_PROTOCOL_INFORMATION                 OpenProtocolInformation;

  // Library Services 库服务
  EFI_PROTOCOLS_PER_HANDLE                      ProtocolsPerHandle;
  EFI_LOCATE_HANDLE_BUFFER                      LocateHandleBuffer;
  EFI_LOCATE_PROTOCOL                           LocateProtocol;
  EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES      InstallMultipleProtocolInterfaces;
  EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES    UninstallMultipleProtocolInterfaces;

  // 32-bit CRC Services 32位CRS服务(循环冗余校验服务)
  EFI_CALCULATE_CRC32                           CalculateCrc32;

  // Miscellaneous Services 杂项服务
  EFI_COPY_MEM                                  CopyMem;
  EFI_SET_MEM                                   SetMem;
  EFI_CREATE_EVENT_EX                           CreateEventEx;
} EFI_BOOT_SERVICES;

三、运行时服务

从进入DXE阶段运行时服务被初始化、直到操作系统结束,运行时服务都一直存在并向上层(操作系统、操作系统加载器、UEFI应用程序或UEFI驱动)提供服务。

EFI运行服务表

extern EFI_RUNTIME_SERVICES  *gRT;

gRT是指向运行服务表的指针,EFI_RUNTIME_SERVICES是一个提供一组运行时服务的数据结构,所提供的服务有:

运行时规则和限制

Variable服务

时间服务

虚拟内存服务

杂项服务

/// EFI Runtime Services Table.
typedef struct {
  EFI_TABLE_HEADER                  Hdr; //表头

  // Time Services 时间服务
  EFI_GET_TIME                      GetTime;
  EFI_SET_TIME                      SetTime;
  EFI_GET_WAKEUP_TIME               GetWakeupTime;
  EFI_SET_WAKEUP_TIME               SetWakeupTime;

  // Virtual Memory Services 虚拟内存服务
  EFI_SET_VIRTUAL_ADDRESS_MAP       SetVirtualAddressMap;
  EFI_CONVERT_POINTER               ConvertPointer;

  // Variable Services 变量服务
  EFI_GET_VARIABLE                  GetVariable;
  EFI_GET_NEXT_VARIABLE_NAME        GetNextVariableName;
  EFI_SET_VARIABLE                  SetVariable;

  // Miscellaneous Services 杂项服务
  EFI_GET_NEXT_HIGH_MONO_COUNT      GetNextHighMonotonicCount;
  EFI_RESET_SYSTEM                  ResetSystem;

  // UEFI 2.0 Capsule Services UEFI2.0 胶囊服务
  EFI_UPDATE_CAPSULE                UpdateCapsule;
  EFI_QUERY_CAPSULE_CAPABILITIES    QueryCapsuleCapabilities;

  // Miscellaneous UEFI 2.0 Service UEFI2.0 杂项服务
  EFI_QUERY_VARIABLE_INFO           QueryVariableInfo;
} EFI_RUNTIME_SERVICES;

UEFI System Table的数据结构是一个由固件在系统启动时创建和填充的表。它由一个固定大小的数据结构定义,其中包含了多个表项,每个表项描述了一个特定的系统资源或功能。 UEFI System Table的数据结构通常被称为EFI_SYSTEM_TABLEEFI_SYSTEM_TABLE_STRUCTURE。它包含以下几个主要的字段: 1. Firmware Vendor:指示固件供应商的字符串。 2. Firmware Revision:指示固件版本的整数值。 3. Console In/Out/Error:指向控制台输入、输出和错误输出的函数指针。 4. Runtime Services:指向运行时服务的函数指针。 5. Boot Services:指向引导时服务的函数指针。 6. NumberOfTableEntries:整数值,表示System Table中表项的数量。 7. ConfigurationTable:指向一个数组,包含了其他表项的指针。 ConfigurationTable是System Table中最重要的字段之一,它是一个数组,每个元素都是一个EFI_CONFIGURATION_TABLE结构体,描述了其他表项的位置和大小。每个EFI_CONFIGURATION_TABLE结构体包含两个字段: - VendorGuid:一个唯一标识符,用于标识特定的表项类型。 - VendorTable:指向特定表项的指针。 通过解析System Table的数据结构,操作系统和应用程序能够访问各种固件功能和硬件资源,如电源管理、内存管理、文件系统访问等。每个表项都提供了特定功能的信息和接口,使得操作系统能够正确地配置和管理系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值