本文共 5485 字,大约阅读时间需要 18 分钟。
UEFI(Unified Extensible Firmware Interface,通用可扩展固件接口)是现代计算机系统中核心的固件接口规范。其架构中最为关键且复杂的部分便是系统表(System Table)。本文将深入探讨UEFI系统表的相关内容,包括其构建过程、 Boot Service Table 和 Runtime Service Table 的功能划分,以及如何利用这些服务表开发与UEFI兼容的系统程序。
系统表(System Table)是UEFI固件的构建基石,里面包含了运行时服务表、设备控制表、 Guthiิศ ซ. 等多个重要接口和数据结构。系统表的主要内容包括:
QE128值,用于验证系统表的完整性,确保它是可信的UEFI系统表。
QE16值,表示系统表的版本。
QE32值,表示系统表的头部大小。
QE32值,用来校验系统表的完整性。
QE32值,用于系统表的VESA(视频电子记忆排序)等轻量级引导程 SHOWDEVICES 接口。
指向一个设备地址,存储了当前固件的供应商ID和相关信息。
QE16值,表示固件的版本信息。
指向与控制台相关的输入接口。
指向与控制台相关的输出接口。
指向与标准错误设备相关的输入接口。
这是系统表中最重要的字段之一。这个指针指向了UEFI运行时服务表,里面包含了大量常用固件接口,如 Start、ExitBootServices 等。
QE32值,表示系统表中包含的其他配置表的数量。
这是一个可选字段,可用于存储系统某些特定固件实现的补充信息。
通过以上结构可以看出,系统表的核心作用是作为固件编程的入口,程序通过它来访问系统所需的各种服务和资源。
系统表的创建过程是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 是系统表中最基本的服务表类型之一,里面包含了UEFI启动过程中常用的接口和函数。这些服务包括事件管理、内存管理、协议安装等。以下是 Boot Service Table 中的主要函数分类:
CreateEventCreateEventExCloseEventSignalEventWaitForEventCheckEventSetTimerRaiseTPLRestoreTPL这些函数为系统在启动过程中提供了事件管理的能力,常用于启动进程调度、任务优先级控制等场景。
AllocatePagesFreePagesGetMemoryMapAllocatePoolFreePool这些函数为系统提供了内存管理的基本接口,可以用来分配和释放物理内存或虚拟内存。
InstallProtocolInterfaceUninstallProtocolInterfaceReinstallProtocolInterfaceRegisterProtocolNotifyLocateHandleHandleProtocolLocateDevicePathOpenProtocolCloseProtocolOpenProtocolInformationConnectControllerDisconnectController这些函数让系统能够管理设备协议,安装和删除协议接口,定位支持特定协议的设备。
LoadImageStartImageUnloadImageEFI_IMAGE_ENTRY_POINTExitExitBootServices这些函数控制着图像的加载与运行,确保固件能够正确执行各个阶段的程序。
SetWatchDogTimerStallCopyMemSetMemGetNextMonotonicCountInstallConfigurationTableCalculateCrc32这些函数提供了一系列通用接口,可用于时间管理、调度控制、数据校验等。
与 Boot Service Table 不同, Runtime Service Table 在启动完成后进入运行时阶段仍然有效。它提供了一系列用于操作系统级别的服务接口,如变量管理、时间控制、虚拟内存管理等。
GetVariableGetNextVariableNameSetVariableQueryVariableInfo这些函数用于管理和访问系统中定义的 EFI 变量,常用于存储和运行时配置信息。
GetTimeSetTimeGetWakeupTimeSetWakeupTime这些函数用于管理系统时间和唤醒时间,确保系统能够正确进行时间更新和恢复。
SetVirtualAddressMapConvertPointer这些函数用于转换物理地址和虚拟地址,便于操作系统在虚拟化环境中使用物理内存。
GetNextHighMonotonicCountResetSystemUpdateCapsuleQueryCapsuleCapabilities这些函数提供了平台运行时的高级功能,如重置系统、管理加密硬件等。
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/