rss logo

Comment virtualiser Windows 11 avec QEMU et la prise en charge des périphériques USB

Logo QEMU

J’ai précédemment expliqué comment configurer une machine virtuelle Windows sur un hôte Arch Linux afin de pouvoir utiliser un périphérique USB (en l’occurrence le scanner Canon CanoScan 4400F). Cet article portait sur Windows 10, dont la prise en charge arrive à son terme. Il est donc pertinent de mettre à jour ce guide pour Windows 11. Cette nouvelle version de Windows introduit en effet des changements importants — notamment des exigences en matière de TPM, de Secure Boot, de CPU compatible, et de démarrage via UEFI — ce qui implique de réadapter plusieurs éléments de la configuration.

Architecture QEMU

Comme mentionné dans l’introduction, ce guide explique comment virtualiser un système d’exploitation Windows 11. Pour cela, il est nécessaire d’émuler à la fois le TPM et l’UEFI. Le système sera installé sur un disque virtuel WIN11.cow, et un scanner USB est connecté à l’hôte Arch Linux.

Schéma montrant QEMU virtualisant Windows 11 sur Arch Linux avec prise en charge du TPM, de l’UEFI et du scanner USB
Architecture d’une machine virtuelle QEMU exécutant Windows 11.

Périphérique USB

Pour utiliser le périphérique USB, il faut d'abord l’identifier, puis attribuer les permissions appropriées. Plus précisément, nous devons nous assurer que l’utilisateur actuel est autorisé à interagir avec celui-ci.

  • Installez l’outil cyme, une alternative à lsusb :
[root@host ~]# pacman -S cyme
  • Listez les périphériques USB et notez bien les identifiants Bus et Device :
[user@host ~]$ cyme -l | grep -i Canon
Bus 003 Device 002: ID 04a9:2228 Canon, Inc. CanoScan 4400F
  • Comme on peut le voir, il est détenu par root :
[user@host ~]$ ls -l /dev/bus/usb/003/002
crw-rw-r--+ 1 root root 189, 257  4 mai   18:49 /dev/bus/usb/003/002

Solution temporaire

Une solution temporaire consiste à changer manuellement le propriétaire du périphérique depuis une invite root. Cette opération devra être répétée après chaque redémarrage.

  • Changez le propriétaire en votre utilisateur actuel :
[root@host ~]# chown user:user /dev/bus/usb/003/002

Solution permanente

Pour rendre ce changement persistant, nous allons créer une règle udev qui attribue automatiquement l’utilisateur comme propriétaire du périphérique.

  • Commencez par récupérer les principaux attributs du périphérique :
root@host:~# udevadm info --attribute-walk --path=$(udevadm info --query=path --name=/dev/bus/usb/003/002)
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:14.0/usb3/3-1':
    KERNEL=="3-10"
    SUBSYSTEM=="usb"
[…]
    ATTR{idProduct}=="2228"
    ATTR{idVendor}=="04a9"
[…]

Une fois les attributs du périphérique identifiés, nous pouvons créer la règle udev correspondante.

  • Créez et éditez le fichier /etc/udev/rules.d/80-scanner.rules :
SUBSYSTEM=="usb", ATTR{idVendor}=="04a9", ATTR{idProduct}=="2228", OWNER="user", GROUP="user"
  • Rechargez les règles udev pour appliquer les modifications :
[root@host ~]# udevadm control --reload
  • Vérifiez que la règle udev est bien appliquée :
[root@host ~]# udevadm test $(udevadm info --query=path --name=/dev/bus/usb/003/002) | less
[…]
Reading rules file: /etc/udev/rules.d/80-scanner.rules
[…]
  • Enfin, assurez-vous que les permissions ont bien été appliquées :
[user@host ~]$ ls -l /dev/bus/usb/003/002
crw-rw-r-- 1 user user 189, 129 31 oct.  09:20 /dev/bus/usb/003/002

QEMU

Configuration initiale

Paquets

  • Installez les paquets QEMU, ainsi que les outils UEFI et TPM :
[root@host ~]# pacman -S qemu-full qemu-hw-usb-host edk2-ovmf swtpm wget

