mcpField
A
acpi-mcp

acpi-mcp

本地服务
github.com/0xmortuex开发工具03 周前更新

关于 acpi-mcp

acpi-mcp 是面向操作系统开发者的 MCP 服务,可读取并解释固件 ACPI 表。它支持从运行中的 QEMU 客户机或文件加载表,并可选用 iasl 反汇编 AML。

主要功能

  1. 01读取运行中 QEMU 的 ACPI 表
  2. 02从目录加载表文件
  3. 03解码并解释 ACPI 表
  4. 04映射 ISA IRQ、GSI 与 I/O APIC
  5. 05查找操作系统开发所需硬件信息
  6. 06使用 iasl 反汇编 AML

适用场景

  1. 01检查 QEMU 客户机中的 ACPI 表
  2. 02核对内核的中断路由
  3. 03查找操作系统配置所需硬件信息
  4. 04通过 iasl 查看 AML

MCP 相关

向 MCP 客户端提供加载、列出、解码和搜索 ACPI 表的工具,也支持转储表数据或选择性反汇编。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"0xmortuex-acpi": {
"command": "uvx",
"args": [
"acpi-mcp"
]
}
}
}
启动命令uvx acpi-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiacpi-mcp0.1.0

工具

8

收录的工具列表 · 更新于 3 周前

参数类型必填说明
hoststring否
namestring是
pathany否
portany否
resumeboolean否
boot_wait_snumber否

详细介绍

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列出已加载的表集。

实时读取虚拟机的方式

  1. 它连接到 gdbstub。调试器连接时,QEMU 会暂停客户机。
  2. 它通过 QEMU 的 Qqemu.PhyMemMode:1 将存根切换到物理内存模式,这样即使客户机启用了分页,ACPI 的物理指针也能正常工作。对于不支持此数据包的存根,它会读取虚拟地址并在输出中注明。
  3. 它会在 EBDA 和 0xE0000-0xFFFFF 范围内搜索经过校验和验证的 RSD PTR ,然后遍历 XSDT(或 RSDT)、FADT、DSDT 和 FACS。
  4. 如果 CPU 尚未运行固件(-S),它会分短时间片运行客户机,直到存在一组完整且校验和有效的表。找到后立即返回。
  5. 它会通过 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

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。