Skip to content

Instantly share code, notes, and snippets.

@startergo
Last active November 30, 2025 00:44
Show Gist options
  • Select an option

  • Save startergo/9a46fec6caf879027518db08a13df503 to your computer and use it in GitHub Desktop.

Select an option

Save startergo/9a46fec6caf879027518db08a13df503 to your computer and use it in GitHub Desktop.
Build QEMU with enabled Hyper-v acceleration (WHPX) and Intel acceleration (HAXM) on Windows

Build QEMU with enabled Hyper-V acceleration (WHPX) and Intel acceleration (HAXM) on Windows

Windows Hypervisor Platform

I assume you're familiar with the WHP(Windows Hypervisor Platform), and you know how enable it, if not read this Install Hyper-V on Windows 10


There is two way to build QEMU for windows:

1 - Use a Linux machine and cross-compiling using MinGW compiler.

2 - Use MSYS2/MinGW on Windows.

As the title implies our choose is number two, so we're going to build QEMU(At this time version 7.2.0) from source with enabled Hyper-v acceleration (WHPX) on Windows 10

Requirements

Note : Installation of Windows SDK 10 is not necessary, so you only need these three header files listed bellow. It depends on you to install the whole SDK or just copy the header files form another source.

WinHvEmulation.h

WinHvPlatform.h

WinHvPlatformDefs.h


Start the MSYS2 environment :

Install the MSYS/MinGW 64-bit required packages:

# Upgrade installed packages
pacman -Suy --noconfirm

# Install basic packets
# You can only install [make pkg-config bison diffutils] packages instead of the whole base-devel package
pacman -Sy --noconfirm --needed base-devel mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc git mingw-w64-x86_64-meson

# Install QEMU specific packets
pacman -Sy --noconfirm --needed \
mingw-w64-x86_64-ninja \
mingw-w64-x86_64-python \
mingw-w64-x86_64-python-sphinx \
mingw-w64-x86_64-python-sphinx_rtd_theme \
mingw-w64-x86_64-autotools \
mingw-w64-x86_64-tools-git \
mingw-w64-x86_64-cc \
mingw-w64-x86_64-angleproject \
mingw-w64-x86_64-capstone \
mingw-w64-x86_64-curl \
mingw-w64-x86_64-cyrus-sasl \
mingw-w64-x86_64-expat \
mingw-w64-x86_64-fontconfig \
mingw-w64-x86_64-freetype \
mingw-w64-x86_64-fribidi \
mingw-w64-x86_64-gcc-libs \
mingw-w64-x86_64-gdk-pixbuf2 \
mingw-w64-x86_64-gettext \
mingw-w64-x86_64-glib2 \
mingw-w64-x86_64-gmp \
mingw-w64-x86_64-gnutls \
mingw-w64-x86_64-graphite2 \
mingw-w64-x86_64-gst-plugins-base \
mingw-w64-x86_64-gstreamer \
mingw-w64-x86_64-gtk3 \
mingw-w64-x86_64-harfbuzz \
mingw-w64-x86_64-jbigkit \
mingw-w64-x86_64-lerc \
mingw-w64-x86_64-libc++ \
mingw-w64-x86_64-libdatrie \
mingw-w64-x86_64-libdeflate \
mingw-w64-x86_64-libepoxy \
mingw-w64-x86_64-libffi \
mingw-w64-x86_64-libiconv \
mingw-w64-x86_64-libidn2 \
mingw-w64-x86_64-libjpeg-turbo \
mingw-w64-x86_64-libnfs \
mingw-w64-x86_64-libpng \
mingw-w64-x86_64-libpsl \
mingw-w64-x86_64-libslirp \
mingw-w64-x86_64-libssh \
mingw-w64-x86_64-libssh2 \
mingw-w64-x86_64-libtasn1 \
mingw-w64-x86_64-libthai \
mingw-w64-x86_64-libtiff \
mingw-w64-x86_64-libunistring \
mingw-w64-x86_64-libunwind \
mingw-w64-x86_64-libusb \
mingw-w64-x86_64-libwebp \
mingw-w64-x86_64-libwinpthread-git \
mingw-w64-x86_64-lz4 \
mingw-w64-x86_64-lzo2 \
mingw-w64-x86_64-nettle \
mingw-w64-x86_64-openssl \
mingw-w64-x86_64-opus \
mingw-w64-x86_64-orc \
mingw-w64-x86_64-p11-kit \
mingw-w64-x86_64-pango \
mingw-w64-x86_64-pkgconf \
mingw-w64-x86_64-SDL2 \
mingw-w64-x86_64-SDL2_image \
mingw-w64-x86_64-python-sphinx \
mingw-w64-x86_64-snappy \
mingw-w64-x86_64-spice-protocol \
mingw-w64-x86_64-spice \
mingw-w64-x86_64-usbredir \
mingw-w64-x86_64-xz \
mingw-w64-x86_64-zlib \
mingw-w64-i686-msitools \
mingw-w64-x86_64-virglrenderer \
mingw-w64-x86_64-zstd
  

* You can obtain more information about each package by using pacman -Q --info PACKAGE_NAME command.

