2. ACPI核心概念

ACPI(高级配置与电源管理接口)的核心并非仅仅是几张表,而是一个完整的、面向对象的解释型执行环境。要深入理解 ACPI 的启动配置与电源管理行为,必须掌握其四大核心概念:Namespace(命名空间)、Device(设备)、Method(方法) 与 Control Method(控制方法)。它们是 ACPI 固件与操作系统交互的基石。

2.1 ACPI Namespace(命名空间)

Namespace 是 ACPI 固件在系统启动时构建的一棵全局树状数据结构,用于描述系统中的所有硬件设备、功能对象及其相互关系。操作系统通过遍历 Namespace 来发现硬件拓扑,并调用其中的对象执行电源管理操作。

关键特性: Namespace 是一个层次化的、动态可扩展的树。根节点固定为 "\"(反斜杠),所有设备、处理器、热区、电池等均作为其子节点或孙节点存在。
类比理解: 可以将 Namespace 视为 ACPI 的“文件系统”。根目录是 "\_SB_"(系统总线),其下挂载了各种设备“文件夹”(如 PCI0、CPU0、BAT0),每个“文件夹”内又包含描述设备属性和行为的“文件”(如 _HID、_STA、_PS0)。

2.1.1 Namespace 的构建与加载

  1. RSDP/XSDT 定位: 操作系统引导时,首先在内存中定位 RSDP(根系统描述指针),进而找到 XSDT(扩展系统描述表)。
  2. DSDT 加载: XSDT 指向 DSDT(差异化系统描述表),这是 Namespace 的主干,包含大部分平台设备定义。
  3. SSDT 动态追加: 操作系统加载 DSDT 后,继续解析 XSDT 中列出的所有 SSDT(辅助系统描述表)。SSDT 用于向 Namespace 中追加或覆盖对象,常用于处理器性能状态、OEM 特定功能等。
  4. 树形结构生成: ACPI 解释器逐条解析 AML(ACPI 机器语言)字节码,执行 Scope()、Device()、Processor() 等操作符,在内存中构建完整的树。
调试要点: 如果 DSDT 或 SSDT 中存在语法错误或对象引用冲突,Namespace 构建将失败,导致设备无法被操作系统识别,甚至触发 BSOD(蓝屏死机)。使用 acpidump 和 iasl 反编译 DSDT/SSDT 是排查此类问题的标准手段。

2.1.2 Namespace 路径与引用

Namespace 中的每个对象都有一个唯一的路径名,遵循类似文件系统的绝对路径和相对路径规则。

路径类型 示例 说明
绝对路径 \_SB_.PCI0.SBRG.EC0 以根节点 "\" 开头,完整描述从根到目标对象的路径。
相对路径 ^PCI0.LPCB.EC0 使用 "^" 表示父节点,从当前作用域向上回溯。
名称路径 EC0 仅在当前作用域内唯一时使用,否则需加限定符。
ACPI Namespace 树形结构示例 \ (Root) \_SB_ \_TZ_ PCI0 CPU0 BAT0 THM0 SBRG PEG0 EC0 图例 根节点 设备节点 桥/总线

2.2 Device(设备)

在 ACPI Namespace 中,Device() 是一个核心对象类型,用于声明一个物理或逻辑设备。操作系统通过解析 Device 节点下的子对象(如 _HID、_CID、_STA、_CRS)来获取设备标识、状态、资源需求等信息。

2.2.1 设备声明与标识

每个 Device 节点必须包含一个或多个标识对象,以便操作系统加载对应的驱动程序。

  • _HID (Hardware ID): 设备的唯一硬件标识符,如 "PNP0C09"(嵌入式控制器)、"ACPI0003"(电源按钮)。
  • _CID (Compatible ID): 兼容设备标识符,用于匹配通用驱动程序。
  • _UID (Unique ID): 当多个相同 _HID 的设备存在时,用于区分实例。
  • _ADR (Address): 设备在总线上的地址,常用于 PCI 设备。
