关于 acpi-mcp
acpi-mcp 是面向操作系统开发者的 MCP 服务,可读取并解释固件 ACPI 表。它支持从运行中的 QEMU 客户机或文件加载表,并可选用 iasl 反汇编 AML。
主要功能
- 01读取运行中 QEMU 的 ACPI 表
- 02从目录加载表文件
- 03解码并解释 ACPI 表
- 04映射 ISA IRQ、GSI 与 I/O APIC
- 05查找操作系统开发所需硬件信息
- 06使用 iasl 反汇编 AML
适用场景
- 01检查 QEMU 客户机中的 ACPI 表
- 02核对内核的中断路由
- 03查找操作系统配置所需硬件信息
- 04通过 iasl 查看 AML
MCP 相关
向 MCP 客户端提供加载、列出、解码和搜索 ACPI 表的工具,也支持转储表数据或选择性反汇编。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
8收录的工具列表 · 更新于 3 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| host | string | 否 | |
| name | string | 是 | |
| path | any | 否 | |
| port | any | 否 | |
| resume | boolean | 否 | |
| boot_wait_s | number | 否 |
详细介绍
acpi-mcp
让你的 AI Agent 读取固件的 ACPI 表,并告诉你它们的含义。
acpi-mcp 是一个 MCP 服务,可读取 ACPI 表 并为操作系统开发者解读这些表。它会介绍 CPU 数量及其 APIC ID、 I/O APIC 所在位置、哪些 ISA IRQ 已重新映射、HPET 和 PCIe 配置 空间的位置,以及让机器关机或重置所需的确切端口写入操作。
它可以从三个来源读取表:
- 正在运行的 QEMU 虚拟机:通过 QEMU 的 gdbstub 从虚拟机物理内存中读取(即使 虚拟机启用了分页,也能正常工作);
- 表文件目录:Linux 的
/sys/firmware/acpi/tables,或任意机器上acpidump -b的输出; - 可选的 AML 反汇编:如果已安装
iasl,即可使用。其他功能都不需要它。
它与 qemu-mcp(启动和操控虚拟机) 以及 gdbstub-mcp(调试内核)配套使用。
效果展示
以下是从 QEMU 11(-M q35 -smp 2)虚拟机中实时读取的实际输出:
> acpi_table MADT
MADT revision 3: local APIC base 0xfee00000 (dual 8259 PICs present: mask them before using the APIC)
2 usable CPU(s), APIC IDs [0, 1]
The BSP is usually APIC ID 0; start the others with INIT-SIPI-SIPI
I/O APIC id 0 at 0xfec00000, GSI base 0
Interrupt source overrides (legacy ISA IRQ -> GSI):
IRQ0 -> GSI 2 (I/O APIC 0 pin 2), bus default, bus default - this is why the PIT timer shows up on I/O APIC pin 2, not 0
IRQ9 -> GSI 9 (I/O APIC 0 pin 9), active high, level - non-ISA polarity/trigger: program the redirection entry to match
...
Local APIC NMI on LINT1 for all CPUs (bus default, bus default) - program LVT LINT1 as NMI
> acpi_find "how do I shut down the machine?"
Soft power-off (S5): \_S5_ = SLP_TYPa 0, SLP_TYPb 0
1. If SMI_CMD (0xb2) is non-zero and SCI_EN (bit 0 of PM1a_CNT) is clear, enable ACPI: outb(0xb2, 0x2) and wait for SCI_EN
2. outw(0x604, 0x2000) # SLP_TYPa << 10 | SLP_EN (bit 13)
> acpi_find "reboot"
Reset: write 0xf to I/O port 0xcf9 (8-bit) (FADT RESET_REG, RESET_REG_SUP set). Fall back to the 8042 if it returns.
> acpi_find "pci config space"
MCFG: PCI Express ECAM (memory-mapped config space)
segment 0, buses 0-255: base 0xb0000000 (256 MiB)
config address of bus B, device D, function F, offset O = 0xb0000000 + ((B - 0) << 20 | D << 15 | F << 12 | O)
> acpi_table DSDT
8491 bytes of AML bytecode, 37 Device objects
Recognised devices:
\_SB_.PCI0 PNP0A08 (compatible PNP0A03) PCI Express host bridge
\_SB_.HPET PNP0103 HPET
\_SB_.PCI0.SF8_.KBD_ PNP0303 PS/2 keyboard (8042)
\_SB_.PCI0.SF8_.COM1 PNP0501 16550 serial port (COM)
...
这些操作步骤经过实际测试,而不只是打印出来。 集成测试会将
acpi_find 给出的确切指令写入正在运行的虚拟机,执行指令并检查结果:
关机操作步骤能关闭 -M pc 和 -M q35,重置操作步骤能重置 q35。作为对照,
只运行 hlt 的测试会让虚拟机继续运行。
为什么需要它
ACPI 是每个业余操作系统在完成“hello world”后遇到的第一道难关。SMP、 I/O APIC、HPET、PCIe 和关机都需要用到它。ACPI 表是分布在固件内存中的二进制结构, 规范长达一千多页,而错误往往悄无声息:如果漏掉 IRQ0 → GSI2 的覆盖项, 计时器就永远不会触发。这个服务会读取固件实际构建的表,并告诉你要配置什么。
据我所知,没有其他 MCP 服务会读取或解读 ACPI 表。
安装
pip install acpi-mcp
claude mcp add acpi -- acpi-mcp
用法
使用 gdbstub(-s)启动 QEMU。可以加上 -S,因为 acpi-mcp 会让固件继续运行,
直到表创建完成:
qemu-system-x86_64 -M q35 -smp 2 -kernel kernel.elf -s -S
然后可以向你的 Agent 提出类似这样的请求:“从端口 1234 上的虚拟机加载 ACPI 表, 告诉我如何通过 I/O APIC 路由键盘中断。”
在 Linux 机器上,你可以读取它自己的表(需要 root 权限):
acpi_load(name="host", path="/sys/firmware/acpi/tables")
工具
| 工具 | 功能 |
|---|---|
acpi_load | 按名称加载表:可从 port= 加载(实时虚拟机;boot_wait_s 可让固件先运行;resume 用于选择之后是否继续运行虚拟机),也可从 path= 加载(目录)。 |
acpi_tables | 列出所有表:地址、长度、校验和、OEM,以及表的用途。 |
acpi_table | 解码并解读单个表:FADT、MADT、HPET、MCFG、DSDT/SSDT、FACS、RSDT/XSDT、WAET、RSDP。 |
acpi_interrupt_routing | 将 ISA IRQ 0-15 映射到 GSI 和 I/O APIC 引脚,并提供极性和触发模式。 |
acpi_find | 回答操作系统开发相关问题:关机、重置、HPET、PCI 配置、CPU、IRQ 路由、PM 计时器、键盘、串口、RTC 世纪值、SCI。 |
acpi_dump | 以十六进制转储表的原始字节。 |
acpi_disassemble | 如果已安装 iasl,则将 AML 转换为 ASL。 |
acpi_sets | 列出已加载的表集。 |
实时读取虚拟机的方式
- 它连接到 gdbstub。调试器连接时,QEMU 会暂停客户机。
- 它通过 QEMU 的
Qqemu.PhyMemMode:1将存根切换到物理内存模式,这样即使客户机启用了分页,ACPI 的物理指针也能正常工作。对于不支持此数据包的存根,它会读取虚拟地址并在输出中注明。 - 它会在 EBDA 和
0xE0000-0xFFFFF范围内搜索经过校验和验证的RSD PTR,然后遍历 XSDT(或 RSDT)、FADT、DSDT 和 FACS。 - 如果 CPU 尚未运行固件(
-S),它会分短时间片运行客户机,直到存在一组完整且校验和有效的表。找到后立即返回。 - 它会通过
D;1分离连接,客户机随后继续运行。传入resume=False可让客户机保持暂停状态,例如在连接到-S虚拟机的 gdbstub-mcp 之前。QEMU 一次只允许连接一个调试器。
限制
- AML 读取器是结构化遍历器,不是解释器。 它会解析描述设备的 Scope、Device 和 Name 对象,并跳过 Method 主体。任何由方法在运行时计算的内容(例如隐藏设备的
_STA)都不会被求值。如果它不得不退回到对某个区域进行字节扫描(例如作用域级别的If),输出中会注明。要获取精确的列表,请使用acpi_disassemble(iasl)。 - UEFI 客户机(OVMF) 会通过 EFI 系统表而非 BIOS 区域将 RSDP 传递给操作系统,因此实时搜索无法找到它。目前请从目录加载这些表(
acpidump -b)。 - 目前仅支持 x86。ARM 的 ACPI(MADT 中的 GICC/GICD、GTDT)已列入待办事项。
测试
pip install ".[test]" "ruff==0.16.0" "mypy==2.3.0"
ruff check src tests && mypy --strict src
pytest tests
单元测试使用从 QEMU 捕获的真实表(tests/fixtures/tables/),因此不需要 QEMU。tests/test_qemu_integration.py 会从 pc 和 q35 上的 i386 和 x86_64 客户机读取实时表,检查 CPU 数量是否与 -smp 一致,检查 resume 语义,并在客户机内运行关机和重置操作流程。未安装的 QEMU 二进制文件会被跳过。
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。