Проброс PCI-устройств в QEMU
На примере Atheros AR9285 (168c:002b) для разработки драйверов KolibriOS
Проброс реализуется на хосте под управлением Linux. На потребительских версиях Windows проброс PCI-устройств в виртуальную машину невозможен:
- Hyper-V DDA (Discrete Device Assignment) доступен только в Windows Server.
- VMware Workstation PCI passthrough не поддерживает (только ESXi на голом железе).
- VirtualBox удалил поддержку, начиная с 6.1.
Технически работа с IOMMU из userspace реализована через подсистему ядра VFIO, аналога которому в открытом доступе на Windows нет.
Требования
- CPU с поддержкой VT-x/AMD-V и VT-d/AMD-Vi
- IOMMU включён в BIOS/UEFI (опция называется
VT-d,Intel Virtualization Technology for Directed I/O,IOMMU,AMD-ViилиSVM) - Linux с модулем
vfio-pci(есть во всех современных ядрах из коробки) - QEMU с поддержкой KVM
Что можно пробрасывать
| Тип | Механизм QEMU | Требует IOMMU |
|---|---|---|
| PCI / PCIe / Mini PCIe / M.2 | -device vfio-pci |
да |
| USB | -device usb-host |
нет |
| SR-IOV Virtual Functions | -device vfio-pci |
да |
| Блочные устройства | -drive file=/dev/sdX |
нет |
Mini PCIe и M.2 — это формы того же PCIe, процедура проброса идентична обычному PCI.
Подготовка хоста Linux
1. Найти устройство
lspci -v | grep -i network

lspci с найденной картой и ID устройстваАдрес слева (02:00.0) используется во всех последующих командах.
2. Получить ID
lspci -n -s 02:00.0
Формат vendor:device, например 168c:002b.
3. Проверить IOMMU-группы
dmesg | grep -i "iommu group"

Пусто → IOMMU не активирован (BIOS или параметры ядра).
При необходимости — развёрнутый вид групп с привязкой устройств:
for d in /sys/kernel/iommu_groups/*/devices/*; do
n=${d#*/iommu_groups/*}; n=${n%%/*}
printf 'IOMMU Group %s ' "$n"
lspci -nns "${d##*/}"
done
Все устройства из одной группы пробрасываются только вместе. Если в группе с целевой картой висят посторонние устройства — нужен ACS override patch (пересборка ядра) или замена слота/материнской платы.
4. Параметры ядра
/etc/default/grub, строка GRUB_CMDLINE_LINUX_DEFAULT:
Intel:
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on vfio-pci.ids=168c:002b"
AMD:
GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on vfio-pci.ids=168c:002b"
*_iommu=on— активирует IOMMUvfio-pci.ids=—vfio-pciзабирает устройство до загрузки штатного драйвера

/etc/default/grubПрименить:
sudo update-grub # Debian/Ubuntu
# sudo grub-mkconfig -o /boot/grub/grub.cfg # Arch/Fedora
sudo reboot
5. Проверка привязки
lspci -v -s 02:00.0 | grep "Kernel driver"
Ожидаемое: Kernel driver in use: vfio-pci.
6. Если драйвер не сменился
Штатный драйвер (ath9k, iwlwifi, e1000e и т.п.) успевает захватить устройство раньше vfio-pci.
Принудительная загрузка vfio-pci:
echo 'vfio-pci' | sudo tee -a /etc/modules
sudo reboot
Чёрный список + дублирование привязки + initramfs:
sudo tee /etc/modprobe.d/blacklist-ath9k.conf <<EOF
blacklist ath9k
blacklist ath9k_htc
EOF
echo 'options vfio-pci ids=168c:002b' | sudo tee /etc/modprobe.d/vfio-pci.conf
sudo update-initramfs -u # Debian/Ubuntu
# sudo dracut -f # Fedora
# sudo mkinitcpio -P # Arch
sudo reboot
Имена модулей в blacklist подставлять под свой чип (iwlwifi, r8169, nouveau и т.д.).
7. Права на /dev/vfio
sudo usermod -aG kvm $USER
echo 'SUBSYSTEM=="vfio", GROUP="kvm", MODE="0660"' | \
sudo tee /etc/udev/rules.d/10-vfio.rules
sudo udevadm control --reload-rules
sudo udevadm trigger
Перелогиниться (новое членство в группе не подхватывается в текущей сессии).
Запуск
Минимальная команда:
qemu-system-x86_64 \
-enable-kvm \
-m 512M \
-vga vmware \
-device vfio-pci,host=02:00.0 \
-cdrom /path/to/kolibri.iso

