Home > Linux, Server stuff > How to boot Windows partition virtually under KVM with UEFI firmware

How to boot Windows partition virtually under KVM with UEFI firmware

It is actually quite easy to boot Windows virtualized using KVM. But to properly use the UEFI bootloader, suitable QEMU arguments are required. Here is a lightly commented QEMU command I use to boot virtual Windows 10 I have on a separate partition.


sudo qemu-system-x86_64 --enable-kvm -cpu host -m 2048 -smp 3 -mem-path /dev/hugepages \
-display sdl -vga qxl \
-device qemu-xhci,id=xhci \
-device virtio-tablet,wheel-axis=true \
-soundhw hda \
-netdev user,id=vmnic,smb=/temp \
-device virtio-net,netdev=vmnic \
-drive file=/usr/share/ovmf/x64/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on \
-drive file=$HOME/.config/qemu-windows.nvram,if=pflash,format=raw,unit=1 \
-drive file=/dev/sdb,index=0,media=disk,driver=raw \
-cdrom /opt/UefiShell.iso

For now I use sudo, because QEMU needs to access raw partitions from /dev/sdb. The other, better way would be assigning a group to /dev/sdb, setting up proper group permissions and adding me to that group.

-m 2048 -smp 3 says to allocate 2GB of RAM for the guest and use 3 CPU cores

-mem-path /dev/hugepages is better described in Arch wiki.

-display sdl -vga qxl Use SDL for rendering and window management in the host and QXL GPU device in the guest (there are QXL drivers for Windows).

-device qemu-xhci,id=xhci Enable USB3 support by emulating an XHCI controller

-device virtio-tablet,wheel-axis=true Emulate a tablet pointing device with mouse scroll support

-soundhw hda Emulate Intel HD Audio

netdev stuff Is for setting up network interface

-drive file=/usr/share/ovmf/x64/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on This is a very important part. It loads OVMF UEFI firmware read-only as the first Flash device. This firmware implements a UEFI bios and allows running UEFI Shell or booting .efi bootloader for Windows (bootmgfw.efi). This OVMF can be downloaded directly from the OVMF project repo or if you are using Arch Linux, just install ovmf package.

-drive file=$HOME/.config/qemu-windows.nvram,if=pflash,format=raw,unit=1 this loads a read-write NVRam flash image as the second virtual flash chip. OVMF firmware uses this to store UEFI variables, .efi boot order, etc. The default image can be copied from the OVMF setup (at /usr/share/ovmf/x64/OVMF_VARS.fd in ovmf Arch linux package). It must be a writable copy.

-drive file=/dev/sdb,index=0,media=disk,driver=raw Attaches my raw sdb block device to the virtual machine. That is used as a HDD for the guest, it has Windows pre-installed there together with EFI partition.

-cdrom /opt/UefiShell.iso UEFI shell iso as a CDROM. Before OVMF nvram is properly configured to boot Windows by default, this will result in booting into the EFI shell which allows to run .efi executables manually. Windows can be run by just navigating into the EFI partition and running the Windows efi loader – blkX:\EFI\Microsoft\Boot\bootmgfw.efi.

I don’t know how to force Windows to write UEFI boot order. There doesn’t seem to be a tool like efibootmgr on Windows. :D Windows would set the UEFI boot order up randomly during some Windows Updates (mostly when you don’t want it to touch your EFI setup). It eventually set the EFI config up for me itself quite quickly. But if it fails, you can always boot Linux using the -cdrom command and use efibootmgr to force the OVMF to boot the Windows loader entry for this virtual machine by default. Usage of the efibootmgr command is out of scope of this article and can be found in many online resources elsewhere.

Have fun with virtualized Windows and remember – Windows is good for games only and for stuff like government PDFs which use proprietary Adobe XFA forms and are therefore supported in official Adobe Reader which has the best support in this lousy platform only. Windows definitely shouldn’t be used on servers or anything serious! By default it is very limited (maximum number or RAM, maximum number of CPU cores, maximum number of listening socket connections, etc) until you pay huge amounts of money to Microsoft. Wise people use Linux and lazy people who don’t care about privacy or freedom use Mac OS X.

Categories: Linux, Server stuff Tags:
  1. defb
    August 1st, 2018 at 03:49 | #1

    I’m attempting to run this with debian testing (at the moment deb10), but unfortunately, the ovmf package in the deb repos don’t have /usr/share/ovmf/x64/OVMF_CODE.fd. Also, by OVMF_CODE.fd, do you mean copy it over to .config and renaming it qemu-windows.nvram? Other than that, I’m impressed at how you can virtualize a physical install of windows when virtual box has trouble doing it.

    • k3a
      August 1st, 2018 at 16:23 | #2

      For Debian (deb/apt) you can list the content of a package with
      # dpkg-query -L ovmf
      ...
      /usr/share/OVMF/OVMF_CODE.fd
      /usr/share/OVMF/OVMF_VARS.fd
      ...

      So just update the path.

      In my case qemu-windows.nvram is a “user” copy of OVMF_VARS.fd. It is mapped by QEMU as a second persistent flash (first being the actual UEFI bios binary which won’t change). This second flash (represented also as a file here) stores the bios settings – mainly boot order (the EFI boot order manages the OS like Windows or utility efibootmgr on Linux and BIOS stores it in this config flash). The original OVMF_VARS.fd contains the ‘default’ settings.

  2. Björn Carlsson
    August 6th, 2018 at 08:04 | #3

    Where did you find UefiShell.iso

  1. No trackbacks yet.