实战案例: 以下是一个典型的 ACPI 设备声明片段(AML 反编译后的 ASL 表示):
Device (EC0) {
    Name (_HID, EisaId ("PNP0C09"))  // 嵌入式控制器
    Name (_UID, Zero)                // 唯一 ID 为 0
    Name (_CRS, ResourceTemplate () { // 当前资源设置
        IO (Decode16, 0x0062, 0x0062, 0x00, 0x02)
        IO (Decode16, 0x0066, 0x0066, 0x00, 0x02)
    })
    Method (_STA, 0, NotSerialized) { // 状态方法
        Return (0x0F)  // 设备存在且启用
    }
}

2.2.2 设备状态管理

ACPI 定义了四种设备电源状态(D-State),由 Device 节点下的控制方法管理:

状态 名称 功耗 恢复延迟 对应控制方法
D0 完全工作 最大 无 _PS0
D1 低功耗(设备特定) 中等 短 _PS1
D2 更低功耗(设备特定) 低 中等 _PS2
D3hot 关闭(软件可恢复) 接近零 长 _PS3
D3cold 关闭(主电源断开) 零 最长 _PS3 + 电源闸控制

2.3 Method(方法)与 Control Method(控制方法)

在 ACPI 语境中,Method 是 Namespace 中的一个可执行对象,包含一段 AML 代码。当操作系统需要查询设备信息或执行电源状态转换时,会调用相应的 Method。Control Method 是特指那些由操作系统主动调用、用于控制硬件行为的 Method,通常以 "_" 前缀命名(如 _PS0、_WAK、_PTS)。

2.3.1 Method 的声明与调用

Method 在 ASL 中通过 Method() 关键字声明,包含名称、参数数量和序列化属性。

// 声明一个控制方法:设置设备到 D0 状态
Method (_PS0, 0, Serialized) {
    // 1. 通知嵌入式控制器开启电源
    Store (0x01, Local0)
    Store (Local0, ^^EC0.SMPR)
    // 2. 等待电源稳定
    Sleep (10)
    // 3. 恢复设备时钟
    Store (One, ^^EC0.CLKE)
    // 4. 返回成功
    Return (Zero)
}
  • 参数数量: 第二个参数(如 0)表示该方法接受的参数个数。
  • 序列化属性: Serialized 表示该方法在同一时间只能被一个线程执行,避免竞态条件;NotSerialized 允许多线程并发。
  • 返回值: 使用 Return() 语句返回整数、缓冲区或包。

2.3.2 常用预定义控制方法

ACPI 规范定义了大量以 "_" 开头的控制方法,操作系统在特定事件发生时自动调用它们。

方法名 所属对象 触发时机 功能描述
_STA Device 设备枚举时 返回设备状态(存在/启用/显示/功能正常)
_PS0 / _PS3 Device 电源状态切换 将设备切换到 D0(工作)或 D3(关闭)状态
_PTS 全局 系统进入睡眠前 准备系统进入睡眠状态(S1-S4)
_WAK 全局 系统唤醒后 处理唤醒事件,恢复设备状态
_OSC Device 操作系统能力协商 操作系统向固件声明其支持的功能(如 PCIe 热插拔)
_BIF 电池 电池信息查询 返回电池的型号、设计容量、电压等信息
Control Method 调用流程:系统进入睡眠 (S3) 用户/内核请求 S3 ACPI 解释器 调用 _PTS (准备睡眠) 遍历设备调用 _PS3 写 PM1a_CNT (SLP_EN) 唤醒后调用 _WAK 硬件中断唤醒 关键控制方法 _PTS: 准备系统睡眠 _WAK: 系统唤醒处理

2.4 核心概念关系总结

Namespace、Device、Method 三者构成了 ACPI 的“骨架-器官-行为”模型:

  • Namespace 是骨架,定义了系统的整体拓扑结构。
  • Device 是器官,是 Namespace 中的功能节点,代表具体的硬件单元。
  • Method / Control Method 是行为,附着在 Device 或全局节点上,定义了硬件如何被操作。
性能优化视角: 在调试电源管理性能时,应重点关注 Device 节点下的 _PS0/_PS3 方法的执行时长。如果某个设备的 _PS0 方法中包含过长的 Sleep() 指令或低效的轮询循环,将直接拖慢系统唤醒速度。使用 ACPI 调试工具(如 acpi_call、ftrace)可以精确测量每个 Control Method 的执行时间。
Namespace、Device、Method 关系图 Namespace (命名空间) Device (设备) _HID, _STA, _CRS Method (控制方法) _PS0, _PS3, _WAK 包含