4. UEFI系统表访问
任务目标
编写一个UEFI应用程序,通过访问UEFI系统表(EFI_SYSTEM_TABLE)读取并打印固件供应商名称、固件版本、UEFI规范版本以及系统表所在内存地址。该程序在UEFI Shell环境下直接运行,用于验证系统表结构的正确访问方式。
核心实现
UEFI应用程序的入口点接收EFI_HANDLE和EFI_SYSTEM_TABLE指针。系统表头部的EFI_TABLE_HEADER结构包含固件版本和UEFI规范版本字段,而FirmwareVendor字段指向固件供应商名称的宽字符串。以下代码直接访问这些字段并格式化输出:
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/PrintLib.h>
#include <Library/DebugLib.h>
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_TABLE_HEADER *Header;
UINT32 SpecMajor;
UINT32 SpecMinor;
UINT32 FwMajor;
UINT32 FwMinor;
// 系统表头指针
Header = &SystemTable->Hdr;
// 解析UEFI规范版本 (BCD格式: 高16位为主版本, 低16位为次版本)
SpecMajor = (Header->Revision >> 16) & 0xFFFF;
SpecMinor = Header->Revision & 0xFFFF;
// 解析固件版本 (BCD格式: 高16位为主版本, 低16位为次版本)
FwMajor = (Header->FirmwareRevision >> 16) & 0xFFFF;
FwMinor = Header->FirmwareRevision & 0xFFFF;
// 打印系统表信息
SystemTable->ConOut->OutputString (
SystemTable->ConOut,
L"=== UEFI System Table Access ===\r\n"
);
// 打印系统表地址
Print(L"SystemTable Address : 0x%08x\r\n", (UINTN)SystemTable);
// 打印固件供应商
Print(L"Firmware Vendor : %s\r\n", SystemTable->FirmwareVendor);
// 打印固件版本
Print(L"Firmware Revision : %d.%d\r\n", FwMajor, FwMinor);
// 打印UEFI规范版本
Print(L"UEFI Spec Revision : %d.%d\r\n", SpecMajor, SpecMinor);
// 打印系统表签名
Print(L"Table Signature : 0x%016lx\r\n", Header->Signature);
return EFI_SUCCESS;
}
构建与运行
该程序使用EDK2构建环境编译。将上述代码保存为SystemTableAccess.c,并在包的.inf文件中声明依赖:
[Sources]
SystemTableAccess.c
[Packages]
MdePkg/MdePkg.dec
[LibraryClasses]
UefiLib
UefiApplicationEntryPoint
PrintLib
DebugLib
构建命令(在EDK2环境中):
build -p YourPackage/YourPackage.dsc -m YourPackage/SystemTableAccess.inf
将生成的SystemTableAccess.efi复制到UEFI Shell可访问的FAT分区,在Shell中执行:
fs0:\> SystemTableAccess.efi
验证方法
程序运行后应输出以下信息,通过观察输出内容判断是否成功:
- SystemTable Address:非零内存地址,通常在32位或64位地址空间内。
- Firmware Vendor:显示固件供应商名称字符串(如"American Megatrends Inc."或"Phoenix Technologies"等),非空。
- Firmware Revision:格式为
主版本.次版本,数值与固件设置界面显示的BIOS版本一致。 - UEFI Spec Revision:格式为
主版本.次版本,通常为2.7或更高版本号。 - Table Signature:固定为
0x5453595320494249(即"IBI SYST"的ASCII码),用于确认系统表结构正确。
若输出中Firmware Vendor为空或Table Signature不匹配,说明系统表访问方式有误或运行环境不是真正的UEFI模式。