Warning: This is in draft and early testing. It's working for me so far, but I haven't tested many senarios yet, please use at your own risk.
I have Windows and Linux installed on the same SSD. I use Linux as my daily driver, and sometimes need to boot into Windows. This guide will enable you to:
- Boot your already installed Windows from within Linux
- Do it safely
- With full CPU/video passthrough and 3D acceleration
- With hardware/OEM Windows Product Key passthrough, so you don't need to reactivate Windows
A few reasons:
- A raw install of Windows is easier to fix than a QCOW2 image if it becomes corrupted
- I want Windows on an SSD, but I don't want to use an external SSD and my laptop doesn't have 2 Nvme ports
- It gives me more options of how and when I can use Windows, on my own terms
- It's kinda cool
So far, I think the risks are:
- Messing up your Linux drives, because you have to pass through the whole SSD to libvirt for this to work.
- That your local Windows won't boot normally any more
(These are the risks I'm trying to mitigate.)
- Use a loop device to access the Windows partition rather than accessing directly
- Fix booting between virtualised and raw Windows
- Install KVM (virt-manager)
sudo dnf install virt-manager libvirt qemu-kvm-core
Note: You shouldn't actually need to install the full qemu package if you've installed libvirt.
- Extract the Windows Activation data from the BIOS
midkr -p ~/.local/share/libvirt
cd ~/.local/share/libvirt
sudo cat /sys/firmware/acpi/tables/MSDM > msdm.bin
- Extract hardware UUID and serial etc. from the BIOS
cd ~/.local/share/libvirt
sudo dmidecode -t 0 > smbios0.txt
sudo dmidecode -t 1 > smbios1.txt
Note: I've copied these to /home because I'm exercising engineering laziness and don't need to remember to backup files in system folders 😜
In Virt-Manager:
- Select "Manual"
- Select "Windows 10"
- Manually type the disk partition e.g. /dev/nvme0n1p2 for your Windows partition, leave it as SATA
- Select e.g. 8192GB memory (half to 3/4 your RAM)
- Select e.g. 8 logical host CPUs (half to 3/4 your threads)
- Click "Customize"
- Click "XML"
- Change the first line to
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
- Add just above the last line
</domain>
, using the strings from yoursmbios0.txt
andsmbios1.txt
(Replace username
, uuid
, and serial
with your own)
<qemu:commandline>
<qemu:arg value="-acpitable"/>
<qemu:arg value="file=/home/insertyours/.local/share/libvirt/acpitable.bin"/>
<qemu:arg value="-acpitable"/>
<qemu:arg value="file=/home/insertyours/.local/share/libvirt/msdm.bin"/>
<qemu:arg value="-smbios"/>
<qemu:arg value="type=0,vendor=American Megatrends International LLC.,version=GA402RJ.315,date=09/21/2022,release=5.24"/>
<qemu:arg value="-smbios"/>
<qemu:arg value="type=1,manufacturer=ASUSTeK COMPUTER INC.,product=ROG Zephyrus G14 GA402RJ_GA402RJ,serial=insertyours,uuid=insertyours,family=ROG Zephyrus G14"/>
</qemu:commandline>
</domain>
- Click CPUs > Details
- Click "Manually set topology"
- Set e.g. Sockets = 1, Cores = 4, Threads = 2 to match the topology for the number of logical CPUs you've set
- Remove "Tablet"
- Update the XML for the NVRAM and make it writable:
sudo cp /usr/share/OVMF/OVMF_VARS.fd $HOME/.config/libvirt/win10.nvram
sudo chmod u+w $HOME/.config/libvirt/win10.nvram
- Change change the
<nvram>
entry in your XML to:
<nvram>$HOME/.config/libvirt/win10.nvram</nvram>
- Click Boot Order > Check "Show boot menu"
- Start the VM
- Immediately hit ESC to enter the UEFI menu. We're going to program the NVRAM to boot the correct partition
- Go into "Boot Management" > "Delete Boot Devices"
- Delete everything except the UEFI > Confirm and Exit
- Click "Add Boot Device"
- You should be presented with your EFI partition. Select it
- Select "EFI" > "Microsoft" > "bootmgfw.efi" (hidden at the bottom)
- Enter a nice name, for example "Windows 10" > Confirm and exit
- Select "Change Boot Order"
- Move "Windows 10" to the top > Confirm and exit
- Save and reboot
If all has gone well, your Windows should now boot 😊
- Right click the Start Menu > Device Manager
- View menu > Show hidden devices
- Expand Display Adapters
- Right click any AMD adapters > Uninstall > and select "Delete drivers"
- Do this for all AMD adapters, because we're about to pass them through, and will need a specific driver
- (Reboot if requested)
- Select virtio-win-latest.iso > Right-click > Mount
- Open the mounted drive and install using the exe
- Shutdown
- Click Boot Order > Disable "Show boot menu"
- Select the NIC > Change the model to virtio