Параметры QEMU
Базовые
| Параметр | Назначение |
|---|---|
-enable-kvm |
Аппаратное ускорение KVM. Для VFIO обязательно. |
-m 512M |
RAM гостя. Колибри хватает 64M, 512M — с запасом под отладку. |
-cpu host |
Прокинуть весь набор инструкций хоста. Альтернативы: qemu64, kvm64.
|
-smp 2 |
Число vCPU. Для отладки одного драйвера — -smp 1.
|
-boot d |
Загрузка с CD. a — FDD, c — HDD, n — PXE.
|
-no-reboot |
triple fault «тройной сбой» = выход QEMU вместо перезагрузки гостя. |
-vga vmware |
Модель видео гостя. Для Колибри подходят std, vmware, cirrus.
|
-fda kolibri.img |
Дискета — штатный формат образа Колибри. Альтернативы: -cdrom file.iso, -hda file.img.
|
vfio-pci
-device vfio-pci,host=02:00.0[,id=net0][,bus=pci.0,addr=05.0][,multifunction=on][,romfile=rom.bin][,x-vga=on]
| Параметр | Назначение |
|---|---|
host=BUS:DEV.FN |
Физический адрес устройства |
id=... |
Внутреннее имя в QEMU (для нескольких пробросов) |
bus=...,addr=... |
Принудительное место на виртуальной PCI-шине гостя |
multifunction=on |
Для multi-function устройств |
romfile=... |
Подмена Option ROM (актуально для GPU) |
x-vga=on |
Режим primary VGA passthrough (только для GPU) |
Для AR9285 достаточно host=02:00.0.
Управление привязкой без перезагрузки
Вернуть устройство хосту:
echo "0000:02:00.0" | sudo tee /sys/bus/pci/drivers/vfio-pci/unbind
echo "0000:02:00.0" | sudo tee /sys/bus/pci/drivers/ath9k/bind
Обратно к vfio-pci:
echo "0000:02:00.0" | sudo tee /sys/bus/pci/drivers/ath9k/unbind
echo "168c 002b" | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id
Диагностика
lsmod | grep ath9k # штатный драйвер должен быть выгружен
ls -la /dev/vfio/ # права на vfio-устройства
dmesg | grep -i -e vfio -e iommu
lspci -k -s 02:00.0 # текущий привязанный драйвер
pkill qemu # убить зависший QEMU
Типовые ошибки
| Сообщение | Причина | Решение |
|---|---|---|
vfio: failed to set iommu for container: Operation not permitted |
Нет прав на /dev/vfio/* |
Шаг 7, перелогин |
vfio-pci: probe ... failed with error -22 |
Устройство не одно в IOMMU-группе | Пробрасывать всю группу или ACS override |
Group N is not viable |
То же | То же |
KVM: entry failed, hardware error 0x80000021 |
-cpu host несовместим с конкретным железом |
-cpu kvm64 или -cpu qemu64
|
| Карта видна в госте, но не отвечает после перезапуска | Reset bug устройства (нет корректного FLR) | Полная перезагрузка хоста между запусками |
BAR ... can't reserve [mem ...] |
Резервирование региона хост-ядром | Добавить pci=realloc в параметры ядра
|
См. также
- Отладка драйверов KolibriOS в QEMU (
-serial,-monitor,-d guest_errors) - Видео-демонстрация процесса — https://www.youtube.com/watch?v=yb3vH_Zs1z0
Внешние ссылки
- Документация ядра Linux: VFIO — Virtual Function I/O
- ArchWiki: PCI passthrough via OVMF — наиболее подробная практическая инструкция
- Gentoo Wiki: GPU passthrough