Windows 11 Upgrade
Upgrade einer bestehenden Windows-10 VM unter KVM/qemu auf Windows 11, trotz nicht unterstützter CPU
Hier ein grober Überblick, was diese Anleitung erreichen möchte: Es sollen die Voraussetzungen für ein Upgrade von Windows 10 auf Windows 11 erfüllt werden bzw. soll die entsprechende Prüfung von Windows 11 durchlaufen. Außerdem werden diverse Modernisierungen vorgenommen.
- Umstellung Partitionsschema von MBR nach GPT
- Umstellung von Legacy-BIOS nach UEFI (OVMF)
- Wechsel auf Q35-Chipsatz
- Fake-CPU (Skylake-Server-IBRS) für das Windows-Setup
- SATA statt IDE und Modernisierung auf Virt-IO SCSI
- Ausreichender Plattenplatz (Resize vorab)
- Host-Hardwareuhr auf UTC inklusive Hyper-V Enlightenments (hypervclock)
- I/O-Beschleunigung durch native AIO und Cache-Optimierung
- Backup der qcow2, XML und NVRAM-VARS vor Beginn
Vorab-Checks
64-Bit Windows erforderlich. In Windows-10-VM: Windows-Einstellungen → System → Info. Prüfen: „Systemtyp: 64-Bit-Betriebssystem“. Wenn 32 Bit: Windows-11-Upgrade nicht möglich.
TPM prüfen (vorher): msinfo32 öffnen. Unter „Systemübersicht“ → „Sicherheitschip“ sollte nicht vorhanden sein. Dies bestätigt, dass TPM erst aktiviert werden muss.
Ausgangslage
Host: Ubuntu 24.04 (wurde upgedated, von 14.04 kommend), KVM / libvirt / virt-manager. VM: Windows 10, Legacy-BIOS, MBR, Chipsatz: i440fx, CPU: Westmere, IDE-Controller, qcow2-Disk zu klein für Windows-11-Upgrade.
Ursprüngliche Partitionen (MBR):
| Nr. | Partition | Größe | Zweck |
|---|---|---|---|
| 1 | Systemreserviert | ~500 MB | Boot |
| 2 | C: | ~40 GB | Windows |
| 3 | Recovery | klein | Windows-Wiederherstellung |
Problem: mbr2gpt lief zunächst nicht, weil die Bootdateien nicht korrekt lagen.
Das Host-System wird betrieben mit einer Echtzeituhr (=RTC bzw. Hardware-Uhr), die auf UTC eingestellt ist. Das Host-System betreibt eine Zeitsynchronisation.
Das Host-System darf weiterhin Legacy-Bios nutzen, es ist also für das Host-System keine Umstellung auf UEFI nötig und auch das Partitionsschema muss nicht auf GPT umgestellt werden. Für das Host-System ist insbesondere auch keine EFI-Partition nötig.
Backup erstellen
Sicherung der VM (Backup)
Bevor tiefgreifende Änderungen vorgenommen werden, müssen die drei Kernkomponenten der VM gesichert werden. Wichtig: Für ein Backup muss die VM erst heruntergefahren werden und ausgeschaltet sein.
- Konfiguration sichern: Mit
virsh dumpxml win10_smss > win10_smss_backup.xmlwird die aktuelle Definition der VM in eine Datei exportiert. - Festplatten-Image kopieren: Die Datei (z. B.
/var/lib/libvirt/images/win10_smss.qcow2) an einen sicheren Ort kopieren. - NVRAM sichern: Falls vorhanden, die Datei unter
/var/lib/libvirt/qemu/nvram/win10_smss_VARS.fdmitsichern, da hier die UEFI-Einstellungen (wie Secure Boot Status) gespeichert sind.
Im Falle eines Fehlers kann die VM jederzeit durch das Zurückkopieren der qcow2-Datei und der NVRAM-Datei und den Befehl virsh define win10_smss_backup.xml wiederhergestellt werden.
Tipp: Falls man btrfs benutzt, benötigt ein einfaches Kopieren, z. B. mit cp win10_smss.qcow2 win10_smss_bak.qcow2 kaum zusätzlichen Speicher (so lange die Dateien gleich bleiben) und auch kaum zusätzliche Zeit zum Kopieren - dank copy-on-write.
Festplatte vergrößern und Partitionen anpassen
Da Windows 11 deutlich mehr Speicherplatz benötigt als Windows 10, erfolgt im ersten Schritt die Vergrößerung der virtuellen Festplatte (die .qcow2-Datei) auf dem Host-System (Ubuntu). Anschließend wird der neue Platz innerhalb der VM verteilt.
1. Datei auf dem Host vergrößern
Zuerst wird das Limit der Datei um 40 GB erhöht. Dazu dient folgender Befehl im Terminal des Ubuntu-Hosts:
qemu-img resize win10.qcow2 +40G2. Vorbereitung: SystemRescueCD booten
Da die Systempartition (C:) im laufenden Betrieb nicht verschieben werden kann, wird die SystemRescueCD genutzt. Wichtig: Die VM muss zu diesem Zeitpunkt noch mit dem alten BIOS und einer kompatiblen CPU (Westmere oder host-passthrough) konfiguriert sein, da die grafische Oberfläche der Rettungs-CD sonst nicht startet.
- Einbinden der SystemRescue-ISO in das virtuelle CD-Laufwerk der VM.
- Ändern der Boot-Reihenfolge in virt-manager.
- Start der VM und Boot von CD.
- Auswahl der Standard-Option im Startmenü.
3. Grafische Oberfläche und GParted starten
Sobald die Textkonsole erscheint, wird die grafische Umgebung mit folgendem Befehl geladen:
startxNachdem der Desktop geladen wurde, erfolgt der Start des Partitionierungswerkzeugs über das Terminal oder das Startmenü:
gparted4. Schritt-für-Schritt in GParted
In GParted ist nun die bestehende Belegung sowie am Ende ein grauer Block ("Unallocated") sichtbar. Die Schritte sind in dieser exakten Reihenfolge über die Funktion „Resize/Move“ auszuführen:
- Recovery-Partition verschieben: Die Recovery-Partition am Ende der Liste wird ausgewählt und ganz nach rechts an das Ende des Speichers verschoben. Dabei werden am ganz rechten Rand ca. 300 MB unzugeordneter Platz frei gelassen (dieser Bereich wird später für die neue EFI-Systempartition benötigt).
- C:-Partition vergrößern: Die Hauptpartition (C:) wird ausgewählt. Der rechte Rand der Partition wird so weit nach rechts gezogen, bis dieser direkt an die verschobene Recovery-Partition anstößt.
- Änderungen anwenden: Über das grüne Häkchen in der Werkzeugleiste („Apply all operations“) werden die geplanten Änderungen physisch auf die virtuelle Festplatte geschrieben.
Nach Abschluss der Operationen wird die VM heruntergefahren und die SystemRescueCD entfernt. Damit ist das Partitionsschema für die Umstellung auf UEFI vorbereitet.
Bootpartition präparieren (Voraussetzung für mbr2gpt)
In einer Windows-10-Eingabeaufforderung mit Admin-Rechten:
bcdboot C:\Windows /s C:Damit werden die Bootdateien neu auf C: geschrieben.
Boot-Flag auf C: setzen (MBR)
Mit Windows (diskpart):
diskpart
list disk
select disk 0
list partition
select partition 2
active
exitDie C:-Partition ist nun die aktive Boot-Partition.
An dieser Stelle unbedingt prüfen, ob die VM immer noch bootet.
Partitionsschema konvertieren (MBR → GPT)
In Windows (Admin-CMD):
mbr2gpt /validate /disk:0 /allowFullOS
mbr2gpt /convert /disk:0 /allowFullOS/allowFullOS wird nur benötigt, wenn Windows von dieser Festplatte gestartet wurde und aktuell läuft. Erst jetzt funktioniert das zuverlässig.
VM-XML bearbeiten
XML sichern:
virsh dumpxml win10_smss > win10_smss.xmlDie XML-Datei lässt sich im Folgenden immer einspielen mit:
virsh define win10_smss.xmlEinspielung der Datei testen und auch testen, ob die VM noch startet. Ggf. kann die Datei unverändert nicht mehr eingespielt werden. Dann den Fehlermeldungen folgend ändern.
Es wird empfohlen, die XML-Datei nach jeder Änderung einzuspielen, um bei Fehlern die Fehlerursache schnell eingrenzen zu können.
Umstellung auf UEFI + Q35 Chipsatz
OVMF-NVRAM vorbereiten:
cp /usr/share/OVMF/OVMF_VARS_4M.fd \
/var/lib/libvirt/qemu/nvram/win10_smss_VARS.fdXML-Abschnitt für das Betriebssystem:
<os firmware='efi'>
<type arch='x86_64' machine='pc-q35-8.2'>hvm</type>
<firmware>
<feature enabled='no' name='enrolled-keys'/>
<feature enabled='yes' name='secure-boot'/>
</firmware>
<loader readonly='yes' secure='yes' type='pflash'>
/usr/share/OVMF/OVMF_CODE_4M.secboot.fd
</loader>
<nvram template='/usr/share/OVMF/OVMF_VARS_4M.fd'>
/var/lib/libvirt/qemu/nvram/win10_smss_VARS.fd
</nvram>
</os>IDE auf SATA umstellen
p>SATA-Controller hinzufügen:
<controller type='sata' index='0'>
<address type='pci'
domain='0x0000'
bus='0x00'
slot='0x1f'
function='0x2'/>
</controller>CD-ROM auf SATA umstellen:
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<source file='/var/lib/libvirt/images/systemrescue.iso'/>
<target dev='sata0' bus='sata'/>
<readonly/>
</disk>CPU-Prüfung durch Windows 11 Update umschiffen
Im vorliegenden Beispiel ist die Intel i5-7440HQ CPU eine 7. Generation CPU. Windows 11 fordert jedoch mindestens eine 8. Generation CPU. Die CPU steht insbesondere nicht auf einer Liste der CPUs, die für Windows 11 freigegeben sind. Im Folgenden wird Windows daher eine andere CPU (="Fake-CPU") vorgegaukelt, die die CPU-Prüfung vor der Windows 11 Upgrade besteht.
<cpu mode='custom' match='exact' check='none'>
<model fallback='allow'>Skylake-Server-IBRS</model>
<topology sockets='1' dies='1' cores='4' threads='1'/>
<feature policy='disable' name='hypervisor'/>
<feature policy='require' name='vme'/>
</cpu>Hyper-V Enlightenments aktivieren
Ausgangslage: Host-System hat Hardware-Uhr auf UTC eingestellt und macht Zeitsynchronisation. Hyper-V Enlightenments via hypervclock stellt Windows eine spezielle Schnittstelle bereit, mit der Windows effizienter und genauer die Zeit abfragen kann.
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
<timer name='hypervclock' present='yes'/>
</clock>Windows 11 erkennt, wenn es unter KVM läuft, und kann spezielle "Abkürzungen" (Hyper-V-Features) nutzen. Ersetze den <features> Block durch diesen:
<features>
<acpi/>
<apic/>
<hyperv mode='custom'>
<relaxed state='on'/>
<vapic state='on'/>
<spinlocks state='on' retries='8191'/>
<vpindex state='on'/>
<runtime state='on'/>
<synic state='on'/>
<stimer state='on'/>
<reset state='on'/>
<frequencies state='on'/>
</hyperv>
<vmport state='off'/>
<smm state='on'/>
</features>TPM aktivieren
Im XML unter devices:
<tpm model='tpm-crb'>
<backend type='emulator' version='2.0'/>
</tpm>Windows-11-Upgrade starten
XML-Datei laden mit:
virsh define win10_smss.xmlVM starten
Wenn die VM noch startet, wäre jetzt nochmal eine gute Gelegenheit, ein Backup zu machen - in eine andere Zieldatei. Siehe oben.
Windows-Installationsmedium unter https://www.microsoft.com/de-de/software-download/windows11 herunterladen und mit virt-manager als CD-ROM einhängen.
setup.exe aus laufendem Windows 10 heraus starten und den Anweisungen folgen. NICHT von dem Windows-Installationsmedium booten!
Geduld: Schwarzer Bildschirm über Stunden normal. Falls nötig, nach 12 Stunden einen Reset in virt-manager erzwingen („Zurücksetzen erzwingen“). Danach setzt das Setup die Installation fehlerfrei fort.
Wenn Windows 11 fehlerfrei läuft, wäre jetzt nochmal eine gute Gelegenheit, ein Backup zu machen - in eine andere Zieldatei. Siehe oben.
Windows mit Echtzeituhr (RTC) auf UTC betreiben
Da das Host-System mit der Echtzeituhr (=Hardwareuhr) auf UTC betrieben wird, gibt es ein Problem. Windows erwartet üblicherweise, dass die Echtzeituhr mit lokaler Zeit betrieben wird. Infolge liegt während der Winterzeit (CEWT) entsprechend die angezeigte Zeit um eine Stunde zurück, wenn man in Windows CET einstellt. Man kann Windows jedoch mittels registry-Eintrag beibringen, dass die Echtzeituhr auf UTC eingestellt ist. PowerShell als Administrator starten.
reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /t REG_DWORD /d 1 /fZeitsynchronisation unter Windows abschalten (Zeitsynchronisation wird vom Host-System erledigt):
Set-Service w32time
StartupType Disabled
Stop-Service w32timeModernisierung der Virt-IO und QXL-Treiber
Umstellen von Virt-IO Block (virtio-blk bzw. vda) nach Virt-IO SCSI (virtio-scsi bzw. sda)
Damit Windows bootet, muss der Treiber vor der Umstellung geladen sein. Wir nutzen eine Dummy-Festplatte, um den Treiber zu erzwingen.
qemu-img create -f qcow2 -o preallocation=metadata dummy.qcow2 1GIm XML: Neue disk anlegen, neuen controller anlegen, CD-ROM ändern von sda auf sdb
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/libvirt/images/win10_smss.qcow2'/>
<target dev='vda' bus='virtio'/>
<boot order='1'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='none' io='native' discard='unmap'/>
<source file='/var/lib/libvirt/images/dummy.qcow2'/>
<target dev='sda' bus='scsi'/>
<boot order='2'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<source file='/home/thomas/Downloads/Win11_25H2_German_x64.iso'/>
<target dev='sdb' bus='sata'/>
<readonly/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
<controller type='scsi' index='0' model='virtio-scsi'>
<driver queues='4'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
</controller>Windows damit booten. Virt-IO Treiber ISO als CD-ROM einbinden. virtio-win-gt-x64.msi und virtio-win-guest-tools.exe installieren. Windows neu starten.
Windows herunterfahren. Systemfestplatte im XML umstellen und dummy-Festplatte entfernen:
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='none' io='native' discard='unmap'/>
<source file='/var/lib/libvirt/images/win10_smss.qcow2'/>
<target dev='sda' bus='scsi'/>
<boot order='1'/>
</disk>Windows starten. Aufräumen: rm dummy.qcow2
Zusätzlich I/O beschleunigen:
<driver name='qemu' type='qcow2' cache='none' io='native' discard='unmap'/>Warum das schneller ist:
- cache='none': Umgeht Host-Page-Cache, verhindert Double Buffering.
- io='native': Nutzt Linux AIO, effizienter bei NVMe/SSD, echtes Multithreading mit virtio-scsi.
- discard='unmap': Erlaubt Trim-Befehle, .qcow2 Datei wächst nicht unendlich.
Troubleshooting copy/paste
Im XML prüfen:
<controller type='virtio-serial' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
</controller>
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>Mit Installation der virtio-win-guest-tools.exe von der CD-ROM und Windows-Reboot sollte copy-paste im virt-manager (prüfen mit: Anzeige/Konsolen/Grafische Konsole Spice) dann eigentlich funktionieren.
Sound modernisieren von ich6 auf ich9
ich6 neigt in der VM zum Knistern und ist veraltet (ac97 sound). Ändere zu:
<sound model='ich9'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</sound>USB2-Controller auf USB3 ändern
Ersetzt 4-5 alte USB-Controller durch einen einzigen modernen USB 3.0 Standard, was CPU-Overhead spart und die Maus-Latenz verbessert. Alle USB-Controller ersetzen durch einmalig:
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
</controller>CPU auf host-passthrough umstellen
Zur besseren Performance, und um den Level3-Cache der Host-CPU mitzubenutzen.
<cpu mode='host-passthrough' check='none' migratable='on'>
<topology sockets='1' dies='1' cores='4' threads='1'/>
<cache mode='passthrough'/>
<feature policy='require' name='invtsc'/>
</cpu>invtsc (Invariant Time Stamp Counter) stellt der VM eine konstante CPU-Taktfrequenz bereit. Dies ist essenziell für präzises Timing in Windows 11 und ermöglicht der VM den direkten, performanten Hardware-Zugriff auf die Zeitquelle. Verhindert Zeit-Drift in der VM bei CPU-Taktänderungen (Turbo Boost) des Laptops.
XML-Datei formal modernisieren
XML-Konfiguration bereits für künftige Upgrades (z. B. auf Ubuntu 26.04) rüsten: Ändere <emulator>/usr/bin/kvm-spice</emulator> zu:
<emulator>/usr/bin/qemu-system-x86_64</emulator>Verhindert Warnung "this is an old compat wrapper script".