This document explains how to inject VirtIO and additional PnP drivers into Windows VMs during migration from VMware to KVM.
hyper2kvm supports injecting Windows drivers in two ways:
System32\drivers with registry entriespnputil# Specify path to virtio-win drivers directory or ISO
virtio_drivers_dir: /path/to/virtio-win-extracted
# Optional: Custom driver configuration
virtio_config: /path/to/custom-virtio-config.yaml
C:\Windows\System32\drivers\HKLM\SYSTEM\CurrentControlSet\ServicesC:\hyper2kvm\drivers\virtio\<service>\The virtio_drivers_dir can contain any Windows drivers, not just VirtIO! Here’s how to structure them:
/path/to/drivers/
├── viostor/ # VirtIO SCSI
│ └── w10/amd64/
│ ├── viostor.sys
│ ├── viostor.inf
│ └── viostor.cat
├── NetKVM/ # VirtIO Network
│ └── w10/amd64/
│ ├── netkvm.sys
│ ├── netkvm.inf
│ └── netkvm.cat
└── CustomDriver/ # Your custom driver
└── w10/amd64/
├── mydriver.sys
├── mydriver.inf
└── mydriver.cat
Then define the custom driver in a YAML config:
# custom-drivers.yaml
drivers:
custom: # New driver type category
- name: MyDriver
service: mydriver
pattern: CustomDriver/w10/amd64/mydriver.sys
class_guid: "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
inf_hint: mydriver.inf
start_type: demand # or boot, system, auto, disabled
pci_ids:
- "pci#ven_XXXX&dev_YYYY"
buckets:
w10:
- w10
- w11 # Fallback
Use it:
# migration-config.yaml
virtio_drivers_dir: /path/to/drivers
virtio_config: /path/to/custom-drivers.yaml
If you just want drivers installed via PnP (not injected as boot-critical), you can place them in the staging directory directly:
# In your migration YAML
virtio_drivers_dir: /path/to/drivers
Structure:
/path/to/drivers/
├── MyDriver/
│ └── w10/amd64/
│ ├── driver.inf
│ ├── driver.cat
│ ├── driver.sys
│ └── driver.dll # Optional coinstallers, etc.
The firstboot service will find and install all *.inf files recursively in:
C:\hyper2kvm\drivers\virtio\**\*.infThe hyper2kvm-firstboot service runs once on first boot as LocalSystem and:
dir /b /s "C:\hyper2kvm\drivers\virtio\*.inf"pnputil /add-driver <path> /installC:\Windows\Temp\hyper2kvm-firstboot.logC:\hyper2kvm\firstboot.doneIf the firstboot service fails, you can manually install drivers:
REM Run as Administrator
cd C:\hyper2kvm\drivers\virtio
REM Install all drivers
for /r %i in (*.inf) do pnputil /add-driver "%i" /install
REM Or use the generated setup script
C:\hyper2kvm\setup.cmd
Mount the converted QCOW2 and verify:
guestfish --ro -a win10-converted.qcow2 -m /dev/sda3
> ls /Windows/System32/drivers/ | grep -E "(viostor|vioscsi|netkvm|balloon)"
> ls /hyper2kvm/drivers/virtio/
balloon/
netkvm/
vioscsi/
viostor/
After conversion but before first boot:
> download /Windows/System32/config/SYSTEM SYSTEM.hive
# Use Registry Editor or hivexsh to check:
# HKLM\SYSTEM\ControlSet001\Services\hyper2kvm-firstboot
> download /Windows/System32/config/SOFTWARE SOFTWARE.hive
# Check:
# HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\DevicePath
# Should contain: %SystemDrive%\hyper2kvm\drivers\virtio
Issue: Firstboot log shows no drivers found
Solution: Check path structure matches:
C:\hyper2kvm\drivers\virtio\<service>\*.inf
Fix: Update _DEFAULT_DRIVER_STAGE_DIR in registry/firstboot.py (already fixed in latest version)
Issue: INACCESSIBLE_BOOT_DEVICE
Causes:
Solution:
virtio.drivers_found should include viostor or vioscsivirtio.registry_changes.success = trueIssue: Windows boots but drivers not installed
Causes:
C:\hyper2kvm\firstboot.doneSolution:
sc query hyper2kvm-firstbootC:\Windows\Temp\hyper2kvm-firstboot.logdel C:\hyper2kvm\firstboot.doneC:\hyper2kvm\setup.cmdIssue: pnputil fails with signature errors
Solution:
bcdedit /set testsigning on
pnputil /add-driver driver.inf /install /subdirs
For boot-critical drivers (storage, etc.), you need to define them in the VirtIO config:
# virtio-config.yaml
drivers:
storage: # Must be one of: storage, network, balloon, input, gpu, filesystem, serial, rng
- name: MyStorageDriver
service: mystor
pattern: MyStorageDriver/w10/amd64/mystor.sys
class_guid: "{4D36E967-E325-11CE-BFC1-08002BE10318}" # SCSI adapter class
inf_hint: mystor.inf
start_type: boot # Critical for storage!
type: kernel
error_control: normal
pci_ids:
- "pci#ven_1234&dev_5678"
critical_device_database: true # Add to CDD for early binding
buckets:
w10:
- w10
- w8.1
- w8
cmd: local
vmdk: /path/to/windows.vmdk
output_dir: /path/to/output
windows: true
# VirtIO drivers
virtio_drivers_dir: /usr/share/virtio-win
# Output
to_output: /path/to/output/windows-converted.qcow2
report: /path/to/output/report.md
cmd: local
vmdk: /path/to/windows.vmdk
output_dir: /path/to/output
windows: true
# VirtIO + custom drivers in same directory
virtio_drivers_dir: /path/to/all-drivers
# Custom driver definitions
virtio_config: /path/to/custom-drivers.yaml
# Output
to_output: /path/to/output/windows-converted.qcow2
report: /path/to/output/report.md
# Dry run to test driver injection only
dry_run: true
cmd: local
vmdk: /path/to/windows.vmdk
windows: true
virtio_drivers_dir: /path/to/virtio-win
report: /path/to/test-report.md
Check the report to verify:
virtio.injected: truevirtio.drivers_found: [...]virtio.packages_staged: [...]virtio.firstboot.success: true