acpi-mcp について
acpi-mcpは、OS開発者向けにファームウェアのACPIテーブルを読み取り、内容を説明するMCPサーバーです。稼働中のQEMUゲストまたはファイルから読み込み、必要に応じてiaslでAMLを逆アセンブルできます。
主な機能
- 01稼働中のQEMUからACPIテーブルを読取
- 02ディレクトリからテーブルを読込
- 03ACPIテーブルのデコードと説明
- 04ISA IRQ、GSI、I/O APICの対応付け
- 05OS開発向けハードウェア情報の検索
- 06iaslによるAMLの逆アセンブル
活用シーン
- 01QEMUゲスト内のACPIテーブルの確認
- 02カーネルの割り込みルーティングの確認
- 03OS設定に必要なハードウェア情報の調査
- 04iaslを使ったAMLの確認
MCP 対応
MCPクライアントに、ACPIテーブルの読み込み、一覧表示、デコード、検索のツールを提供し、ダンプや任意の逆アセンブルにも対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
8掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| host | string | いいえ | |
| name | string | はい | |
| path | any | いいえ | |
| port | any | いいえ | |
| resume | boolean | いいえ | |
| boot_wait_s | number | いいえ |
詳細
acpi-mcp
AI エージェントにファームウェアの ACPI テーブルを読み取らせ、その内容を説明させましょう。
acpi-mcp は、ACPI テーブルを読み取り、OS 開発者向けに説明する MCP サーバーです。CPU の数と APIC ID、I/O APIC の場所、再マッピングされる ISA IRQ、HPET と PCIe コンフィグレーション空間の場所、マシンの電源を切る方法やリセットする方法を示す正確なポート書き込みについて確認できます。
次の 3 つの場所からテーブルを読み取ります。
- 稼働中の QEMU ゲスト:QEMU の gdbstub を通じてゲストの物理メモリから読み取ります(ゲストがページングを有効にした後でも動作します)。
- テーブルファイルのディレクトリ:Linux の
/sys/firmware/acpi/tables、または任意のマシンからのacpidump -bの出力を読み取ります。 - 必要に応じて、
iaslがインストールされていれば AML を逆アセンブルできます。それ以外には何も必要ありません。
qemu-mcp(VM の起動と操作)および 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」の次に、趣味で OS を開発する人が必ず直面する最初の難関です。SMP、I/O APIC、HPET、PCIe、電源オフには ACPI が必要です。テーブルはファームウェアメモリ全体に広がるバイナリ構造で、仕様書は 1,000 ページを超え、バグは表面化しません。IRQ0 → GSI2 のオーバーライドを見落とすと、タイマーはまったく作動しなくなります。このサーバーは、ファームウェアが実際に作成したテーブルを読み取り、プログラムすべき内容を回答します。
調べた限り、ACPI テーブルを読み取って説明する MCP サーバーはほかにありません。
インストール
pip install acpi-mcp
claude mcp add acpi -- acpi-mcp
使い方
gdbstub(-s)を有効にして QEMU を起動します。ACPI テーブルが作成されるまでファームウェアを実行させるため、-S を指定してもかまいません。
qemu-system-x86_64 -M q35 -smp 2 -kernel kernel.elf -s -S
次のようにエージェントに尋ねます。「ポート 1234 の VM から ACPI テーブルを読み込んで、キーボード割り込みを I/O APIC 経由でルーティングする方法を教えてください」
Linux マシンでは、root 権限でそのマシン自身のテーブルを読み取れます。
acpi_load(name="host", path="/sys/firmware/acpi/tables")
ツール
| ツール | 機能 |
|---|---|
acpi_load | port=(稼働中の VM。boot_wait_s でファームウェアを事前に実行し、resume でその後ゲストを実行するかどうかを選択)または path=(ディレクトリ)から、名前を指定してテーブルを読み込みます。 |
acpi_tables | すべてのテーブルのアドレス、長さ、チェックサム、OEM、およびテーブルの用途を一覧表示します。 |
acpi_table | 1 つのテーブルをデコードして説明します。対象:FADT、MADT、HPET、MCFG、DSDT/SSDT、FACS、RSDT/XSDT、WAET、RSDP。 |
acpi_interrupt_routing | ISA IRQ 0~15 を GSI および I/O APIC ピンに対応付け、極性とトリガーモードも示します。 |
acpi_find | OS 開発に関する質問に回答します。対象:シャットダウン、リセット、HPET、PCI コンフィグレーション、CPU、IRQ ルーティング、PM タイマー、キーボード、シリアル、RTC 世紀、SCI。 |
acpi_dump | テーブルの生バイト列を 16 進ダンプします。 |
acpi_disassemble | iasl -d を使って AML を ASL に変換します。iasl がインストールされている場合に利用できます。 |
acpi_sets | 読み込み済みのテーブルセットを一覧表示します。 |
ライブ VM の読み取り方法
- gdbstub に接続します。デバッガーが接続されると、QEMU はゲストを一時停止します。
- QEMU の
Qqemu.PhyMemMode:1を使用して、スタブを物理メモリに切り替えます。これにより、ゲストでページングが有効になっていても、ACPI の物理ポインターが機能します。このパケットに対応していないスタブでは、仮想アドレスを読み取り、その旨を出力に示します。 - EBDA と
0xE0000-0xFFFFFを検索して、チェックサムが有効なRSD PTRを探し、その後 XSDT(または RSDT)、FADT、DSDT、FACS を順にたどります。 - CPU がまだファームウェアを実行していない場合(
-S)、完全でチェックサムが有効なテーブル一式が見つかるまで、ゲストを短時間ずつ実行します。見つかるとすぐに返します。 D;1でデタッチし、ゲストの実行を再開します。たとえば、-Sの VM に gdbstub-mcp を接続する前など、ゲストを一時停止したままにするにはresume=Falseを指定します。QEMU で同時に使用できるデバッガーは 1 つだけです。
制限事項
- AML リーダーは構造化ウォーカーであり、インタープリターではありません。 デバイスを記述する Scope、Device、Name オブジェクトを解析し、Method 本体はスキップします。デバイスを非表示にする
_STAなど、メソッドが実行時に計算する内容は評価されません。スコープレベルのIfなどで領域をバイトスキャンする必要がある場合は、その旨を出力に示します。正確な一覧を取得するには、acpi_disassemble(iasl)を使用してください。 - **UEFI ゲスト(OVMF)**は、RSDP を BIOS 領域ではなく EFI システムテーブル経由で OS に渡すため、ライブ検索では見つかりません。現時点では、ディレクトリからこれらのテーブルを読み込んでください(
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 サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。