博客
关于我
BIOS/UEFI基础——System Table和Architecture Protocols
阅读量:527 次
发布时间:2019-03-06

本文共 5485 字,大约阅读时间需要 18 分钟。

UEFI系统表与服务表详解

UEFI(Unified Extensible Firmware Interface,通用可扩展固件接口)是现代计算机系统中核心的固件接口规范。其架构中最为关键且复杂的部分便是系统表(System Table)。本文将深入探讨UEFI系统表的相关内容,包括其构建过程、 Boot Service Table 和 Runtime Service Table 的功能划分,以及如何利用这些服务表开发与UEFI兼容的系统程序。


UEFI系统表的基本结构

系统表(System Table)是UEFI固件的构建基石,里面包含了运行时服务表、设备控制表、 Guthiิศ ซ. 等多个重要接口和数据结构。系统表的主要内容包括:

1.Signature(签名)

QE128值,用于验证系统表的完整性,确保它是可信的UEFI系统表。

2.Revision(修订编号)

QE16值,表示系统表的版本。

3.HeaderSize(头部大小)

QE32值,表示系统表的头部大小。

4.CRC32(循环校验和)

QE32值,用来校验系统表的完整性。

5.Reserved(预留空间)

QE32值,用于系统表的VESA(视频电子记忆排序)等轻量级引导程 SHOWDEVICES 接口。

6.FirmwareVendor(固件供应商标识)

指向一个设备地址,存储了当前固件的供应商ID和相关信息。

7.FirmwareRevision(固件修订编号)

QE16值,表示固件的版本信息。

8.ConsoleInHandle(控制输入设备的磁引环)

指向与控制台相关的输入接口。

9.ConsoleOutHandle(控制输出设备的输入流)

指向与控制台相关的输出接口。

10.StandardErrorHandle(标准错误设备的输入流)

指向与标准错误设备相关的输入接口。

11.RuntimeServices(运行时服务表)

这是系统表中最重要的字段之一。这个指针指向了UEFI运行时服务表,里面包含了大量常用固件接口,如 StartExitBootServices 等。

12.NumberOfConfigurationTableEntries(配置表条目数)

QE32值,表示系统表中包含的其他配置表的数量。

13.ConfigurationTable(配置表)

这是一个可选字段,可用于存储系统某些特定固件实现的补充信息。

通过以上结构可以看出,系统表的核心作用是作为固件编程的入口,程序通过它来访问系统所需的各种服务和资源。


系统表的建立与运行

系统表的创建过程是UEFI启动阶段(DXE,Differentiated Execution Environment)中的关键步骤。系统表需要在固件运行的早期阶段初始化,以供后续 drivers 和程序使用。

系统表的初始化代码示例

以下是DXE主调度(DxeMain.c)中一个简单的系统表初始化代码段:

// DXE主调度(DxeMain.c)中创建系统表的代码示例EFI_SYSTEM_TABLE mEfiSystemTableTemplate = {   {     EFI_SYSTEM_TABLE_SIGNATURE,           // 签名    EFI_SYSTEM_TABLE_REVISION,            // 修订编号    sizeof(EFI_SYSTEM_TABLE),             // 头部大小    0,                                      // CRC32值    0                                       // 保留值  },  NULL,                                   // 固件供应商标识  0,                                      // 固件修订编号  NULL,                                   // 控制输入设备的磁引环  NULL,                                   // 控制输出设备的输入流  NULL,                                   // 标准错误设备的输入流  NULL,                                   // 运行时服务表指针  &mBootServices,                          // Boot服务表指针  0,                                      // 配置表条目数  NULL                                    // 配置表指针};

在实际实现中,系统表需要通过 AllocateRuntimeCopyPool 函数分配内存,并进行数据初始化。完成后的系统表会被 DXE 核心用于后续服务的建立与运行。


Boot Service Table(Boot Service Table, Boot 服务表)

Boot Service Table 是系统表中最基本的服务表类型之一,里面包含了UEFI启动过程中常用的接口和函数。这些服务包括事件管理、内存管理、协议安装等。以下是 Boot Service Table 中的主要函数分类:

1. 与事件相关的

  • CreateEvent
  • CreateEventEx
  • CloseEvent
  • SignalEvent
  • WaitForEvent
  • CheckEvent
  • SetTimer
  • RaiseTPL
  • RestoreTPL

这些函数为系统在启动过程中提供了事件管理的能力,常用于启动进程调度、任务优先级控制等场景。

2. 与内存相关的

  • AllocatePages
  • FreePages
  • GetMemoryMap
  • AllocatePool
  • FreePool

这些函数为系统提供了内存管理的基本接口,可以用来分配和释放物理内存或虚拟内存。

3. 与协议相关的

  • InstallProtocolInterface
  • UninstallProtocolInterface
  • ReinstallProtocolInterface
  • RegisterProtocolNotify
  • LocateHandle
  • HandleProtocol
  • LocateDevicePath
  • OpenProtocol
  • CloseProtocol
  • OpenProtocolInformation
  • ConnectController
  • DisconnectController

这些函数让系统能够管理设备协议,安装和删除协议接口,定位支持特定协议的设备。

4. 与图像相关的

  • LoadImage
  • StartImage
  • UnloadImage
  • EFI_IMAGE_ENTRY_POINT
  • Exit
  • ExitBootServices

这些函数控制着图像的加载与运行,确保固件能够正确执行各个阶段的程序。