Clone the QEMU git repository after the MSYS/MinGW toolchain prepared:

git clone https://github.com/qemu/qemu/
cd qemu
git switch -c stable-7.2 origin/stable-7.2
git submodule init
git submodule update --recursive
  • You can build with Qemu stable-8.1 as the HAXM support was dropped in Qemu stable-8.2
  • HAXM states that it supports up to stable-7.2

The Device Guard and Credential Guard hardware readiness tool released by Microsoft can disable the Hyper-V Windows 10 features along with Hyper-V. You can either run WHPX or HAXM, but not both:

  • Download the latest version of the tool from here. The following steps assume version 3.6.
  • Unzip.
  • Open an elevated (i.e. Run as administrator) Command Prompt:
@powershell -ExecutionPolicy RemoteSigned -Command "X:\path\to\dgreadiness_v3.6\DG_Readiness_Tool_v3.6.ps1 -Disable"
  • To disable HAXM and enable WHPX you have to run the tool in reverse order replacing -Disable switch with -Enable
  • You can compile Qemu with the latest source code by dropping this line:
git switch -c stable-7.2 origin/stable-7.2

But you have to drop --enable-hax

  • Reboot.

Copy the required header files of WHP from Windows SDK to the MinGW toolchain:

As I mentioned before you don't have to install the Windows SDK you just need three header files, anyway if you have the Windows SDK installed, you may have multiple versions of it. With the following powershell command you can simple get list of all Windows SDKs were already installed on your machine.

Get-ChildItem "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows Kits\Installed Roots"
PS C:\Users\UserName> Get-ChildItem "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows Kits\Installed Roots"


    Hive: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Kits\Installed Roots


Name                           Property
----                           --------
10.0.17134.0
10.0.17763.0
10.0.18362.0

After you choose your target SDK version just run this command with your SDK version! to copy the header files to MinGW setup

# If include directory is missing create it:
mkdir  /mingw64/x86_64-w64-mingw32/include/
cp /c/Program\ Files\ \(x86\)/Windows\ Kits/10/Include/10.0.26100.0/um/WinHv*\
 /mingw64/x86_64-w64-mingw32/include/

Configure the build system:

In this example I just built the QEMU with my minimum requirements, you can see more options by running this command $ ./configure --help

Show All Available options

$ ./configure --help

Usage: configure [options]
Options: [defaults in brackets after descriptions]

Standard options:
  --help                   print this message
  --prefix=PREFIX          install in PREFIX [c:/Program Files/QEMU]
  --interp-prefix=PREFIX   where to find shared libraries, etc.
                           use %M for cpu name [/usr/gnemul/qemu-%M]
  --target-list=LIST       set target list (default: build everything)
                           Available targets: aarch64-softmmu alpha-softmmu
                           arm-softmmu cris-softmmu hppa-softmmu i386-softmmu
                           lm32-softmmu m68k-softmmu microblazeel-softmmu
                           microblaze-softmmu mips64el-softmmu mips64-softmmu
                           mipsel-softmmu mips-softmmu moxie-softmmu
                           nios2-softmmu or1k-softmmu ppc64-softmmu ppc-softmmu
                           riscv32-softmmu riscv64-softmmu s390x-softmmu
                           sh4eb-softmmu sh4-softmmu sparc64-softmmu
                           sparc-softmmu tricore-softmmu unicore32-softmmu
                           x86_64-softmmu xtensaeb-softmmu xtensa-softmmu
  --target-list-exclude=LIST exclude a set of targets from the default target-list

