
Um framework Linux para permitir shims de cartão PCIe 'Virtual' definidos no espaço do usuário para permitir o desenvolvimento de drivers de cartão PCIe no host.
O PCIem é um framework que cria dispositivos PCIe virtuais no kernel Linux, utilizando algumas técnicas inovadoras para apresentar placas sintéticas como dispositivos PCI legítimos ao SO do host.
Para resumir o que é o PCIem: um framework para (embora não limitado a) desenvolver e testar drivers de dispositivos PCIe sem exigir hardware real no host.
O PCIem e o libfvio-user são duas soluções diferentes para necessidades diferentes; pode haver confusão ao compará-los, portanto, aqui estão as diferenças (Veja a figura 1 para mais detalhes).
A principal diferença é que o libvfio-user normalmente depende de um cliente (que implementa o protocolo vfio-user), geralmente QEMU (através de KVM, usando VM exits) para expor o dispositivo PCIe emulado ao convidado. Você escreve seu servidor vfio (geralmente com um mecanismo de callback) que então interage com o cliente.
O que o PCIem faz, em vez disso, é expor o dispositivo diretamente no host; sem KVM, sem convidados, sem máquinas virtuais, nada. O dispositivo aparece no barramento PCIe do host como se estivesse fisicamente conectado.
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: Testado com Raspberry Pi 4b, device-tree (sem ACPI)
nota riscv: Testado com VisionFive 2 (Device-tree) e Muse Pi Pro (Device-tree e ACPI)
Uma placa compatível com Bochs BGA (bochs-drm) que pode ser utilizada por utilitários no espaço do usuário, como o Weston; usa SDL3.
https://github.com/user-attachments/assets/d2f7abe4-aef4-4d3a-a30b-ab7ec793faed
Controlador NVME com 1GB de armazenamento anexado. O usuário pode livremente formatar, montar, criar e remover arquivos da memória.
https://github.com/user-attachments/assets/29ce370a-7317-4fd4-9d1d-c3e868e1083d
Modelo de emulação compatível com ICH6 que pode reproduzir samples em conjunto com o pipewire.
NOTA: Leve estalo de áudio apenas na gravação; funciona bem no geral
https://github.com/user-attachments/assets/7264a18c-6fcb-46c4-acde-9531b0be7ff6
Uma implementação bastante ingênua da placa E1000. Suporta redirecionamento de comunicações de/para sua NIC real. Também pode usar Wi-Fi, mas é menos estável.
https://github.com/user-attachments/assets/b6b9862c-349c-49da-8a79-4769dfa31915
A placa é programada inteiramente no QEMU (basicamente uma máquina de estados para a placa), que faz toda a inicialização no espaço do usuário e o tratamento de comandos a partir do driver real executando no host.
Pode executar DOOM renderizado por software (envia quadros finalizados com DMA para a placa, que o QEMU exibe) e também jogos simples OpenGL 1.X (nas capturas de tela, tyr-glquake e xash3d; graças a uma máquina de estados OpenGL personalizada implementada inteiramente no QEMU que renderiza as listas de comandos por software e atualiza o estado interno de acordo).
| Funcionalidade | PCIem | libfvio-user |
|---|
| Conexão | Arquivo de dispositivo (/dev/pciem) | Sockets UNIX (protocolo vfio-user) |
| Onde o driver alvo executa | Host | SO convidado |
| Onde o dispositivo emulado executa | Espaço do usuário | Espaço do usuário |
| Acessos ao dispositivo | Direto (dentro do host) | Virtualizado (convidado para host) |
Figura 1: Comparação entre os frameworks
| Distribuição |
|---|
| Ubuntu mais recente | - | - | |
| Ubuntu 24.04 LTS | |||
| Debian estável | - | - | |
| Fedora mais recente | - | - | |
| openSUSE Tumbleweed | - | - |