Disque virtuel

  • Créez le disque virtuel (ajoutez l’option -o nocow=on si vous utilisez un système de fichiers Btrfs) :
[user@host ~]$ qemu-img create -f qcow2 WIN11.cow 80G
Formatting 'WIN11.cow', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=85899345920 lazy_refcounts=off refcount_bits=16
  • Si nécessaire, vous pouvez redimensionner l’image du disque virtuel :
[user@host ~]$ qemu-img WIN11.cow +10G

VirtIO

VirtIO est une norme de virtualisation pour les pilotes de périphériques réseau et disque, dans laquelle seul le pilote du système invité "sait" qu’il fonctionne dans un environnement virtuel, et coopère avec l’hyperviseur. Cela permet aux systèmes invités de bénéficier de performances élevées pour les opérations réseau et disque, tout en conservant la majorité des avantages de la paravirtualisation. (source : https://wiki.libvirt.org/Virtio.html).

[user@host ~]$ wget "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso"

Secure Boot

Comme Arch ne fournit pas actuellement son propre fichier OVMF_VARS.secboot.4m.fd avec des clés pré-enregistrées, nous devons l’obtenir depuis une distribution qui le propose — comme Fedora. Pour cela, téléchargez le paquet RPM approprié, puis extrayez-en le fichier OVMF_VARS.secboot.4m.fd.

  • Créez un répertoire pour stocker les fichiers liés au Secure Boot :
[user@host ~]$ mkdir secboot
  • Installez les outils nécessaires à l’extraction des paquets RPM :
[root@host ~]# pacman -S rpmextract
[user@host ~]$ wget "https://kojipkgs.fedoraproject.org/packages/edk2/20241117/5.fc42/noarch/edk2-ovmf-20241117-5.fc42.noarch.rpm"
  • Extrayez le contenu du paquet RPM :
[user@host ~]$ rpmextract.sh edk2-ovmf-20241117-5.fc42.noarch.rpm
  • Convertissez le fichier extrait OVMF_VARS_4M.secboot.qcow2 au format OVMF_VARS_4M.secboot.fd :
[user@host ~]$ qemu-img convert -O raw -f qcow2 usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2 OVMF_VARS_4M.secboot.fd
  • Enfin, copiez les fichiers OVMF_CODE.secboot.4m.fd et OVMF_VARS_4M.secboot.fd du paquet edk2-ovmf dans le répertoire secboot :
[user@host ~]$ cp /usr/share/edk2/x64/OVMF_CODE.secboot.4m.fd ./secboot
[user@host ~]$ cp OVMF_VARS_4M.secboot.fd ./secboot

TPM

Nous utiliserons ensuite la commande swtpm pour créer un socket UNIX auquel QEMU se connectera.

  • Créez un répertoire pour stocker les données du TPM :
[user@host ~]$ mkdir tpm

Organisation des répertoires

Organisez tous les fichiers téléchargés ou créés dans une structure claire.

  • Voici l’organisation que j’ai personnellement choisie :
    • Répertoire secboot : contient les fichiers OVMF_VARS_4M.secboot.fd et OVMF_CODE.secboot.4m.fd
    • Répertoire tpm : contient le fichier swtpm-sock (généré lors de l'exécution de la commande swtpm socket)
    • WIN11.cow : disque virtuel
    • virtio-win.iso : image ISO des pilotes VirtIO
Structure de fichiers montrant les éléments nécessaires d’une machine virtuelle QEMU : firmware UEFI OVMF, état TPM, image disque et fichiers ISO sous Arch Linux

Installation de Windows 11

Nous sommes maintenant prêts à lancer la machine virtuelle et à commencer l’installation de Windows 11.

  • Exécutez la commande suivante pour créer le socket UNIX :
[user@host ~]$ swtpm socket --tpm2 --tpmstate dir=./tpm --ctrl type=unixio,path=./tpm/swtpm-sock
  • Depuis un autre terminal, vérifiez que les fichiers suivants sont présents dans le répertoire tpm :
[user@host ~]$ ls tpm/
swtpm-sock  tpm2-00.permall
  • Exécutez la commande suivante depuis votre répertoire principal QEMU en utilisant les paramètres suivants :
    • -machine q35 : requis pour le Secure Boot
    • -m 8192 : alloue 8 Go de RAM à la machine virtuelle
    • -smp cores=4 : attribue 4 cœurs virtuels
    • -boot order=d : démarre à partir du lecteur CD-ROM

Remarque : Si nécessaire, vous pouvez vous connecter à la machine virtuelle à l’aide d’un client VNC — par exemple avec la commande suivante : vncviewer -PreferredEncoding tight 127.0.0.1:5900

[user@host ~]$ qemu-system-x86_64 -machine q35 -m 8192 \
-cpu host -enable-kvm -smp cores=4 \
-net nic,model=virtio-net-pci,macaddr=52:54:00:12:34:56 -net user,id=mynet0,net=192.168.76.0/24,dhcpstart=192.168.76.9 \
-cdrom ./Win11_24H2_English_x64.iso \
-drive file=./virtio-win.iso,media=cdrom,index=3 \
-boot order=d \
-drive file=./WIN11.cow,index=0,media=disk,if=virtio,format=qcow2 \
-chardev socket,id=chrtpm,path=./tpm/swtpm-sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0 \
-drive if=pflash,format=raw,readonly=on,file=./secboot/OVMF_CODE.secboot.4m.fd -drive if=pflash,format=raw,file=./secboot/OVMF_VARS_4M.secboot.fd
  • Lors de l’étape de sélection du disque, vous devez charger manuellement les pilotes de stockage VirtIO :
Écran d'installation de Windows 11 affichant le bouton Charger un pilote pendant la sélection du disque dans une machine virtuelle QEMU
  • Accédez à viostor > w11, sélectionnez le dossier amd64, puis cliquez sur OK :
Installation de Windows 11 affichant le chemin de sélection du pilote VirtIO : viostor > w11 > amd64 dans une VM QEMU
  • Sélectionnez le pilote VirtIO, puis cliquez sur Installer :
Installation de Windows 11 affichant le pilote Red Hat VirtIO SCSI sélectionné dans une machine virtuelle QEMU
  • Une fois Windows 11 installé, procédez à l’installation des pilotes VirtIO :
Explorateur de fichiers Windows affichant le contenu de l’ISO virtio-win avec l’installateur virtio-win-gt-x64 mis en évidence pour les pilotes VirtIO

Post-installation

  • Une fois Windows 11 installé, vous n’avez plus besoin du média d’installation ni de l’ISO VirtIO. Vous pouvez également :
    • Activer la redirection RDP pour permettre des connexions à distance via RDP, en utilisant : hostfwd=tcp::5555-:3389
    • Ajouter -boot order=c pour démarrer directement depuis le disque dur virtuel
    • Activer le passthrough USB pour un périphérique de l’hôte avec : -device usb-host,hostdevice=/dev/bus/usb/003/002
[user@host ~]$ qemu-system-x86_64 -machine q35 -m 8192 \
-cpu host -enable-kvm -smp cores=4 \
-net nic,model=virtio-net-pci,macaddr=52:54:00:12:34:56 -net user,id=mynet0,net=192.168.76.0/24,dhcpstart=192.168.76.9,hostfwd=tcp::5555-:3389 \
-boot order=c \
-drive file=./WIN11.cow,index=0,media=disk,if=virtio,format=qcow2 \
-chardev socket,id=chrtpm,path=./tpm/swtpm-sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0 \
-drive if=pflash,format=raw,readonly=on,file=./secboot/OVMF_CODE.secboot.4m.fd -drive if=pflash,format=raw,file=./secboot/OVMF_VARS_4M.secboot.fd \
-device qemu-xhci,id=xhci -device usb-host,hostdevice=/dev/bus/usb/003/002
  • Vous pouvez ensuite vous connecter à la machine virtuelle via RDP et vérifiez la présence du périphérique USB :
[user@host ~]$ xfreerdp3 /v:127.0.0.1:5555 /w:1080 /h:720 /u:"USER" /p:"PASSWORD" /cert:ignore
Gestionnaire de périphériques de Windows 11 affichant le scanner Canon CanoScan détecté sous Autres périphériques via passthrough USB dans QEMU
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :

contact mail address