Exécuter Windows 11 sur Linux en VM QEmu imbriquée

Traduction automatique depuis l'anglais — non relue.
Summary

Comment configurer une machine virtuelle QEmu/KVM sous Linux avec prise en charge de la virtualisation imbriquée pour exécuter Windows 11 et WSL2, y compris les pilotes VirtIO, la configuration HyperV et la gestion des disques.

J’utilise exclusivement Linux chez moi et j’avais besoin d’une VM Windows pour compiler la suite de flipper virtuel et d’autres logiciels nécessitant l’utilisation du Windows Subsystem for Linux (WSL2).

Virtualbox vs QEmu

J’avais initialement choisi Virtualbox pour sa simplicité, mais je n’ai jamais réussi à y installer WSL2. Il semble que WSL2 soit implémenté sur la technologie HyperV de Windows, ce qui nécessite des fonctionnalités de virtualisation imbriquée pour être utilisé dans une VM.

Contrairement à ce qui est annoncé dans la documentation officielle wsl-virtualbox, il semble que la prise en charge de la virtualisation imbriquée pour HyperV n’ait pas été incluse dans la dernière version 7.0 de Virtualbox (7.0.14-Debian à la date de rédaction), rendant impossible l’installation de WSL2 vbox-hyperv. Cela pourrait changer avec la sortie de la version 7.1.

1
2
3
WslRegisterDistribution failed with error: 0x80370102
Please enable the Virtual Machine Platform Windows feature and ensure virtualization is enabled in the BIOS.
For information please visit https://aka.ms/enablevirtualization

C’était l’occasion d’essayer QEmu, qui le prend en charge et promet d’être plus efficace grâce à l’utilisation de KVM et virtio.

Configuration de QEmu

J’ai suivi l’excellent tutoriel de raphtlw, dont les étapes sont équivalentes pour Windows 11 (à quelques occurrences IDE près qui devraient être remplacées par SATA). Les étapes les plus importantes sont résumées ici, et vous pouvez vous référer à la page originale pour une explication détaillée avec captures d’écran.

Dépendances

1
sudo apt-get install qemu-kvm bridge-utils virt-manager qemu-system virt-viewer spice-vdagent

Configuration classique

Avant de commencer le processus d’installation, vous devrez télécharger deux fichiers ISO :

  • Windows 11, disponible sur le site de Microsoft
  • L’ISO des pilotes VirtIO, nécessaire pour configurer les périphériques VirtIO pendant l’installation (le réseau est obligatoire) — montez-le comme un deuxième lecteur CDROM.

Créez une nouvelle VM qui sera installée à partir d’un fichier ISO :

  • CPU, mémoire : j’ai laissé les paramètres par défaut.
  • Taille du disque : au moins 60 Go sont recommandés — Windows lui-même occupe environ 30 Go, et les outils de compilation nécessitent 10 à 20 Go supplémentaires. Vous pouvez toujours étendre la partition après l’installation.
  • Créez un deuxième lecteur CDROM dans le menu Stockage (sélectionnez le type de support comme CDROM) et pointez vers l’ISO VirtIO.
  • Activez le démarrage depuis le CDROM SATA dans les options de démarrage. Vous pouvez également le sélectionner via le menu BIOS si la machine ne démarre pas.
  • Passez au pilote VirtIO pour le disque dur et la carte réseau pour de meilleures performances.

Ajustement de la prise en charge HyperV

La configuration a fonctionné jusqu’à ce que j’installe WSL2 et redémarre, moment où j’ai été accueilli par l’écran bleu avec le message SYSTEM_THREAD_EXCEPTION_NOT_HANDLED. La VM n’a jamais réussi à se rétablir.

J’ai trouvé des indications dans cet excellent article de Redpill Linpro, et après quelques essais avec l’éditeur XML dans la section “Processeur” de la configuration de la VM, j’ai réussi à redémarrer Windows avec ces paramètres :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
  <features>
    <acpi/>
    <apic/>
    <pae/>
    <hyperv mode="custom">
      <vpindex state="on"/>
      <synic state="on"/>
    </hyperv>
    <smm state="on"/>
  </features>
  <cpu mode="custom" match="exact" check="partial">
    <model fallback="allow">Broadwell-noTSX-IBRS</model>
    <feature policy="disable" name="hypervisor"/>
    <feature policy="require" name="vmx"/>
  </cpu>
  <clock offset="utc">
    <timer name="rtc" tickpolicy="catchup"/>
    <timer name="pit" tickpolicy="delay"/>
    <timer name="hpet" present="no"/>
    <timer name="hypervclock" present="yes"/>
    <timer name="kvmclock" present="yes"/>
  </clock>

