
Un framework de Linux para permitir shims de tarjetas PCIe 'Virtuales' definidos en espacio de usuario para habilitar el desarrollo de controladores de tarjetas PCIe dentro del host.
PCIem es un framework que crea dispositivos PCIe virtuales en el kernel de Linux aprovechando algunas técnicas novedosas para presentar tarjetas sintéticas como dispositivos PCI legítimos al sistema operativo anfitrión.
Para resumir qué es PCIem: un framework para (aunque no limitado a) desarrollar y probar controladores de dispositivos PCIe sin necesidad de hardware real en el anfitrión.
PCIem y libfvio-user son dos soluciones diferentes para necesidades distintas, puede haber confusión al compararlas, por lo que aquí están las diferencias (Véase figura 1 para más detalles).
La principal es que libvfio-user normalmente depende de un cliente (que implementa el protocolo vfio-user), generalmente QEMU (a través de KVM, usando salidas de VM) para exponer el dispositivo PCIe emulado al invitado. Escribe su servidor vfio (con un mecanismo de devolución de llamada generalmente) que luego interactúa con el cliente.
Lo que hace PCIem en cambio es exponer el dispositivo directamente en el anfitrión; sin KVM, sin invitados, sin máquinas virtuales, nada. El dispositivo aparece en el bus PCIe del anfitrión como si estuviera conectado físicamente.
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, riscvNota aarch64: Probado con Raspberry Pi 4b, device-tree (Sin ACPI)
Nota riscv: Probado con VisionFive 2 (Device-tree) y Muse Pi Pro (Device-tree y ACPI)
Una tarjeta compatible con Bochs BGA (bochs-drm) que puede ser manejada por utilidades de espacio de usuario como Weston; usa SDL3.
https://github.com/user-attachments/assets/d2f7abe4-aef4-4d3a-a30b-ab7ec793faed
Controlador NVME con 1GB de almacenamiento adjunto. El usuario puede formatear, montar, crear y eliminar archivos libremente de la memoria.
https://github.com/user-attachments/assets/29ce370a-7317-4fd4-9d1d-c3e868e1083d
Modelo de emulación compatible con ICH6 que puede reproducir muestras en conjunto con pipewire.
NOTA: Ligero crujido de audio solo audible en la grabación, funciona bien por lo demás
https://github.com/user-attachments/assets/7264a18c-6fcb-46c4-acde-9531b0be7ff6
Una implementación bastante ingenua de la tarjeta E1000. Soporta redirección de comunicaciones hacia/desde tu NIC real. También puede usar Wi-Fi pero es menos estable.
https://github.com/user-attachments/assets/b6b9862c-349c-49da-8a79-4769dfa31915
La tarjeta está programada enteramente en QEMU (máquina de estados para la tarjeta, básicamente), que realiza toda la inicialización en espacio de usuario y el manejo de comandos desde el controlador real que se ejecuta en el anfitrión.
Puede ejecutar DOOM renderizado por software (Envía fotogramas terminados con DMA a la tarjeta que QEMU muestra) y también juegos simples de OpenGL 1.X (En las capturas de pantalla, tyr-glquake y xash3d; gracias a una máquina de estados OpenGL personalizada implementada enteramente en QEMU que renderiza por software las listas de comandos y actualiza el estado interno en consecuencia).
| Característica | PCIem | libfvio-user |
|---|
| Conexión | Archivo de dispositivo (/dev/pciem) | Sockets UNIX (protocolo vfio-user) |
| El controlador objetivo se ejecuta en | Anfitrión | OS Invitado |
| El dispositivo emulado se ejecuta en | Espacio de usuario | Espacio de usuario |
| Accesos al dispositivo | Directo (Dentro del anfitrión) | Virtualizado (Invitado a Anfitrión) |
Figura 1: Comparación entre frameworks
| Distribución |
|---|
| Ubuntu Última | - | - | |
| Ubuntu 24.04 LTS | |||
| Debian Estable | - | - | |
| Fedora Última | - | - | |
| openSUSE Tumbleweed | - | - |