世界を動かす技術を、日本語で。

ユーザースペースにおけるPCIeデバイスエミュレーションのためのLinuxカーネルフレームワーク

2026年1月20日原文(github.com)

概要

PCIem は、Linuxカーネル上でユーザ空間のみで動作する PCIeデバイスエミュレーションフレームワーク。 実ハードウェア不要で PCIeドライバの開発・テスト を実現。 BAR、DMA、割り込み などのPCIe機能を包括的にサポート。 QEMU などのユーザ空間アプリでプロトタイプ作成が可能。 MIT/GPLv2デュアルライセンス で公開。

PCIemとは何か

  • PCIem は、Linuxカーネル内で 仮想PCIeデバイス を生成するフレームワーク
  • 新規技術 により、合成カードを 正規のPCIデバイス としてホストOSに認識させる
  • 実機ハードウェア不要 でPCIeデバイスドライバの 開発・検証 を可能にする仕組み
  • PCIemフレームワーク を使い、ユーザ空間からデバイス挙動を自在にエミュレート

アーキテクチャ

  • Linuxカーネルユーザ空間 の2層構成
    • /dev/pciem デバイスファイルを介した PCIem Framework の実装
      • PCI Config SpaceBARマッピング のエミュレーション
      • INT/MSI/MSI-X割り込み の動的トリガー
      • DMA (IOMMU対応/非対応)や P2P DMA もサポート
    • Userspace PCI shim によるPCIeデバイスロジックの実装
      • ユーザ空間アプリが PCIem を通じてデバイス制御を実現
  • 既存のPCIeドライバPCIem の存在を意識せず動作可能

主な機能

  • BAR(Base Address Register)管理
    • プログラムによるBAR登録・管理機構
  • ウォッチポイント
    • CPUウォッチポイントによるイベント駆動型アーキテクチャ
  • 割り込みサポート
    • Legacy IRQ/MSI/MSI-X の全サポートと動的トリガー
  • PCI Capabilityフレームワーク
    • モジュール式PCI機能システム(内部はリンクリスト構造)
  • DMAシステム
    • IOMMU対応 DMA操作とアトミックメモリ操作サポート
  • P2P DMA
    • デバイス間ピアツーピアDMA(ホワイトリストベースのアクセス制御)
  • ユーザ空間定義型
    • PCIeプロトタイプを 任意のユーザ空間アプリ で実装可能

利用例

  • ProtoPCIemカード
    • QEMU 上でカード全体をプログラムし、初期化やコマンド処理をユーザ空間で実現
    • DOOM などのソフトウェアレンダリングゲームを動作可能
    • OpenGL 1.X ゲーム(例:tyr-glquake、xash3d)もQEMU内のカスタムOpenGLステートマシンで描画
    • DMA経由でフレームをカードに送信し、QEMUが表示

ライセンス

  • pciem_framework.c および protopciem_driver.cMIT/GPLv2デュアルライセンス
  • その他の部分は MITライセンス

参考リンク

Hackerたちの意見

うーん… Raspberry Piとか、もっとパワフルなデバイスを使ってPCIeカードをエミュレートできるようになるのかな? 1xから16xスロットまで、マシンに差し込むことができるネットワークカードをエミュレートするカードのアイデアが面白いな。VPNとか他のことをカード上で動かして、ホストからオフロードできるし、ストレージとしても使える。ZFSを動かせるだけのパワーがあって、いくつかのディスクをまとめてホストに1つのディスクとして見せることができれば、ZFSがサポートされていないデバイスでも使えるようになる。でも、これは簡単なことじゃないだろうな…

stm32mp2シリーズのMCUみたいなものでLinuxを動かして、MCUのカーネルモジュールから制御できるPCIeエンドポイントとして使えるんだよね。そうすれば、任意のPCIeデバイスをプログラムできるけど、速度記録を更新することはないだろうし、PHYはPCIe 1xに制限されてるかも。

… それともイーサネット経由のPCIe ;)

他のデバイスを使ってPCIeカードをエミュレートする これに対する他の解決策はFPGAカードだね: https://www.fpgadeveloper.com/list-of-fpga-dev-boards-for-pc... 価格の幅が広いのに注意。FPGAツールも扱わなきゃいけないけど、その分タイミングがずっと良くなるよ。

こんにちは!作者です!実際には、ホストのリアルドライバが行うトランザクションを、どこにでもオフロードできるんですよ。PCIは遅延に強いから、デバイスと交渉することが多いし、効率的にスループットを管理できれば、特に問題はないと思います。PCIemが特別なのは、ドライバが行うアクセスに関してほぼ自由にできることです。完全に自由です。私はシンプルなNVMEコントローラを作ったんですが(1GBのドライブをmallocしただけ)、それがローカルのPCIバスに現れます(通常のLinuxのnvmeブロックドライバもちゃんと接続できます)。フォーマットしたり、マウントしたり、ファイルやフォルダを作ったり…結構面白いです。あと、QEMUの中に作ったシンプルなラスタライザもあって、それにドライバを書きたかったんですが、存在しないので、PCIemを使ってドライバの書き込みをカードをホストしているQEMUインスタンスにリダイレクトしました(そのおかげでソフトウェアレンダリングのDOOMやOpenGL 1.XベースのQuake、Half-Lifeポートが動かせました)。

一部のARMチップはPCIeエンドポイントモードができて、カーネルはnvme SSDのふりをするサポートがありますよ。 https://docs.kernel.org/nvme/nvme-pci-endpoint-target.html

最近、DMAチートカードを買ったんだけど、実はただのFPGA PCIeカードなんだ。まだいじってみてないけど、ソフトウェアで本物のPCIeカードをエミュレートするのは難しそうだね。PCIeはかなり高速だから。

これがDPUの役割だよ。

こういうことは、Plan 9みたいなOSではめちゃくちゃ簡単。単一のプロトコル、9Pを使うだけだから。Ethernetデバイスは抽象化されて、カーネルによってファイルシステムとして提供されるんだ。すべてが9Pだから、サーバーがどこで動いてるかなんて気にしない。ローカルのカーネル内サーバーでも、ユーザースペースのサーバーでも、TCPやIL、PCIeリンク、RS232ポート、SPI、USBなどの任意の双方向リンクを介したリモートサーバーでもOK。これで、他のマシンから個々のハードウェアやネットワークスタック(ip(3)や任意の9Pサーバー)をプロセスのローカル名前空間にマウントできる。プロセスごとの名前空間を使えば、ファイルシステムの見え方をカスタマイズできるし、その子プロセスも同様にカスタマイズできる。9frontをOcteonチップで動かすことに興味がある人もいるよ。これができれば、Octeonカードで好きなものを動かせるようになるし(Plan 9のクロスプラットフォームは一級品だから)、ホストのルートファイルシステムを使ってカードをブートしたり、ホスト上でプログラムを書いてテストしたり、objtype環境変数をmips/armに変更して、Octeon用のバイナリをビルドして、rcpuを使ってOcteonで実行したりできる。必要なのは、Octeon上で動くカーネルとホストのカーネルドライバだけで、あとはすぐに使える状態になるよ。

追加の処理能力や再構成の容易さのために、1つ以上の(再プログラム可能な?)FPGAをそのカードに追加できるかも……なんでこういうFPGA付きのカードがレトロコンピュータのエミュレーションやシミュレーションに使われてないのか、ずっと不思議に思ってたんだよね。

これがDMAカードのやることだよ。

ドライバーや本物のハードウェアを開発しているなら、これは大きな勝利だね。ボタン一つでプロトコルを反復できるから。

Hacker Newsで議論の続きを見る