Advanced options (experts only):
  --cross-prefix=PREFIX    use PREFIX for compile tools []
  --cc=CC                  use C compiler CC [cc]
  --iasl=IASL              use ACPI compiler IASL [iasl]
  --host-cc=CC             use C compiler CC [cc] for code run at
                           build time
  --cxx=CXX                use C++ compiler CXX [c++]
  --objcc=OBJCC            use Objective-C compiler OBJCC [cc]
  --extra-cflags=CFLAGS    append extra C compiler flags QEMU_CFLAGS
  --extra-cxxflags=CXXFLAGS append extra C++ compiler flags QEMU_CXXFLAGS
  --extra-ldflags=LDFLAGS  append extra linker flags LDFLAGS
  --cross-cc-ARCH=CC       use compiler when building ARCH guest test cases
  --cross-cc-flags-ARCH=   use compiler flags when building ARCH guest tests
  --make=MAKE              use specified make [make]
  --install=INSTALL        use specified install [install]
  --python=PYTHON          use specified python [python3]
  --smbd=SMBD              use specified smbd [/usr/sbin/smbd]
  --with-git=GIT           use specified git [git]
  --static                 enable static build [no]
  --mandir=PATH            install man pages in PATH
  --datadir=PATH           install firmware in PATH
  --docdir=PATH            install documentation in PATH
  --bindir=PATH            install binaries in PATH
  --libdir=PATH            install libraries in PATH
  --libexecdir=PATH        install helper binaries in PATH
  --sysconfdir=PATH        install config in PATH
  --localstatedir=PATH     install local state in PATH (set at runtime on win32)
  --firmwarepath=PATH      search PATH for firmware files
  --with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir []
  --with-pkgversion=VERS   use specified string as sub-version of the package
  --enable-debug           enable common debug build options
  --enable-sanitizers      enable default sanitizers
  --disable-strip          disable stripping binaries
  --disable-werror         disable compilation abort on warning
  --disable-stack-protector disable compiler-provided stack protection
  --audio-drv-list=LIST    set audio drivers list:
                           Available drivers: dsound sdl
  --block-drv-whitelist=L  Same as --block-drv-rw-whitelist=L
  --block-drv-rw-whitelist=L
                           set block driver read-write whitelist
                           (affects only QEMU, not qemu-img)
  --block-drv-ro-whitelist=L
                           set block driver read-only whitelist
                           (affects only QEMU, not qemu-img)
  --enable-trace-backends=B Set trace backend
                           Available backends: dtrace ftrace log simple syslog ust
  --with-trace-file=NAME   Full PATH,NAME of file to store traces
                           Default:trace-<pid>
  --disable-slirp          disable SLIRP userspace network connectivity
  --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)
  --enable-malloc-trim     enable libc malloc_trim() for memory optimization
  --oss-lib                path to OSS library
  --cpu=CPU                Build for host CPU [x86_64]
  --with-coroutine=BACKEND coroutine backend. Supported options:
                           ucontext, sigaltstack, windows
  --enable-gcov            enable test coverage analysis with gcov
  --gcov=GCOV              use specified gcov [gcov]
  --disable-blobs          disable installing provided firmware blobs
  --with-vss-sdk=SDK-path  enable Windows VSS support in QEMU Guest Agent
  --with-win-sdk=SDK-path  path to Windows Platform SDK (to build VSS .tlb)
  --tls-priority           default TLS protocol/cipher priority string
  --enable-gprof           QEMU profiling with gprof
  --enable-profiler        profiler support
  --enable-debug-stack-usage
                           track the maximum stack usage of stacks created by qemu_alloc_stack

Optional features, enabled with --enable-FEATURE and
disabled with --disable-FEATURE, default is enabled if available:

  system          all system emulation targets
  user            supported user emulation targets
  linux-user      all linux usermode emulation targets
  bsd-user        all BSD usermode emulation targets
  docs            build documentation
  guest-agent     build the QEMU Guest Agent
  guest-agent-msi build guest agent Windows MSI installation package
  pie             Position Independent Executables
  modules         modules support (non-Windows)
  debug-tcg       TCG debugging (default is disabled)
  debug-info      debugging information
  sparse          sparse checker

  gnutls          GNUTLS cryptography support
  nettle          nettle cryptography support
  gcrypt          libgcrypt cryptography support
  auth-pam        PAM access control
  sdl             SDL UI
  sdl-image       SDL Image support for icons
  gtk             gtk UI
  vte             vte support for the gtk UI
  curses          curses UI
  iconv           font glyph conversion support
  vnc             VNC UI support
  vnc-sasl        SASL encryption for VNC server
  vnc-jpeg        JPEG lossy compression for VNC server
  vnc-png         PNG compression for VNC server
  cocoa           Cocoa UI (Mac OS X only)
  virtfs          VirtFS
  mpath           Multipath persistent reservation passthrough
  xen             xen backend driver support
  xen-pci-passthrough    PCI passthrough support for Xen
  brlapi          BrlAPI (Braile)
  curl            curl connectivity
  membarrier      membarrier system call (for Linux 4.14+ or Windows)
  fdt             fdt device tree
  bluez           bluez stack connectivity
  kvm             KVM acceleration support
  hax             HAX acceleration support
  hvf             Hypervisor.framework acceleration support
  whpx            Windows Hypervisor Platform acceleration support
  rdma            Enable RDMA-based migration
  pvrdma          Enable PVRDMA support
  vde             support for vde network
  netmap          support for netmap network
  linux-aio       Linux AIO support
  cap-ng          libcap-ng support
  attr            attr and xattr support
  vhost-net       vhost-net kernel acceleration support
  vhost-vsock     virtio sockets device support
  vhost-scsi      vhost-scsi kernel target support
  vhost-crypto    vhost-user-crypto backend support
  vhost-kernel    vhost kernel backend support
  vhost-user      vhost-user backend support
  spice           spice
  rbd             rados block device (rbd)
  libiscsi        iscsi support
  libnfs          nfs support
  smartcard       smartcard support (libcacard)
  libusb          libusb (for usb passthrough)
  live-block-migration   Block migration in the main migration stream
  usb-redir       usb network redirection support
  lzo             support of lzo compression library
  snappy          support of snappy compression library
  bzip2           support of bzip2 compression library
                  (for reading bzip2-compressed dmg images)
  lzfse           support of lzfse compression library
                  (for reading lzfse-compressed dmg images)
  seccomp         seccomp support
  coroutine-pool  coroutine freelist (better performance)
  glusterfs       GlusterFS backend
  tpm             TPM support
  libssh          ssh block device support
  numa            libnuma support
  libxml2         for Parallels image format
  tcmalloc        tcmalloc support
  jemalloc        jemalloc support
  avx2            AVX2 optimization support
  replication     replication support
  opengl          opengl support
  virglrenderer   virgl rendering support
  xfsctl          xfsctl support
  qom-cast-debug  cast debugging support
  tools           build qemu-io, qemu-nbd and qemu-img tools
  vxhs            Veritas HyperScale vDisk backend support
  bochs           bochs image format support
  cloop           cloop image format support
  dmg             dmg image format support
  qcow1           qcow v1 image format support
  vdi             vdi image format support
  vvfat           vvfat image format support
  qed             qed image format support
  parallels       parallels image format support
  sheepdog        sheepdog block driver support
  crypto-afalg    Linux AF_ALG crypto backend driver
  capstone        capstone disassembler support
  debug-mutex     mutex debugging support
  libpmem         libpmem support