5. 其他常用接口

  • SetWatchDogTimer
  • Stall
  • CopyMem
  • SetMem
  • GetNextMonotonicCount
  • InstallConfigurationTable
  • CalculateCrc32

这些函数提供了一系列通用接口,可用于时间管理、调度控制、数据校验等。


Runtime Service Table(Runtime Service Table, 运行时服务表)

与 Boot Service Table 不同, Runtime Service Table 在启动完成后进入运行时阶段仍然有效。它提供了一系列用于操作系统级别的服务接口,如变量管理、时间控制、虚拟内存管理等。

1. 与变量相关的

  • GetVariable
  • GetNextVariableName
  • SetVariable
  • QueryVariableInfo

这些函数用于管理和访问系统中定义的 EFI 变量,常用于存储和运行时配置信息。

2. 与时间相关的

  • GetTime
  • SetTime
  • GetWakeupTime
  • SetWakeupTime

这些函数用于管理系统时间和唤醒时间,确保系统能够正确进行时间更新和恢复。

3. 与虚拟内存相关的

  • SetVirtualAddressMap
  • ConvertPointer

这些函数用于转换物理地址和虚拟地址,便于操作系统在虚拟化环境中使用物理内存。

4. 其他运行时接口

  • GetNextHighMonotonicCount
  • ResetSystem
  • UpdateCapsule
  • QueryCapsuleCapabilities

这些函数提供了平台运行时的高级功能,如重置系统、管理加密硬件等。


Architecture Protocols(架构协议)

UEFI运行时所依赖的核心协议也需要在系统表中进行注册和初始化。这些协议包括:

EFI_CORE_PROTOCOL_NOTIFY_ENTRY{  gEfiSecurityArchProtocolGuid,    // 安全架构协议  gCpuArchProtocolGuid,           // CPU 架构协议  gMetronomeArchProtocolGuid,      // 时钟架构协议  gTimerArchProtocolGuid,           // 定时器架构协议  gBdsArchProtocolGuid,             // 启动设备架构协议  gWatchdogTimerArchProtocolGuid,    // 软件车子架构协议  gRuntimeArchProtocolGuid,          // 运行时架构协议  gVariableArchProtocolGuid,         // 变量架构协议  gVariableWriteArchProtocolGuid,     // 变量写入架构协议  gCapsuleArchProtocolGuid,           // 系统补丁架构协议  gMonotonicCounterArchProtocolGuid,  // 单调计数器架构协议  gResetArchProtocolGuid,             // 重置架构协议  gRealTimeClockArchProtocolGuid,     // 实时钟架构协议  NULL

这些协议的安装顺序非常关键,通常要求遵循一定的优先级顺序进行安装,以确保系统的稳定性和一致性。


系统表的填充与初始化

系统表和运行时服务表中的具体接口在 EFIST(EFI引导体)运行的不同阶段会逐步被初始化。例如,以下是 RealTimeClock 模块中初始化时间服务的代码片段:

EFI_STATUSInitializeRealTimeClock(  IN EFI_HANDLE ImageHandle,  IN EFI_SYSTEM_TABLE *SystemTable) {  EFI_STATUS Status;  Status = LibRtcInitialize(ImageHandle, SystemTable);  if (Status != EFI_SUCCESS) {    return Status;  }  // 初始化时间相关的运行时服务接口  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;}

这个代码段展示了如何将实时钟功能初始化到系统表中,并确保时间服务能够正确运行。类似的步骤会在各个模块中按照自己的需求进行。


总结与展望

通过以上详细的解读,我们可以清楚地看到,系统表和相关服务表在UEFI系统中的核心作用。理解和使用这些表在开发 UE speaker 的固件drv或其他 UE-Compatible 系统程序中至关重要。随着 UEInstaller 和其它工具的不断成熟,随着对 UE_ARCH_PROTOCOL 的深入理解,开发 UE-Compatible 系统将变得越来越高效和自动化。

在实际开发中,建议对上述的每个接口和协议进行深入理解,利用相关工具和调试方法进行验证,以确保系统的稳定性和兼容性。

转载地址:http://ryodz.baihongyu.com/

你可能感兴趣的文章
Mysql 分页
查看>>
Mysql 分页语句 Limit原理
查看>>
MySQL 创建新用户及授予权限的完整流程
查看>>
mysql 创建表,不能包含关键字values 以及 表id自增问题
查看>>
mysql 删除日志文件详解
查看>>
mysql 判断表字段是否存在,然后修改
查看>>
mysql 协议的退出命令包及解析
查看>>
mysql 取表中分组之后最新一条数据 分组最新数据 分组取最新数据 分组数据 获取每个分类的最新数据
查看>>
mysql 多个表关联查询查询时间长的问题
查看>>
mySQL 多个表求多个count
查看>>
mysql 多字段删除重复数据,保留最小id数据
查看>>
MySQL 多表联合查询:UNION 和 JOIN 分析
查看>>
MySQL 大数据量快速插入方法和语句优化
查看>>
mysql 如何给SQL添加索引
查看>>
mysql 字段区分大小写
查看>>
mysql 字段合并问题(group_concat)
查看>>
mysql 字段类型类型
查看>>
MySQL 字符串截取函数,字段截取,字符串截取
查看>>
MySQL 存储引擎
查看>>
mysql 存储过程 注入_mysql 视图 事务 存储过程 SQL注入
查看>>