From Segfault
Jump to navigation Jump to search


With kholia/OSX-KVM it appears to be possible to install macOS as a libvirt virtual machine. The installation was pretty straightforward. In the first step, it recommends to disable[1] to disable the CPU's MSRs:

echo 1 | sudo tee /sys/module/kvm/parameters/ignore_msrs                          # May not be needed at all!

Install some prerequisites:

sudo apt-get install qemu virt-manager dmg2img git wget libguestfs-tools   uml-utilities
sudo dnf install qemu-kvm virt-manager dmg2img git wget libguestfs-tools-c uml_utilities

Clone & use the repository:

git clone osx-kvm-git && cd osx-kvm-git

Once the image has been downloaded, convert it via:

dmg2img -v BaseSystem.dmg BaseSystem.img

The same can be done with a recent version of qemu-img:

qemu-img convert BaseSystem.dmg -O raw BaseSystem.img

Copy the installation scripts and some additional files into our virtual machine location:

mkdir /opt/vm/macos0
cp -p OVMF_CODE.fd OVMF_VARS-1024x768.fd Mojave/CloverNG.qcow2 macOS-libvirt-NG.xml /opt/vm/macos0

These files are needed for: The installation script, to be modified
OVMF_CODE.fd Open Virtual Machine Firmware
OVMF_VARS-1024x768.fd OVMF variable store[2]
Mojave/CloverNG.qcow2 Clover EFI bootloader
macOS-libvirt-NG.xml macOS libvirt XML configuration

Create an (empty) system disk:

cd /opt/vm/macos0
qemu-img create -f qcow2 macos_disk0.qcow2 30G

Adjust as needed:

$ cat
          -drive if=pflash,format=raw,readonly,file=OVMF_CODE.fd \
          -drive id=InstallMedia,if=none,file=BaseSystem.img,format=raw \
          -drive id=Clover,if=none,snapshot=on,format=qcow2,file=CloverNG.qcow2 \
          -drive id=MacHDD,if=none,file=macos_disk0.qcow2,format=qcow2 \

Similarily macOS-libvirt-NG.xml, of course.


For some reason our network configuration presented by Libvirt was not working correctly and we had to flush the DNS cache[3] in our now running macOS image:

sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

But flushing the DNS cache turned out to be insufficient - we also needed to set[4] a valid DNS server:

sudo scutil
> open
> d.init
> d.add ServerAddresses *
> set State:/Network/Service/<SERVICE_ID>/DNS
> quit

The important part was the <SERVICE_ID>, a seemingly randomly generated string:

$ echo list | scutil | grep DHCP$
 subKey [59] = State:/Network/Service/1234A123-ABC1-2345-DEF2-123ABCDEFGHIJK/DHCP

As the installation would not continue without a working network connection, we really needed to (temporarily) get DNS working here. For that we put a small script on a nearby web server containing the following:

S=$(echo list | scutil | awk '/Service.*DHCP/ {print $NF}' | sed 's/DHCP/DNS/')

while true; do

echo "open
d.add ServerAddresses *
set ${S}" | scutil

sleep 10

After booting the installation, execute a Terminal and download the script with curl (use the web server's IP address since we don't have DNS yet) and let it run in the background, preferably with nohup. It will adjust the system's DNS configuration with the name servers set above and with that the installation should continue.