NOTE: The object files are built at the place where configure is launched

__

You can specify your Build directory for binary files through --prefix= option, in this example I passed the ../../QEMU-7.2.0-bin directory to it, so after you run make install it will put all binary files in this directory for you. It's a good idea to use a variable instead of hardcoding it evrywhere (E.g. BUILD_PATH=$HOME/QEMU-4.1.0-bin/)

BUILD_PATH=$HOME/QEMU-7.2.0-bin/
mkdir build
cd build
../configure \                                                                      
 --prefix=$BUILD_PATH\
 --target-list=x86_64-softmmu,i386-softmmu\
 --enable-whpx\
 --enable-avx2 \
 --enable-dmg \
 --enable-avx512bw \
 --enable-parallels \
 --enable-virglrenderer \
 --enable-aehd \
 --enable-hax \
 --enable-tools\
 --enable-lzo\
 --enable-bzip2\
 --enable-sdl \
 --enable-gtk\
 --enable-vdi \
 --enable-qcow1\
 --disable-capstone \
 --enable-spice \
 --enable-spice-protocol \
 --enable-tools \
 --enable-vhdx \
 --enable-vhost-net \
 --enable-vmdk \
 --enable-vvfat \
 --enable-gtk \
 --enable-gtk-clipboard \
 --enable-guest-agent \
 --enable-opengl \
 --disable-werror
Show used options descriptions

# whpx            Windows Hypervisor Platform acceleration support
# hax             Intel Hypervisor Platform acceleration support
# tools           build qemu-io, qemu-nbd and qemu-img tools
# lzo             support of lzo compression library
# bzip2           support of bzip2 compression library (for reading bzip2-compressed dmg images)
# sdl             SDL UI
# gtk             gtk UI
# hax             HAX acceleration support
# vdi             vdi image format support
# qcow1           qcow v1 image format support
# capstone        capstone disassembler support

Build and Install(Copy the binary files):

Start the build process

meson compile

After the build process finished run this commands to copy all binary files to your build directory

BUILD_PATH=$HOME/QEMU-7.2.0-bin/
mkdir $BUILD_PATH

meson install

When you run meson install it copies the binary files to build directory, but debug information and symbols are striped from these files, if you need this information just run this command to copy unmodified binary files.

