PCIem 是一个框架,通过利用一些新颖技术,在 Linux 内核中创建虚拟 PCIe 设备,将合成卡作为合法的 PCI 设备呈现给主机操作系统。
简而言之,PCIem 是一个用于(但不限于)开发和测试 PCIe 设备驱动程序的框架,无需主机上的实际硬件。
PCIem 和 libfvio-user 是两种针对不同需求的解决方案,比较两者时可能会产生混淆,因此此处说明差异(更多信息请参见图1)。
主要区别在于,libvfio-user 通常依赖一个客户端(实现 vfio-user 协议),通常是 QEMU(通过 KVM,使用 VM 退出)将模拟的 PCIe 设备暴露给客户机。你编写你的 vfio 服务器(通常使用回调机制),然后与客户端交互。
而 PCIem 则是将设备直接暴露在主机上;无需 KVM、无需客户机、无需虚拟机,什么都不需要。设备出现在主机的 PCIe 总线上,就像物理连接一样。
graph LR
subgraph Kernel ["Host Linux Kernel"]
direction TB
RealDriver["Real PCIe Driver"]
subgraph Framework ["PCIem Framework"]
direction TB
Config["PCI Config Space"]
BARs["BARs"]
IRQ["Interrupts"]
DMA["DMA / IOMMU"]
end
end
Interface(("/dev/pciem"))
subgraph User ["Linux Userspace"]
direction TB
Shim["Device Emulation"]
end
Framework <==> Interface
Interface <==> Shim
6.6gcc-12amd64/i386,aarch64,riscvaarch64 说明: 已在 Raspberry Pi 4b 上测试,设备树(无 ACPI)
riscv 说明: 已在 VisionFive 2(设备树)和 Muse Pi Pro(设备树和 ACPI)上测试
一张兼容 Bochs BGA (bochs-drm) 的显卡,可由 Weston 等用户空间工具驱动;使用 SDL3。
https://github.com/user-attachments/assets/d2f7abe4-aef4-4d3a-a30b-ab7ec793faed
NVME 控制器,附带 1GB 存储空间。用户可以自由格式化、挂载、创建和删除内存中的文件。
https://github.com/user-attachments/assets/29ce370a-7317-4fd4-9d1d-c3e868e1083d
兼容 ICH6 的模拟模型,可与 pipewire 配合播放样本。
注意:录音中仅听到轻微音频爆裂,其他情况下工作正常。
https://github.com/user-attachments/assets/7264a18c-6fcb-46c4-acde-9531b0be7ff6
一个相当朴素的 E1000 网卡实现。支持与真实 NIC 之间的通信重定向。也可以使用 Wi-Fi,但稳定性较差。
https://github.com/user-attachments/assets/b6b9862c-349c-49da-8a79-4769dfa31915
该卡完全在 QEMU 中编程(基本上是卡的状态机),QEMU 处理所有用户空间初始化以及来自主机上运行的真实驱动程序的命令处理。
可以运行软件渲染的 DOOM(通过 DMA 将完成的帧提交给卡,由 QEMU 显示),以及简单的 OpenGL 1.X 游戏(截图中为 tyr-glquake 和 xash3d;这要归功于完全在 QEMU 中实现的自定义 OpenGL 状态机,它可以软件渲染命令列表并相应地更新内部状态)。
| 特性 | PCIem | libfvio-user |
|---|
| 连接方式 | 设备文件 (/dev/pciem) | UNIX 套接字 (vfio-user 协议) |
| 目标驱动运行于 | 宿主机 | 客户操作系统 |
| 模拟设备运行于 | 用户空间 | 用户空间 |
| 设备访问 | 直接(宿主机内) | 虚拟化(客户机到宿主机) |
图1:框架比较
| 发行版 |
|---|
| Ubuntu 最新版 | - | - | |
| Ubuntu 24.04 LTS | |||
| Debian 稳定版 | - | - | |
| Fedora 最新版 | - | - | |
| openSUSE Tumbleweed | - | - |