Installing Mac OS on KVM

Background

I first tried to install Mac OS onto a VM back in 2010 or 2011 I think. I’ve come back to the task from time to time and have never been successful, but truthfully until recently all the virtual machines I’ve created on Cinnamon had been too slow to be useful anyway. Now that I have Cinnamon doing virtual machines well, I came back to the Mac – at the same time I was doing other VMs, and I didn’t keep careful track of what I did to get it up. This document is meant to record what I remember of what I did the first time, and then to do it again and keep better records.

First Install: High Sierra

My friend MRF sent me a link to this guy: https://github.com/kholia/OSX-KVM. I cloned his repo to cinnamon. Then used his ./fetch-macOS.py script to download the BaseSystem.dmg file for High Sierra. I then converted BaseSystem.dmg to BaseSystem.img (not sure which tool I used, probably qemu_img). Then I created a disk mac_hdd_ng.img using qemu-img create. All the files are inside the git directory.

Instructions call for creating a tap0 device on the virbr0. I have such a device, so I guess I did that.

Then instructions offer two options for converting the input xml to a runnable system:

1) run the ./boot-macOS-HS.sh script; or

2) use macOS-libvirt xml files, with virsh or virtmanager, after editing for file paths.

I think I did the latter.

Fixing the screen resolution

After I had gotten it up (and this was weeks later) I wanted to change the resolution on the screen and make it bigger. I read a page on the guy’s github page which talks about how.

  1. while within the vm, you first have to mount the EFI partition. If not visible use diskutil list to get the physical name of the disk, e.g. disk0s1. Then do sudo diskutil mount disk0s1. Could be more than one EFI – have to find the one which has the folder CLOVER in it.
  2. open the EFI volume, open CLOVER, find config.plist, edit with textedit. Find ScreenResolution and modify it. I originally chose 1920×1200, but that was a mistake. I ended up finally with 1920×1080 – but see below: be careful.
  3. The next step is supposed to be to reboot, catch the startup of clover with ESC, and modify the resolution in a parameter screen. However, that parameter screen MAY NOT HAVE the resolution you chose above – and now you are screwed, because you cannot get back to it, because you need to boot into the VM and the VM has a resolution specified which is unavailable. CATCH 22. I had chosen a resolution of 1920×1200, because I had another VM using that resolution and it was a good fit. But when I booted and got into the parameter screen, that resolution wasn’t available.
  4. I noticed that the parameter screen said something about the list of available resolutions being filtered by the amount of video ram. So I figured out how to change the xml for the VM to specify more vram (have to enable virtmanager options to allow editing xml, because there was not a vram setting among the offered GUI options in virtmanager), and then on the video virtio device, modify the xml to add after the model type: vram=”131072”. This enabled more resolution options, but still no 1920×1200, which was what I had told the config.plist. If the resolution isn’t right the screen is distorted, unreadable garbage, but I thought my best best was to try to match the HxV ratio, so I chose 1440×900 which is the same 1:1.6 ratio as 1920×1200. Sure enough, although the screen was very odd and still quite distorted, I was able to read it, and operate enough to change the EFI/CLOVER/config.plist and change it to 1920×1080, which I had observed was available in the clover parameter screen.
  5. Then reboot, catch the clover boot with ESC and get the parameter screen, and set it to 1920×1080, save, reboot, and it worked: I have a 1920×1080 resolution.

Second Attempt: Catalina

Next I Decided to do the whole installation again, starting with cloning the repo in case there was anything new, and this time I will go for catalina.

Cloned into OSX-KVM2 on cinnamon.

Cinnamon is on 20.04 focal, and has no “python” any longer (you have to specify), so I changed fetch.py to specify python3.

Chose to download: 19G73 2020-07-15 macOS Catalina

Did:

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

qemu-img create -f qcow2 \
   /virtualdisks/mac_hdd_ng.img 128G

So this time I am putting the img file for the disk into the /virtualdisks directory instead.

I am skipping the setup of tap, as I have done that already.

I edited the file /home/dee/git/OSX-KVM2/macOS-libvirt-Catalina.xml as the instructions said, to change occurrences of CHANGEME/OSX-KVM to dee/git/OSX-KVM2 except I also changed the location of the mac_hdd_ng.img file (the main run time disk) which I had put into /virtualdisks.

Ran the validation and it validates.

Now use virsh to take the xml file and create a specific virtual machine. I’m a little confused by this, but I think that the xml file I have is a template for building machines, and now I am building an actual machine.

After doing this, I couldn’t make virt-manager show the new macOS, and eventually figured out that the xml file has a UUID in it, and the two UUIDs (old macOS high sierra, and new macOS catalina) had the same UUID. Applied horrible kludge of just changing one digit it the new UUID. Restarted libvirtd and it appears.

As a side note, I don’t quite get how this UUID is supposed to work. It seems to be hard coded by the original dev guy whose repo I’m cloning, so it is hardly “universally unique”. It obviously isn’t even unique from one installation to another.