cp x86_64-softmmu/*.exe $BUILD_PATH
cp i386-softmmu/*.exe $BUILD_PATH

:'
x86_64-softmmu/*.exe
  ├───qemu-system-x86_64.exe
  └───qemu-system-x86_64w.exe

i386-softmmu/*.exe
  ├───qemu-system-i386.exe
  └───qemu-system-i386w.exe
'

The End

C:\msys64\home\UserName\QEMU-7.2.0-bin>qemu-system-x86_64.exe --version
QEMU emulator version 4.1.50 (v4.1.0-733-g89ea03a7dc-dirty)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
Show Directory List of QEMU-7.2.0-bin

$  ls -la $BUILD_PATH
total 285581
drwxr-xr-x 1 UserName None        0 Sep 11 13:37 .
drwxr-xr-x 1 UserName None        0 Sep 11 13:36 ..
drwxr-xr-x 1 UserName None        0 Sep 11 13:35 applications
-rw-r--r-- 1 UserName None     3211 Sep 11 13:35 bamboo.dtb
-rw-r--r-- 1 UserName None   131072 Sep 11 13:35 bios.bin
-rw-r--r-- 1 UserName None   262144 Sep 11 13:35 bios-256k.bin
-rw-r--r-- 1 UserName None     9779 Sep 11 13:35 canyonlands.dtb
-rw-r--r-- 1 UserName None 67108864 Sep 11 13:35 edk2-aarch64-code.fd
-rw-r--r-- 1 UserName None 67108864 Sep 11 13:35 edk2-arm-code.fd
-rw-r--r-- 1 UserName None 67108864 Sep 11 13:35 edk2-arm-vars.fd
-rw-r--r-- 1 UserName None  3653632 Sep 11 13:35 edk2-i386-code.fd
-rw-r--r-- 1 UserName None  3653632 Sep 11 13:35 edk2-i386-secure-code.fd
-rw-r--r-- 1 UserName None   540672 Sep 11 13:35 edk2-i386-vars.fd
-rw-r--r-- 1 UserName None    42903 Sep 11 13:35 edk2-licenses.txt
-rw-r--r-- 1 UserName None  3653632 Sep 11 13:35 edk2-x86_64-code.fd
-rw-r--r-- 1 UserName None  3653632 Sep 11 13:35 edk2-x86_64-secure-code.fd
-rw-r--r-- 1 UserName None   240128 Sep 11 13:35 efi-e1000.rom
-rw-r--r-- 1 UserName None   240128 Sep 11 13:35 efi-e1000e.rom
-rw-r--r-- 1 UserName None   240128 Sep 11 13:35 efi-eepro100.rom
-rw-r--r-- 1 UserName None   238592 Sep 11 13:35 efi-ne2k_pci.rom
-rw-r--r-- 1 UserName None   238592 Sep 11 13:35 efi-pcnet.rom
-rw-r--r-- 1 UserName None   242688 Sep 11 13:35 efi-rtl8139.rom
-rw-r--r-- 1 UserName None   242688 Sep 11 13:35 efi-virtio.rom
-rw-r--r-- 1 UserName None   236032 Sep 11 13:35 efi-vmxnet3.rom
drwxr-xr-x 1 UserName None        0 Sep 11 13:35 firmware
-rw-r--r-- 1 UserName None   783724 Sep 11 13:35 hppa-firmware.img
drwxr-xr-x 1 UserName None        0 Sep 11 13:35 icons
drwxr-xr-x 1 UserName None        0 Sep 11 13:35 keymaps
-rw-r--r-- 1 UserName None     9216 Sep 11 13:35 kvmvapic.bin
-rwxr-xr-x 1 UserName None   139373 Sep 11 13:37 libatk-1.0-0.dll
-rwxr-xr-x 1 UserName None    74771 Sep 11 13:37 libbz2-1.dll
-rwxr-xr-x 1 UserName None  1015140 Sep 11 13:37 libcairo-2.dll
-rwxr-xr-x 1 UserName None    37749 Sep 11 13:37 libcairo-gobject-2.dll
-rwxr-xr-x 1 UserName None    36029 Sep 11 13:37 libdatrie-1.dll
-rwxr-xr-x 1 UserName None  1682539 Sep 11 13:37 libepoxy-0.dll
-rwxr-xr-x 1 UserName None   183228 Sep 11 13:37 libexpat-1.dll
-rwxr-xr-x 1 UserName None    34176 Sep 11 13:37 libffi-6.dll
-rwxr-xr-x 1 UserName None   294979 Sep 11 13:37 libfontconfig-1.dll
-rwxr-xr-x 1 UserName None   682123 Sep 11 13:37 libfreetype-6.dll
-rwxr-xr-x 1 UserName None   141883 Sep 11 13:37 libfribidi-0.dll
-rwxr-xr-x 1 UserName None    85136 Sep 11 13:37 libgcc_s_seh-1.dll
-rwxr-xr-x 1 UserName None   171040 Sep 11 13:37 libgdk_pixbuf-2.0-0.dll
-rwxr-xr-x 1 UserName None  1243245 Sep 11 13:37 libgdk-3-0.dll
-rwxr-xr-x 1 UserName None  1524386 Sep 11 13:37 libgio-2.0-0.dll
-rwxr-xr-x 1 UserName None  1162600 Sep 11 13:37 libglib-2.0-0.dll
-rwxr-xr-x 1 UserName None    26808 Sep 11 13:37 libgmodule-2.0-0.dll
-rwxr-xr-x 1 UserName None   318421 Sep 11 13:37 libgobject-2.0-0.dll
-rwxr-xr-x 1 UserName None   154260 Sep 11 13:37 libgraphite2.dll
-rwxr-xr-x 1 UserName None  6593944 Sep 11 13:37 libgtk-3-0.dll
-rwxr-xr-x 1 UserName None   984148 Sep 11 13:37 libharfbuzz-0.dll
-rwxr-xr-x 1 UserName None  1055522 Sep 11 13:37 libiconv-2.dll
-rwxr-xr-x 1 UserName None   135218 Sep 11 13:37 libintl-8.dll
-rwxr-xr-x 1 UserName None   638393 Sep 11 13:37 libjpeg-8.dll
-rwxr-xr-x 1 UserName None   143727 Sep 11 13:37 liblzo2-2.dll
-rwxr-xr-x 1 UserName None   260720 Sep 11 13:37 libpango-1.0-0.dll
-rwxr-xr-x 1 UserName None    71379 Sep 11 13:37 libpangocairo-1.0-0.dll
-rwxr-xr-x 1 UserName None    94480 Sep 11 13:37 libpangoft2-1.0-0.dll
-rwxr-xr-x 1 UserName None   101742 Sep 11 13:37 libpangowin32-1.0-0.dll
-rwxr-xr-x 1 UserName None   287905 Sep 11 13:37 libpcre-1.dll
-rwxr-xr-x 1 UserName None   677220 Sep 11 13:37 libpixman-1-0.dll
-rwxr-xr-x 1 UserName None   231911 Sep 11 13:37 libpng16-16.dll
-rwxr-xr-x 1 UserName None    21134 Sep 11 13:37 libssp-0.dll
-rwxr-xr-x 1 UserName None  1759933 Sep 11 13:37 libstdc++-6.dll
-rwxr-xr-x 1 UserName None    68018 Sep 11 13:37 libthai-0.dll
-rwxr-xr-x 1 UserName None    56844 Sep 11 13:37 libwinpthread-1.dll
-rw-r--r-- 1 UserName None     1024 Sep 11 13:35 linuxboot.bin
-rw-r--r-- 1 UserName None     1536 Sep 11 13:35 linuxboot_dma.bin
-rw-r--r-- 1 UserName None     1024 Sep 11 13:35 multiboot.bin
-rw-r--r-- 1 UserName None   767256 Sep 11 13:35 openbios-ppc
-rw-r--r-- 1 UserName None   382048 Sep 11 13:35 openbios-sparc32
-rw-r--r-- 1 UserName None  1593408 Sep 11 13:35 openbios-sparc64
-rw-r--r-- 1 UserName None    36888 Sep 11 13:35 opensbi-riscv32-virt-fw_jump.bin
-rw-r--r-- 1 UserName None    40968 Sep 11 13:35 opensbi-riscv64-sifive_u-fw_jump.bin
-rw-r--r-- 1 UserName None    40968 Sep 11 13:35 opensbi-riscv64-virt-fw_jump.bin
-rw-r--r-- 1 UserName None   156328 Sep 11 13:35 palcode-clipper
-rw-r--r-- 1 UserName None     9982 Sep 11 13:35 petalogix-ml605.dtb
-rw-r--r-- 1 UserName None     8259 Sep 11 13:35 petalogix-s3adsp1800.dtb
-rw-r--r-- 1 UserName None  1048576 Sep 11 13:35 ppc_rom.bin
-rw-r--r-- 1 UserName None     1536 Sep 11 13:35 pvh.bin
-rw-r--r-- 1 UserName None    67072 Sep 11 13:35 pxe-e1000.rom
-rw-r--r-- 1 UserName None    61440 Sep 11 13:35 pxe-eepro100.rom
-rw-r--r-- 1 UserName None    61440 Sep 11 13:35 pxe-ne2k_pci.rom
-rw-r--r-- 1 UserName None    61440 Sep 11 13:35 pxe-pcnet.rom
-rw-r--r-- 1 UserName None    61440 Sep 11 13:35 pxe-rtl8139.rom
-rw-r--r-- 1 UserName None    60416 Sep 11 13:35 pxe-virtio.rom
-rw-r--r-- 1 UserName None      850 Sep 11 13:35 QEMU,cgthree.bin
-rw-r--r-- 1 UserName None     1402 Sep 11 13:35 QEMU,tcx.bin
-rw-r--r-- 1 UserName None    18752 Sep 11 13:35 qemu_vga.ndrv
-rwxr-xr-x 1 UserName None    86016 Sep 11 13:35 qemu-edid.exe
-rwxr-xr-x 1 UserName None   400896 Sep 11 13:35 qemu-ga.exe
-rwxr-xr-x 1 UserName None  1538560 Sep 11 13:35 qemu-img.exe
-rwxr-xr-x 1 UserName None  1491456 Sep 11 13:35 qemu-io.exe
-rw-r--r-- 1 UserName None   154542 Sep 11 13:35 qemu-nsis.bmp
-rwxr-xr-x 1 UserName None  9132032 Sep 11 13:35 qemu-system-i386.exe
-rwxr-xr-x 1 UserName None  9132032 Sep 11 13:35 qemu-system-i386w.exe
-rwxr-xr-x 1 UserName None  9165312 Sep 11 13:35 qemu-system-x86_64.exe
-rwxr-xr-x 1 UserName None  9165312 Sep 11 13:35 qemu-system-x86_64w.exe
-rw-r--r-- 1 UserName None    42608 Sep 11 13:35 s390-ccw.img
-rw-r--r-- 1 UserName None    67232 Sep 11 13:35 s390-netboot.img
-rwxr-xr-x 1 UserName None  1275183 Sep 11 13:37 SDL2.dll
-rw-r--r-- 1 UserName None     4096 Sep 11 13:35 sgabios.bin
drwxr-xr-x 1 UserName None        0 Sep 11 13:35 share
-rw-r--r-- 1 UserName None  1667280 Sep 11 13:35 skiboot.lid
-rw-r--r-- 1 UserName None   930656 Sep 11 13:35 slof.bin
-rw-r--r-- 1 UserName None       20 Sep 11 13:35 spapr-rtas.bin
-rw-r--r-- 1 UserName None   310010 Sep 11 13:35 trace-events-all
-rw-r--r-- 1 UserName None   349148 Sep 11 13:35 u-boot.e500
-rw-r--r-- 1 UserName None   524288 Sep 11 13:35 u-boot-sam460-20100605.bin
-rw-r--r-- 1 UserName None    38400 Sep 11 13:35 vgabios.bin
-rw-r--r-- 1 UserName None    38912 Sep 11 13:35 vgabios-ati.bin
-rw-r--r-- 1 UserName None    27648 Sep 11 13:35 vgabios-bochs-display.bin
-rw-r--r-- 1 UserName None    38400 Sep 11 13:35 vgabios-cirrus.bin
-rw-r--r-- 1 UserName None    38912 Sep 11 13:35 vgabios-qxl.bin
-rw-r--r-- 1 UserName None    28160 Sep 11 13:35 vgabios-ramfb.bin
-rw-r--r-- 1 UserName None    38912 Sep 11 13:35 vgabios-stdvga.bin
-rw-r--r-- 1 UserName None    38912 Sep 11 13:35 vgabios-virtio.bin
-rw-r--r-- 1 UserName None    38912 Sep 11 13:35 vgabios-vmware.bin
-rwxr-xr-x 1 UserName None    93720 Sep 11 13:37 zlib1.dll


Written by @rceninja 2019

Building Qemu

To use qemu on WIndows with hardware acceleration you first start by enabling Hyper-V if it isn't enabled already. Next, run qemu with the following additional option:

--accel whpx,kernel-irqchip=off

Or with:

-machine q35,hpet=off,smm=off,vmport=off,accel=whpx

WHPX crashes using separate OVMF CODE & VARS, so combine these to a single file :

copy /B OVMF_VARS.fd + OVMF_CODE.fd OVMF_combined.fd
  • Add Virgl acceleration
  • To prevent dynamic loading of the binaries you need to add "$HOME\QEMU-7.2.0-bin", "$HOME\QEMU-7.2.0-bin\share" and "$HOME/../../mingw64/bin" to the $PATH environmental variable.
  • Run Qemu:
qemu-system-x86_64 -L "$HOME\QEMU-7.2.0-bin" -L "$HOME\QEMU-7.2.0-bin\share" "$HOME/../../mingw64/bin" -accel help
Accelerators supported in QEMU binary:
tcg
hax
whpx
C:\msys64\home\<user_name>\QEMU-8.1.0-bin
C:\msys64\home\<user_name>\QEMU-8.1.0-bin\share
C:\msys64\mingw64\bin
  • Add Qemu to the MingW64's path in the .bash_profile (residing in $HOME/.bash_profile) so Qemu is accesible from MingW64`.
# Set PATH so it includes user's private bin if it exists
  if [ -d "${HOME}/QEMU-8.1.0-bin" ] ; then
    PATH="${HOME}/QEMU-8.1.0-bin:${PATH}"
  fi
  • Adjust the path as required.

  • Test the acceleration with macOS on Qemu. Based on this site. You need to create the machine with the folder in Linux. I used endeavouros and Quickemu. Run Quickemu on the same machine so the Host CPU vendor is detected and guest CPU is optimised accordingly.

  • After creating the VM in Linux copy the folder to Windows and adjust the paths for the drives and there names accordingly in the batch file below.

Note:

  • With Ventura, the shared cache is now off of the Root volume and instead inside the Preboot volume. Thus the Rosetta cache is not available to us if it wasn't installed during the installation.

  • With the advent of CryptexFixup.kext, Rosetta Cryptex will now automatically be installed during OS installs and updates when a non AVX2 machine is detected.

  • When installing macOS Ventura or higher in Qemu and with -cpu host the CPU is passed to the VM and as a result macOS will be installed without the legacy non-AVX2.0 dyld shared caches (as the machine will see that the CPU supports AVX2).

  • Since the -cpu host option is only available in KVM (and KVM is not available in Windows) if after the installation someone needs to emulate -cpu Penryn or -cpe Westmere (in Windows) or any pre Haswell cpu with added options and even added +AVX2 the macOS VM machine will fail to boot due to missing dyld shared cache.

  • To avoid that, before building the machine add the boot argument -crypt_force_avx to the OpenCores config.plist, which will force-install the Rosetta Cryptex even on AVX2.0 systems.

  • Sample batch file:

qemu-system-x86_64.exe ^
-accel whpx,kernel-irqchip=off ^
-machine q35 -cpu Westmere,vendor=GenuineIntel,+pcid,+ssse3,+sse4.2,+popcnt,+avx,+aes,+xsave,+xsaveopt,check ^
-m 4096 -vga std ^
-audiodev dsound,id=snd0 ^
-device ich9-intel-hda ^
-device hda-duplex,audiodev=snd0 ^
-drive file="macos-sonoma\OpenCore.qcow2",index=0,media=disk ^
-drive file="macos-sonoma\disk.qcow2",index=1,media=disk ^
-drive file="macos-sonoma\RecoveryImage.img",index=2,media=disk,format=raw ^
-rtc base=localtime ^
-bios "macos-sonoma\OVMF_combined.fd" ^
-device nec-usb-xhci,id=xhci ^
-device usb-tablet ^
-device usb-kbd ^
-global nec-usb-xhci.msi=off ^
-device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" ^
-smbios type=2 ^
-nodefaults ^
-netdev user,id=net0 ^
-device virtio-net-pci,netdev=net0,id=net0,mac=52:54:00:11:22:33 ^
-device ich9-ahci,id=sata
  • If you need to manipulate the Opencore EFI folder you can mount a premade EFI\EFI\boot\bootx64.efi folder where the bootx64.efi loader is the Opencore's bootx64.efi loader (Reference). Just replace the line:
-drive file="macos-sonoma\OpenCore.qcow2",index=0,media=disk ^

with:

-drive file=fat:rw:"macos-sonoma\EFI",format=raw,file.label=EFI ^

Where the Opencore EFI folder resides in the macos-sonoma\EFI folder forming this structure macos-sonoma\EFI\EFI\boot\bootx64.efi.

  • Kernel arguments for Iris passtrough:
quiet                                                         Print less during kernel boot
intel_iommu=on                                                Enable Intel VT-d
iommu=pt                                                      Skip devices incompatible with passthrough (Only needed if you experience problems without this. Typically with iGPUs)
initcall_blacklist=sysfb_init                                 Prevent sysfb.c from calling its sysfb_init function (no framebuffers)
nofb                                                          Recognized by *some* drivers in the kernel tree to skip framebuffer allocation. Not needed with the above sysfb_init blacklist
video=vesafb:off                                              Inform vesa driver to skip framebuffer work (Maybe not needed with above sysfb_init blacklist)
video=efifb:off                                               Inform efifb platform driver to skip framebuffer work (Maybe not needed with above sysfb_init blacklist)
vfio-pci.ids=8086:46a6                                        OP telling vfio-pci to immediately bind to their 'Alder Lake-P Integrated Graphics Controller' before any other driver has the opportunity.
disable_vga=1                                                 Understood by the vfio-pci driver which makes it try to skip vga arbitration explained more here https://www.kernel.org/doc/html/v4.12/gpu/vgaarbiter.html
modprobe.blacklist=i915,snd_hda_intel,snd_hda_codec_hdmi      Instruct modprobe to skip loading these modules on encounter
vfio_iommu_type1.allow_unsafe_interrupts=1                    For systems which don't support interrupt remapping, tell the vfio_iommu_type1 to quietly ignore them
kvm.ignore_msrs=1                                             Tell KVM driver to ignore unknown KVM-specific MSRs from windows guests. Typically only needed for host cpu passthrough on specific rack server architecture. Not typically PCs.
  • Qemu arguments:
qemu-system-x86_64 # Run QEMU
 -machine pc                                       Qemu 7.2.1 alises this to "pc-i440fx-7.2". Acceptable.
 -m 12G                                            Give the guest 12GB of external memory
 -accel kvm                                        Enable KVM acceleration for the guest's CPU operations. The KVM driver is the powerhouse of Linux virtualization performance turning it into a Type1 bare-metal grade hypervisor
 -cpu host,hv-passthrough,hv-enforce-cpuid         Gives the guest a processor with identical host features
                                                   hv-passthrough   also enables all supported hyper-v flags
                                                   hv-enforce-cpuid forces the guest to only use enlightenments exposed by the CPUID given. KVM allows guests to use all of them by default.

 -device vfio-pci-igd-lpc-bridge,id=vfio-pci-igd-lpc-bridge0,bus=pci.0,addr=1f.0                                         Allocate a virtual IGD/LPC bridge device for OPs iGPU to sit under to help make the magic happen
 -device vfio-pci,host=00:02.0,x-igd-gms=4,id=hostdev0,bus=pci.0,addr=0x2,x-igd-opregion=on,romfile=vbios_gvt_uefi.rom   OP passing through the actual iGPU with a rom dump for the guest to execute at boot time.
                                                                                                                         x-igd-opregion is an experimental feature to enable Opregion support for external monitors on these iGPUs
                                                                                                                         x-igd-gms is used to set the memory size for this device
                                                                                                                         Rom dumps are sometimes needed to initialize a PCI device properly if it scrambles its rom on host boot. (Can also sometimes be revived with a host suspend/sleep, resetting the card)
 -drive if=pflash,format=raw,readonly=on,file=$PWD/OVMF_CODE.fd         This is the TianoCore UEFI bios image to be executed on x86_64 VMs as their bios.
 -drive if=pflash,format=raw,file=$PWD/OVMF_VARS.fd                     This the persistent storage file (appropriately padded out) for the above UEFI bios to save its variables in. The OS may also store permanent key data in here and modify things such as boot orders and boot-relevant encryption keys.

 -nodefaults                       Tells qemu to not give the guest any default hardware which it would normally give. E.g. virtual VGA adapters, video cards, CD drives, serial and others it would normally start with
 -nographic                        Prevents qemu from spawning a graphical window for quest video and serial access. CLI-only approach.
 -vga none                         Don't allocate a virtual "VGA compatible" video card to the guest. Redundant with -nodefaults
 -display none                     Don't use a display at all, redundant with -nodefaults and -nographic unless you want to use curses or some other text-driven display method.
  • Launch command:
qemu-system-x86_64 -machine pc -m 12G -accel kvm -cpu host,hv-passthrough,hv-enforce-cpuid -device vfio-pci-igd-lpc-bridge,id=vfio-pci-igd-lpc-bridge0,bus=pci.0,addr=1f.0 -device vfio-pci,host=00:02.0,x-igd-gms=4,id=hostdev0,bus=pci.0,addr=0x2,x-igd-opregion=on,romfile=vbios_gvt_uefi.rom -drive if=pflash,format=raw,readonly=on,file=$PWD/OVMF_CODE.fd -drive if=pflash,format=raw,file=$PWD/OVMF_VARS.fd -nodefaults -nographic -vga none -display none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment