本附錄整理各平台的工具安裝步驟。全書實作至少需要 ; 建議完整安裝 acpica-tools 與 QEMU。

Linux

\(sudo apt update\) sudo apt install acpica-tools # iasl, acpidump, acpixtract, acpiexec \(sudo apt install qemu-system-x86 ovmf # QEMU + UEFI firmware (optional) \end{shell} \begin{shell}[title={Fedora / RHEL}]\) sudo dnf install acpica-tools \(sudo dnf install qemu-kvm edk2-ovmf \end{shell} \section{macOS} \begin{shell}\) brew install acpica # iasl, acpiexec, acpixtract \(brew install qemu \end{shell} macOS 沒有 \code{/sys/firmware/acpi},抓取實機 ACPI tables 的練習 (第 22 章、Project 5)請在 Linux 實體機或虛擬機上進行。 \section{驗證安裝} \begin{shell}\) iasl -v Intel ACPI Component Architecture ASL+ Optimizing Compiler/Disassembler version 20230628

\(echo 'DefinitionBlock ("t.aml", "SSDT", 2, "TEST", "TEST", 1) {}' > t.dsl\) iasl t.dsl && ls t.aml ASL Input: t.dsl - 1 lines, 55 bytes, 0 keywords AML Output: t.aml - 36 bytes, 0 named objects t.aml

建議的專案目錄結構

acpi-lab/ ├── src/ ← 自己寫的 .dsl ├── build/ ← iasl 產出的 .aml ├── dump/ ← acpidump 取得的機器表 └── notes/ ← 分析筆記與機器地圖

ACPI 預定義物件速查表

以下按用途分類整理本書用到的預定義物件(完整清單見 ACPI Spec 第 5.6.6 節與第 6 章)。

識別與列舉

lL9.2cm 物件 & 用途
& Hardware ID:driver 綁定依據(EISA ID 或 8 字元字串)
& Compatible ID:相容識別碼(單一或 Package)
& Unique ID:同 多實例時區分用
& 可列舉匯流排上的位址(如 PCI 的 device/function)
& PCI class code(給無 的裝置)
& 裝置的人類可讀名稱(Unicode)
& 插槽編號(slot user number)

狀態與資源

lL9.2cm 物件 & 用途
& 裝置狀態位元圖(見下表)
& 裝置初始化方法(namespace 載入後呼叫)
& OperationRegion handler 可用性通知
& 目前使用的硬體資源(ResourceTemplate)
& 可能的資源組態
& 設定資源組態
& 停用裝置資源解碼
& Device Specific Data:key-value 裝置屬性
& Device Specific Method:UUID 分派的萬用方法

回傳值位元定義:

clL7.2cm 位元 & 意義 & 說明
bit 0 & Present & 裝置存在
bit 1 & Enabled & 已啟用並解碼資源
bit 2 & Show in UI & 應顯示於使用者介面
bit 3 & Functioning & 運作正常(0 = 故障)
bit 4 & Battery Present & 電池裝置專用

裝置電源管理

lL9.2cm 物件 & 用途
– & 將裝置切換到 D0–D3 的方法
– & 各 D-state 所需的 PowerResource 列表
/ / & PowerResource 的開、關、查詢
& 喚醒能力:GPE 編號 + 最低可喚醒 S-state
/ & 啟用/設定裝置喚醒
– & 各 S-state 下可喚醒的最深 D-state

系統睡眠

lL9.2cm 物件 & 用途
& Prepare To Sleep:進睡眠前韌體準備
& 喚醒後處理,回傳喚醒狀態
& Transition To State:睡眠轉換前後各呼叫一次
– & 各 S-state 的 SLP_TYP 值(Package)

電池、按鍵與熱管理

lL9.2cm 物件 & 用途
/ & 電池靜態資訊(設計容量等)
& 電池動態狀態(電量、充放電)
& 上蓋狀態(1 = 開)
& 熱區目前溫度(單位 0.1 K)
/ / & Passive/Critical/Hibernate 觸發點
– & Active cooling 觸發點(風扇檔位)
/ / & CPU P-state 表/控制暫存器/上限
/ & CPU C-state 表/相依性

常用 Notify 代碼

clL7.4cm 代碼 & 名稱 & 典型用途
& Bus Check & 重新列舉整條匯流排
& Device Check & 檢查裝置存在狀態(熱插拔)
& Device Wake & 裝置要求喚醒
& Eject Request & 退出請求
& 裝置自訂 & 電池狀態改變、熱區溫度變化等
& 裝置自訂 & 熱區 trip point 改變、電池資訊改變等

工具指令速查

iASL 常用旗標

lL8.6cm 指令 & 用途
& 編譯,產生
& 反組譯,產生
& 反組譯時解析外部(SSDT)符號
& 另輸出 C hex 陣列(EDK II 嵌入用)
& 產生 ASL/AML 對照 listing()
& 指定輸出檔名
& 抑制特定編號的警告
& 取得系統 ACPI tables(僅 Windows;Linux 用 acpidump)
/ & 說明/版本

取表與執行

\(sudo acpidump > acpi.out # dump all tables\) acpixtract -a acpi.out # split into dsdt.dat, ssdt1.dat, ... \(iasl -e ssdt*.dat -d dsdt.dat # disassemble with externals \end{shell} \begin{shell}[title={acpiexec 常用指令}]\) acpiexec dsdt.dat # load table(s) into userspace interpreter - namespace # dump whole namespace - find _HID # find objects by name - execute _SB.DEV0.TEST # run a method - debug _SB.DEV0.TEST # single-step a method - quit

Linux ACPI 觀察點

lL8.2cm 路徑/指令 & 用途
& 原始 ACPI tables(可直接 dd 出來)
& 列舉出的 ACPI 裝置(path、hid、status)
& GPE 觸發計數(抓 GPE storm)
& 執行期調整 debug_layer/debug_level
& 開機與執行期 ACPI 訊息
& 開機參數:開啟 AML Debug 輸出

ACPI Error Code 對照表

ACPICA 的錯誤碼以 開頭,出現在 kernel log 與 acpiexec 輸出中。 完整定義見 ACPICA 原始碼 。

lL4.3cmL5.2cm 錯誤碼 & 意義 & 典型成因與修法
& 名稱重複建立 & NotSerialized 方法內 被重入;SSDT 與 DSDT 同名衝突。 改 Serialized 或改名。
& 找不到參照的物件 & 引用不存在的名稱;SSDT 缺 ;韌體版本差異。 用 防禦。
& 運算元型別錯誤 & 對 Package 做算術、把 Buffer 當 Integer 用。 檢查隱含轉換規則(第 4 章)。
& Arg 未初始化 & 呼叫端傳的參數數量不足。核對方法宣告的參數個數。
& Local 未初始化 & 某分支忘了先賦值就讀取 LocalX。
& Package 索引越界 & 超出 Package 長度。先用 檢查。
& Buffer 索引越界 & CreateXXXField 或 Index 超出 Buffer 大小。
& 資源描述子型別錯誤 & 回傳的 ResourceTemplate 內容不合法。
& While 迴圈逾時 & 輪詢硬體旗標永遠等不到。檢查 Field 位址與硬體狀態。
& 逾時 & Acquire mutex/Wait event 逾時。檢查鎖的釋放路徑。

除錯時的定位順序(詳見第 24 章):