UEFI学习笔记(十):系统表与ACPI表的遍历

一、概述

在 UEFI 系统表中,有几个关键的表用于提供系统信息、服务和硬件抽象。这些表可以通过 EFI_SYSTEM_TABLE 访问,常见的 UEFI 系统表如下:

1、EFI_SYSTEM_TABLE (系统表)

EFI_SYSTEM_TABLE 是一个指针,包含多个服务和系统信息。

包含以下几个重要表:

2、EFI_BOOT_SERVICES (引导服务表):

提供在引导期间可用的功能(如内存分配、事件管理、协议处理等)。

3、EFI_RUNTIME_SERVICES (运行时服务表):

提供操作系统加载后仍可使用的服务(如变量管理、时间功能和固件更新等)。

4、EFI_CONFIGURATION_TABLE (配置表):

包含各种硬件信息和平台信息,包含 ACPI、SMBIOS、HOB(Hand-off Block)等表。

二、遍历ACPI表

c 复制代码
VOID ListAllAcpiTables(VOID)
{
  UINTN     i, j, EntryCount;
  CHAR8     strBuff[20];
  UINT64    *EntryPtr;
  EFI_GUID  AcpiTableGuid  = ACPI_TABLE_GUID;
  EFI_GUID  Acpi2TableGuid = EFI_ACPI_TABLE_GUID;
  EFI_CONFIGURATION_TABLE   *configTab = NULL;  
  EFI_ACPI_DESCRIPTION_HEADER           *XSDT, *Entry;
  EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *Root;

  Print(L"List All ACPI Tables:\n");
  configTab = gST->ConfigurationTable;
  
  for (i = 0; i < gST->NumberOfTableEntries; i++) {   
    // Step1: 查找 ACPI 表
    if ((CompareGuid(&configTab->VendorGuid, &AcpiTableGuid) == 0) ||
        (CompareGuid(&configTab->VendorGuid, &Acpi2TableGuid) == 0)) { 
      Print(L"Found ACPI table: %g\n", &configTab->VendorGuid); 
      Root = configTab->VendorTable;
      Print(L"ROOT SYSTEM DESCRIPTION @[0x%p]\n", Root);

      // Step2: 检查修订版本(只接受修订版本 >= 2)
      if (Root->Revision >= EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {
        // Step3: 获取 XSDT 表地址
        XSDT = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Root->XsdtAddress;
        EntryCount = (XSDT->Length - sizeof(EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64);

        Print(L"XSDT address = [0x%p]\n", XSDT);
        Print(L"XSDT-Length = 0x%x\n", XSDT->Length);
        Print(L"Number of ACPI Tables = %d\n", EntryCount);

        // Step4: 遍历每个 ACPI 表并输出信息
        EntryPtr = (UINT64 *)(XSDT + 1);
        for (j = 0; j < EntryCount; j++, EntryPtr++) {
          Entry = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(*EntryPtr));

          // 输出每个表的签名、长度和校验和等基本信息
          ZeroMem(strBuff, sizeof(strBuff));
          CopyMem(strBuff, &(Entry->Signature), sizeof(UINT32));
          Print(L"Table Signature: %a\n", strBuff);
          Print(L"Table Address: 0x%p\n", Entry);
          Print(L"Table Length: 0x%x\n", Entry->Length);
          Print(L"Table Checksum: 0x%x\n", Entry->Checksum);

        }
      }
    }
    configTab++;
  }
}

整个函数 ListAllAcpiTables 的逻辑是:

1)遍历系统配置表。

  1. 查找 ACPI 表,并验证 RSDP 的版本。

  2. 从 RSDP 获取 XSDT 表的地址,并计算其中的 ACPI 表数量。

  3. 遍历所有 ACPI 表,打印它们的基本信息

相关推荐
RickyWasYoung5 小时前
【笔记】智能汽车、电动汽车政策文件
笔记·汽车
Ma0407136 小时前
【机器学习】监督学习、无监督学习、半监督学习、自监督学习、弱监督学习、强化学习
人工智能·学习·机器学习
小熊officer6 小时前
Nginx学习
运维·学习·nginx
秋邱6 小时前
价值升维!公益赋能 + 绿色技术 + 终身学习,构建可持续教育 AI 生态
网络·数据库·人工智能·redis·python·学习·docker
Three~stone7 小时前
Matlab2025b的安装教程(附安装包和密钥破解文件)
学习·mysql·持续部署
爱学习的大牛1237 小时前
如何系统学习网络渗透测试:从入门到精通的完整指南
网络·学习
落子摘星7 小时前
suricata学习杂记(一)
学习·modbus·suricata·pdu
charlie1145141918 小时前
深入理解C/C++的编译链接技术6——A2:动态库设计基础之ABI设计接口
c语言·开发语言·c++·学习·动态库·函数
white-persist8 小时前
【攻防世界】reverse | Reversing-x64Elf-100 详细题解 WP
c语言·开发语言·网络·python·学习·安全·php
love530love8 小时前
【保姆级教程】Windows + Podman 从零部署 Duix-Avatar 数字人项目
人工智能·windows·笔记·python·数字人·podman·duix-avatar