Je n’ai pas encore essayé d’optimiser ces paramètres au-delà de la confirmation que désactiver le passthrough CPU et sélectionner la bonne architecture CPU faisaient partie de la solution. La prochaine étape serait de consulter la documentation ou de continuer le processus d’essais-erreurs pour déterminer quelles propriétés sont réellement nécessaires ou offrent les meilleures performances. Comme le dit l’article, vos résultats peuvent varier.

À titre de référence, voici la configuration initiale proposée par QEmu :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state="on"/>
      <vapic state="on"/>
      <spinlocks state="on" retries="8191"/>
    </hyperv>
    <vmport state="off"/>
  </features>
  <cpu mode="host-passthrough"/>
  <clock offset="localtime">
    <timer name="rtc" tickpolicy="catchup"/>
    <timer name="pit" tickpolicy="delay"/>
    <timer name="hpet" present="no"/>
    <timer name="hypervclock" present="yes"/>
  </clock>

Installation de Windows 11

Laissez l’installateur vous guider jusqu’à l’étape où vous choisissez le disque sur lequel installer Windows. La liste devrait être vide.

Sélectionnez l’option “Charger les pilotes”, et parcourez le deuxième CDROM (E:) pour trouver les pilotes corrects pour votre système d’exploitation et votre plateforme (notez que parfois il n’y a pas de version win11, mais win10 fonctionne également) :

  • E:\viostor\w11\amd64 (disque)
  • E:\NetKVM\w11\amd64 (NIC)
  • E:\qxldod\w10\amd64 (graphique)

Cochez “Masquer les pilotes qui ne sont pas compatibles avec le matériel de cet ordinateur” pour vous assurer que les pilotes corrects sont trouvés. Si rien n’apparaît, vous avez peut-être oublié de passer un périphérique en VirtIO.

Plus tard dans le processus d’installation, vous n’aurez pas l’opportunité de charger de nouveaux pilotes via l’interface graphique. Vous pourriez atteindre une étape où l’installateur essaie de trouver une connexion réseau et reste bloqué faute d’interface réseau. Dans ce cas, appuyez sur Shift+F10 pour ouvrir un shell, naviguez vers les dossiers respectifs et exécutez :

1
2
pnputil /add-driver *.inf
pnputil /scan-devices

Il m’est arrivé que l’installateur trouve l’interface réseau mais refuse de se connecter faute de connectivité Internet. En exécutant un ping depuis le shell, j’ai confirmé le problème. Sur l’hôte, les paquets arrivaient au pont mais n’étaient pas transmis, probablement à cause de règles iptables manquantes. La solution la plus simple est de redémarrer libvirtd — cela n’affectera pas les VM en cours d’exécution :

1
sudo service libvirtd restart

Agent invité et pilotes supplémentaires

Une fois Windows installé, vous devriez également installer :

  • E:\virtio-win-guest-tools.exe depuis l’ISO VirtIO
  • Outils invités SPICE (dans la section Guest / Windows binaries) pour des fonctionnalités telles que le partage du presse-papiers et la résolution dynamique entre l’hôte et l’invité

Visual Studio et outils associés

Vous pouvez télécharger gratuitement l’installateur en ligne avec l’édition Community.

Voici les paramètres de charge de travail que j’ai utilisés pour mon cas d’utilisation actuel. Ils nécessitent environ 10 Go supplémentaires.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
Web & Cloud
    [ ] ASP.NET and web development
    [ ] Azure development
    [X] Python development, could be useful
    [ ] Node.js developmen
Desktop & Mobile
    [ ] .NET Multi-platform App UI development
    [ ] .NET Desktop development
    [X] Desktop development with C++
    [ ] Universal Windows Platform development
    [ ] Mobile development with C++
Gaming
    [X] Game development with Unity
    [X] Game development with C++
Other toolsets
    [ ] Data storage and processing
    [ ] Data science and analytical applications
    [ ] Visual Studio extension development
    [ ] Office / SharePoint development
    [X] Linux and embedded development with C++