After a lot of messing around, I never managed to get it to work. After a certain period I figured I had modified so many things that I should just start over fresh.

Second try at Catalina

This time I will be following instructions more closely, not doing so much deviation. Note that now I am installing into OSX-KVM3 on my /home/dee/git.

git clone https://github.com/kholia/OSX-KVM.git \ 
    OSX-KVM3
cd OSX-KVM3
<modify fetch.py to use python3>
./fetch.py
select option 9 latest catalina
qemu-img convert BaseSystem.dmg -O raw \ 
    BaseSystem.img
qemu-img create -f qcow2 mac_hdd_ng.img 128G

At this point the current instructions offer an option: either use their boot-macOS-Catalina.sh script, which internally does a call to qemu-system-x86_64 to set up the machine, OR use their provided xml file macOS-libvirt-Catalina.xml, after first changing some strings inside it, and giving that to virsh or virtmanager.

From doing it before, I know that if I use the libvirt-Catalina.xml that it has a hard coded uuid in it, which conflicts with the existing macos VM I have, which is high-sierra.

Furthermore, the boot script method is listed as “primary”, and it points for further information to an earlier readme file where the virsh/virtmanager method appears to be deprecated. Plus, when I had trouble last time, I was using the virsh method, so this time I’m inclined to try the boot-macOS-Catalina.sh script.

On the other hand, as I look at the boot-macOS-Catalina.sh script, which is quite simple, it appears to me that it is going to fail right away: the qemu-system-x86_64 call has a reference to a disk: “-drive if=pflash,format=raw,file=$OVMF/OVMF_VARS-1024×768.fd ” and the variable $OVMF is set to “./backup” and that file OVMF_VARS-1024×768.fd is present, but not in the ./backup directory. So I am going to copy the file into ./backup.

When I ran it, I get the error:

qemu-system-x86_64: warning: host doesn't support \ 
   requested feature: CPUID.01H:ECX.pcid [bit 17]

I compared the scripts “MY_OPTIONS” which are supposed to list cpu options (and which one is invited to tweak if necessary), with the /proc/cpuinfo of my cpu. I found that among the couple of options in the former that were not in the latter, one was “pcid”, so I removed that from MY_OPTIONS, which fixed that problem.

Now I was getting an error that says:

Unable to init server: Could not connect: \
   Connection refused.

I am sure this is probably very easy to fix if one knows a little more, but I wasn’t able to figure out what to do. I was also having issues with whether the tap device should or should not be initialized when the script ran. So eventually, I decided to go back to the other way, and try to define with virsh/virtmanager.

Initially, that didn’t work either. I got it to boot into some early state (similar to what I get with Clover on High Sierra). On this screen it was offering Shutdown, an EFI shell, and Reset NVRAM, but the option to boot into the OS doesn’t seem to be there. I messed around a little with the settings, looking for something that could be wrong.

Among the things I did – which might be important later, has to do with the nvram. There seemed to be two files OVMF_VARS.fd and OVMF_VARS_1024x768.fd. It initially was pointing to the latter, and I changed it to point to the former. That sounds like it has something to do with resolution, and interestingly when I eventually got this up it did not require that I change the screen resolution – it came up in a usable resoltion – looks like 1920×1080 but I’m not sure.

Back to the boot disks: Since I couldn’t figure out what was wrong, I compared the XML to the working XML of the High Sierra one, and the Catalina one didn’t seem to have the BaseSystem.img disk defined. I also compared the “source” xml files, and the BaseSystem.img disk is defined in the High Sierra source xml, but not in the Catalina source xml. So I copied that section of xml into the (target/final) Catalina xml, adjusting the path. Also the boot order seemed wrong, or at least different from the High Sierra xml, and I fixed that too. I didn’t make the changes in the source xml, maybe I should have done.

When it booted, now the loader offered the option to boot into the MacOS base system. When I did it I got the right action – the Apple, the progress bar, all that, but then it went into Recovery, and offered the normal Option-R type options. I chose Reinstall Catalina. But it claimed to have no disk to install on – it said that the macOS Base System disk, which it could see, was “locked”. To be sure that the BaseSystem.img wasn’t corrupt I copied the BaseSystem.dmg to where it was visible by carraway, and opened it, and it opens fine. Then I realized that BaseSystem.img aka BaseSystem.dmg is intended to be “the DVD” – of course it isn’t going to install there. Where is the main disk?

I booted back into it again, and this time, instead of doing the (re-)install, I ran disk utility. I found three disks, figured out that one was the flash, one was the BaseSystem.img which is the “installer disk”, and the third was the big one, which was “uninitialized”, so I told disk utility to erase it, it put a partition table on, formatted it as HFS journaled. Then I exited disk utility and bingo, I could do an install of Catalina on the new disk. Which I did.

Installation took a long time. Then it rebooted. I have Catalina.