2. ACPI核心概念
ACPI(高级配置与电源管理接口)的核心并非仅仅是几张表,而是一个完整的、面向对象的解释型执行环境。要深入理解 ACPI 的启动配置与电源管理行为,必须掌握其四大核心概念:Namespace(命名空间)、Device(设备)、Method(方法) 与 Control Method(控制方法)。它们是 ACPI 固件与操作系统交互的基石。
2.1 ACPI Namespace(命名空间)
Namespace 是 ACPI 固件在系统启动时构建的一棵全局树状数据结构,用于描述系统中的所有硬件设备、功能对象及其相互关系。操作系统通过遍历 Namespace 来发现硬件拓扑,并调用其中的对象执行电源管理操作。
2.1.1 Namespace 的构建与加载
- RSDP/XSDT 定位: 操作系统引导时,首先在内存中定位 RSDP(根系统描述指针),进而找到 XSDT(扩展系统描述表)。
- DSDT 加载: XSDT 指向 DSDT(差异化系统描述表),这是 Namespace 的主干,包含大部分平台设备定义。
- SSDT 动态追加: 操作系统加载 DSDT 后,继续解析 XSDT 中列出的所有 SSDT(辅助系统描述表)。SSDT 用于向 Namespace 中追加或覆盖对象,常用于处理器性能状态、OEM 特定功能等。
- 树形结构生成: ACPI 解释器逐条解析 AML(ACPI 机器语言)字节码,执行
Scope()、Device()、Processor()等操作符,在内存中构建完整的树。
acpidump 和 iasl 反编译 DSDT/SSDT 是排查此类问题的标准手段。
2.1.2 Namespace 路径与引用
Namespace 中的每个对象都有一个唯一的路径名,遵循类似文件系统的绝对路径和相对路径规则。
| 路径类型 | 示例 | 说明 |
|---|---|---|
| 绝对路径 | \_SB_.PCI0.SBRG.EC0 |
以根节点 "\" 开头,完整描述从根到目标对象的路径。 |
| 相对路径 | ^PCI0.LPCB.EC0 |
使用 "^" 表示父节点,从当前作用域向上回溯。 |
| 名称路径 | 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 设备。
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 | 电池 | 电池信息查询 | 返回电池的型号、设计容量、电压等信息 |
2.4 核心概念关系总结
Namespace、Device、Method 三者构成了 ACPI 的“骨架-器官-行为”模型:
- Namespace 是骨架,定义了系统的整体拓扑结构。
- Device 是器官,是 Namespace 中的功能节点,代表具体的硬件单元。
- Method / Control Method 是行为,附着在 Device 或全局节点上,定义了硬件如何被操作。
Sleep() 指令或低效的轮询循环,将直接拖慢系统唤醒速度。使用 ACPI 调试工具(如 acpi_call、ftrace)可以精确测量每个 Control Method 的执行时间。