Running Mac OS X as a QEMU/KVM Guest
Gabriel L. Somlo
See the old version of this page
here.
FINAL UPDATE (2018-10-21):
I no longer have the cycles to work on this project. At this point QEMU and KVM are mostly capable of supporting OS X (up to Sierra), and the largest portion of the effort still required lies with edk2/ovmf (start with my fork on github as indicated below, and go from there).
Additionally, since Apple machines have become increasingly locked down and end-user unfriendly, I can't continue considering them for any upcoming hardware refresh (which is too bad, they used to make almost perfect Linux machines for the last 20 years!).
NOTE: Installer .iso images prepared based on Sierra 10.12.4 or later will hang during boot. However, guest images installed with 10.12.3 or earlier can successfully be upgraded, assuming the applesmc fix mentioned above is applied. The cause for this is as of yet unknown (to me, at least).
You will need the following:
- Tools: git, gcc[-c++], nasm, [auto]make, iasl, kernel-devel, etc.
- Linux kernel ≥ 4.7
- QEMU ≥ 2.6.0
- Patched OVMF firmware, built from source
I currently use Fedora 26. Anything close to it in terms of "freshness" should likely do just fine.
To build the patched OVMF firmware blob, follow these instructions:
git clone https://github.com/gsomlo/edk2.git
cd edk2
git checkout gls-miscopt
make -C BaseTools
. edksetup.sh BaseTools
build -a X64 -t GCC5 -p OvmfPkg/OvmfPkgX64.dsc
cp $(find ./Build/ -name OVMF.fd) ~/
The result of this process is a firmware blob named OVMF.fd, which will be copied to your home directory by the last command shown above. A
binary OVMF blob built by applying my patches on top of the current edk2 master branch (as indicated by the abbreviated commit ID in the file name) is available to help speed things up, but you're strongly encouraged to build your own :)
SnowLeopard (10.6) was the last OS X version released in DVD format. Starting with Lion (10.7), an install DVD (.iso) image may be generated on an OS X machine by following the steps below (Thanks Dick Marinus for pointing out the Yosemite-specific updates!):
# As of Yosemite, this really only works if executed as root,
# so let's start with that:
sudo -s
# Mount the installer image:
hdiutil attach /Applications/Install\ OS\ X\ Yosemite.app/Contents/SharedSupport/InstallESD.dmg -noverify -nobrowse -mountpoint /Volumes/install_app
# Convert the boot image to a sparse bundle:
hdiutil convert /Volumes/install_app/BaseSystem.dmg -format UDSP -o /tmp/Yosemite
# Increase the sparse bundle capacity for packages, kernel, etc.:
hdiutil resize -size 8g /tmp/Yosemite.sparseimage
# Mount the sparse bundle target for further processing:
hdiutil attach /tmp/Yosemite.sparseimage -noverify -nobrowse -mountpoint /Volumes/install_build
# Remove Package link and replace with actual files:
rm /Volumes/install_build/System/Installation/Packages
cp -rp /Volumes/install_app/Packages /Volumes/install_build/System/Installation/
# NEW: As of Yosemite, there are additional installer dependencies:
cp -rp /Volumes/install_app/BaseSystem* /Volumes/install_build/
# NEW: As of Yosemite, we also need a kernel image!
# Assuming we're executing these steps on a Yosemite machine with
# a version EXACTLY matching that of the installer we're preparing:
cp -rp /System/Library/Kernels /Volumes/install_build/System/Library/
# NOTE: If the running OS X version is not identical to that of
# the installer being prepared, one may copy the
# necessary files (/System/Library/Kernels/*) from the
# /Volumes/install_app/Packages/Essentials.pkg package,
# using third party software (e.g. Pacifist -- WARNING:
# shareware, not free/open source software, your ideological
# purity may vary).
# Unmount both the installer image and the target sparse bundle:
hdiutil detach /Volumes/install_app
hdiutil detach /Volumes/install_build
# Resize the partition in the sparse bundle to remove any free space:
hdiutil resize -size $(hdiutil resize -limits /tmp/Yosemite.sparseimage | tail -n 1 | awk '{ print $1 }')b /tmp/Yosemite.sparseimage
# Convert the sparse bundle to ISO/CD master:
hdiutil convert /tmp/Yosemite.sparseimage -format UDTO -o /tmp/Yosemite
# Remove the sparse bundle:
rm /tmp/Yosemite.sparseimage
# Rename the ISO and move it to the desktop:
mv /tmp/Yosemite.cdr ~/Desktop/Yosemite.iso
First, create an empty hard drive image:
qemu-img create -f qcow2 mac_hdd.img 64G
Using the following command line, install OS X from the boot media created earlier (Thanks Jim Burns for the Penryn hint, which is needed instead of core2duo as of Sierra):
bin/qemu-system-x86_64 -machine q35,accel=kvm -bios ~/OVMF.fd -m 4096 \
-cpu Penryn -smp 4,cores=2 \
-usb -device usb-kbd -device usb-tablet \
-device isa-applesmc,osk="insert-real-64-char-OSK-here" \
-netdev user,id=usr0 -device e1000-82545em,netdev=usr0,id=vnet0 \
-device ide-drive,bus=ide.0,drive=MacDVD \
-drive id=MacDVD,if=none,snapshot=on,file=~/DVD/Sierra.10.12.1.iso \
-device ide-drive,bus=ide.2,drive=MacHDD \
-drive id=MacHDD,if=none,file=~/mac_hdd.img \
-monitor stdio
In addition to the OVMF.fd firmware blob, the DVD image, and a blank hard drive image, you'll need to provide the value of OSK0 and OSK1, as a single concatenated 64-character string. If you own a Mac and run Linux on it natively (the license-compliant use case for the application of these instructions), you can retrieve them by compiling and running
SmcDumpKey.c.
Finally, to start your freshly installed guest, run:
bin/qemu-system-x86_64 -machine q35,accel=kvm -bios ~/OVMF.fd -m 4096 \
-cpu Penryn -smp 4,cores=2 \
-usb -device usb-kbd -device usb-tablet \
-device isa-applesmc,osk="insert-real-64-char-OSK-here" \
-netdev user,id=usr0 -device e1000-82545em,netdev=usr0,id=vnet0 \
-device ide-drive,bus=ide.2,drive=MacHDD \
-drive id=MacHDD,if=none,file=~/mac_hdd.img \
-monitor stdio
NOTE: If using qemu ≤ 2.8, substitute "-device usb-mouse" instead of "-device usb-tablet". A patch to make the latter work with OS X (thanks to Phil Dennis-Jordan) only became available starting with version 2.9.0.
Let me start with the obligatory disclaimer: I am not a lawyer, and this is not legal advice!
We know that OS X is supported on commercial virtualization solutions such as
VMWare Fusion and
Parallels. Reading through
Apple's EULA (which states that "[...] you are granted a [...] license to install, use and run one (1) copy of the Apple Software on a single Apple-Branded computer at any one time"), it appears everything is OK as long as the underlying hardware is made by Apple.
What if the hypervisor OS is
different than OS X? (both Fusion and Parallels both use OS X as the hypervisor OS). Well, it appears
VMWare ESXi allows running OS X guests (presumably only if the hardware is, once again, manufactured by Apple). This is clearly an example of OS X running as guest on top of a
non-OS X hypervisor, on top of Apple-manufactured hardware.
So, it is my belief that, as long as I'm running a Linux/KVM hypervisor on a genuine Mac computer (which I've personally been doing exclusively since cca. 2006, btw), the license does not forbid me from running OS X as a VM guest on top of it.
In terms of advice, all I can say is: Check with the legal and/or moral authorities in your local jurisdiction before trying this at home! :)
A few things still need work:
- OS X High Sierra (10.13) doesn't boot at this time. No idea yet if (and how) the new Apple filesystem (APFS) plays into this.
- None of QEMU's current audio devices appear to have native OS X driver support
- Screen resolution / resizing doesn't work
- Most importantly, the HFS+ EDK2 patches (and the OS X boot support ones which depend on HFS+) are rather far from being palatable to the upstream EDK2 project. A major refactoring of the HFS+ support is needed first; Then, cleaning up and upstreaming the OS X boot support work originally done by Reza Jelveh would be needed.
- Additional details on https://github.com/gsomlo/edk2 are needed for those interested. The repository contains three branches, stacked on top of each other: On top of the master branch (which tracks upstream, there's gls-hfsplus, containing the HFS+ driver in its current, fsw-based form. On top of that, there's gls-macboot containing Reza's hacks to get OS X to load, which will need to be cleaned up once we have a reliable upstream HFS+ filesystem. Finally, on top of everything, there's gls-miscopt, containing convenient hacks for everyday OSX use (e.g. forcing the default screen size to something a bit more useful). I (re)structured my clone of edk2 this way so that I can easily rebase things on top of upstream, while at the same time being able to bounce between filesystem driver development in gls-hfsplus and using OSX.