Git sera nécessaire, et vous pouvez trouver les binaires Windows sur le site officiel.

WSL2

Vous pouvez installer WSL2 directement depuis le Microsoft Store, ou via la ligne de commande comme indiqué ci-dessous.

Ouvrez cmd.exe depuis le menu démarrer et exécutez en tant qu’administrateur :

1
wsl --install

Si vous avez Windows 11, ou une version suffisamment récente de Windows 10, vous devriez déjà avoir WSL2. Confirmez avec :

1
2
3
4
5
6
7
8
$ wsl -v
WSL version: 2.1.4.0
Kernel version: 5.15.146.1-2
WSLg version: 1.0.60
MSRDC version: 1.2.5105
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.22631.2861

Plus d’informations peuvent être trouvées dans wslinfo, wsl1 et wsl2. Le système vous demandera de redémarrer.

Vous pouvez ensuite installer une distribution Linux (par exemple Debian) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ wsl --install --distribution Debian

Installing Windows optional component: VirtualMachinePlatform

Deployment Image Servicing and Management tool
Version: 10.0.22621.2792

Image Version: 10.0.22631.2861

Enabling feature(s)
[==========================100.0%==========================]
The operation completed successfully.
The requested operation is successful. Changes will not be effective until the system is rebooted.
Installing: Debian GNU/Linux
Debian GNU/Linux has been installed.
The requested operation is successful. Changes will not be effective until the system is rebooted.

Après avoir choisi un identifiant et un mot de passe, vous devriez avoir un shell Linux fonctionnel.

Maintenance

Si vous manquez d’espace disque, vous pouvez soit essayer de récupérer de l’espace, soit étendre le fichier image de Windows.

Récupérer de l’espace : Compact OS, mémoire virtuelle et fichiers d’hibernation

Vous pouvez d’abord essayer de désinstaller les applications inutilisées, bien que la configuration décrite ci-dessus n’ait pratiquement aucun logiciel supplémentaire installé.

Vous pouvez récupérer quelques Go en compressant les fichiers système à l’aide de la fonctionnalité “Compact OS” de Windows, en suivant ce tutoriel :

  1. Ouvrez le menu Démarrer.
  2. Recherchez Invite de commandes, faites un clic droit sur le résultat et sélectionnez Exécuter en tant qu’administrateur.
  3. Vérifiez si Compact OS est déjà activé :
1
Compact.exe /CompactOS:query
  1. Activez Compact OS :
1
Compact.exe /CompactOS:always

Le processus de compression peut prendre jusqu’à 20 minutes. Vous pouvez annuler la modification à tout moment avec Compact.exe /CompactOS:never.

Vous pouvez également économiser de l’espace en réduisant les fichiers de mémoire virtuelle et d’hibernation. Ouvrez une invite de commandes en tant qu’administrateur et exécutez :

1
powercfg /h /type reduced

Cela réduit le fichier d’hibernation d’environ 30 %. Pour le supprimer entièrement :

1
powercfg /h /off

Pour restaurer le fichier d’hibernation complet plus tard :

1
powercfg /h /size 100

Extension de la taille de l’image QEmu

Pendant que la VM est arrêtée, redimensionnez l’image :

1
sudo qemu-img resize /var/lib/libvirt/images/win11.qcow2 +10G

Vous pouvez ensuite utiliser le Gestionnaire de disques de Windows pour étendre le système de fichiers sur l’espace nouvellement disponible.

Je n’ai pas pu déplacer la partition de récupération située entre le lecteur C: et l’espace non alloué depuis Windows. Pour contourner cela, vous pouvez utiliser les outils côté hôte :

1
2
sudo modprobe nbd max_part=16
sudo qemu-nbd -c /dev/nbd0 /var/lib/libvirt/images/win11.qcow2

Le gestionnaire de partitions KDE n’a initialement pas vu les 10 Go supplémentaires. GParted les a vus, mais a affiché un avertissement :

1
2
3
Not all of the space available to /dev/nbd0 appears to be used, you can fix
the GPT to use all of the space (an extra 20971520 blocks) or continue with
the current setting?

Après avoir réparé la table GPT, les deux outils ont fonctionné correctement :

1
sudo gparted /dev/nbd0

Une fois terminé, déconnectez l’image :

1
sudo qemu-nbd -d /dev/nbd0

Références