Originally I had been trying to get Snow Leopard to work in qemu-kvm, and it kind of does; I had even thought of contributing to that project to make it work even better (e.g. the e1000 emulation does not work under Mac OS X). However, I decided that I simply don’t have the time: I had submitted a patch to their developer list fixing SCSI MMC passthrough, which allows things like clonedvd, or CD burning to work from inside a VM. I never received a response to the final patch (not even a NAK), which discouraged me from spending much more time on it.
Anyway, now, a few months later, I’ve been playing about with VirtualBox. Frankly it just works a lot better; there’s a nice management GUI, 2d/3d acceleration, nice modular source code, command line management tools, and you can easily host VMs on a remote machine and manage them using the excellent phpvirtualbox if you want. I’ve converted all my VMs to it and zapped qemu-kvm completely.
Interestingly, it also supports Snow Leopard (mostly) out of the box without any faffing about with bootloaders. I had followed these instructions, but I ran into various problems:
CPU Incompatability
I installed it on an older Core 2 Quad based machine, and the installation worked perfectly fine. However when I tried it on my Core i5 laptop, the infamous AppleIntelCPUPowerManagement kext told me I had an "Unsupported CPU". So I need to kill that prior to the install.
I needed to modify the snow leopard installation ISO prior to installation. Apple’s installation media are slightly odd: they have a normal ISO9660 filing system, which contains various drivers for windows. However, they also have a legacy "Apple Partition Map" partition table which has the actual installation filing system on it. Assuming you can mount it under linux, this makes it dead easy to customise as it is a full read/write filing system, unlike ISO9660.
I’ll want to loopback a specific partition from the image, which tends to be tricky under linux. However I recently found a useful tool, "kpartx" in the multipath-tools suite. It uses the linux device mapper to create devices for each partition in an image, which you can then mount normally.
It goes like this (as root of course):
modprobe dm_mod LDEV=`losetup -f -v snowimage.iso | sed "s/Loop device is //"` kpartx -av $LDEV
This should create a number of new entries in /dev/mapper of the form "loopXpY", where X is the number of the /dev/loop device created by losetup above, and Y is the partition number. We want partition 3, and we can now mount it with:
modprobe hfsplus mkdir /tmp/snowmnt mount /dev/mapper/loop0p3 /tmp/snowmnt
You can now simply remove the kext with:
rm -fr /tmp/snowmnt/System/Library/Extensions/AppleIntelCPUPowerManagement.kext
And finally, unmount the image:
umount /tmp/snowmnt kpartx -d snowimage.iso losetup -d snowimage.iso
After this, you should be able to do a normal install on even modern CPUs.
Oh, once you’ve installed it, it will, of course, have installed a new copy of AppleIntelCPUPowerManagement.kext on your local disk; just boot up off the install DVD again, and use the Terminal app to:
rm -fr /System/Library/Extensions/AppleIntelCPUPowerManagement.kext
and reboot.
100% CPU Use on older CPUs
If you’re installing on an older CPU, and didn’t need to remove AppleIntelCPUPowerManagement.kext, I found the VM used 100% CPU all the time. This is apparently well known, is due to the VM not implementing the hardware that kext requires, so it sits in a tight loop spewing errors. I’d recommend just:
rm -fr /System/Library/Extensions/AppleIntelCPUPowerManagement.kext
as root from an existing Mac OS X installation, and reboot.
Upgrading kills the installation
So, once I had it all installed, I naturally wanted to upgrade it to the latest point release. I duly downloaded it, and set it installing. It seemed to work, but right at the end, somewhere during the "Moving files into place" stage, Mac OS crashed, with a "You must press reset on your machine" message. After that, the image was completely screwed and will not boot.
So, one reinstall from scratch later, I took a snapshot of the VM (yet another feature of virtualbox which is much easier than qemu). Interestingly, I remembered I had tried this on the older machine, with AppleIntelCPUPowerManagement.kext still in place, and it worked fine. During the upgrade, a new version of that kext is installed. I wondered if Mac OS X was then immediately loading it, which would then kill the machine.
So, I downloaded a copy of the NullCpuPowerManagement.kext from here. This is designed to override AppleIntelCPUPowerManagement.kext, and just do nothing at all. I installed it into /System/Library/Extensions as normal, and rebooted. I checked it was definitely being loaded by running:
ioreg | grep Power
under Mac Os X and I could see it was. I started the installation again, and this time it worked perfectly right to the end!
However, after a reboot, it failed at AppleIntelCPUPowerManagement.kext again. Obviously NullCpuPowerManagement.kext can prevent any new power management kexts being loaded, but if both it and the original are there, mac os x will choose the original. Not a problem really; I simply reset the VM and booted it back up off the snow leopard DVD and deleted AppleIntelCPUPowerManagement.kext again using the Terminal. Rebooted, and its working perfectly at 10.6.6.
It is slightly annoying I still have to modify the image slightly, but at least you can do it with an absolute minimum of changes.
UPDATE: On a hunch, I wondered if perhaps Mac OS X enumerates the drivers in /System/Library/Extensions in alphabetical order (AppleIntelCPU…. is before NullCPU…. obviously). So I restored AppleIntelCPUPowerManagement.kext and renamed NullCPUPowerManagement.kext to be before it with:
cd /System/Library/Extensions mv NullCPUPowerManagement.kext AAANullCPUPowerManagement.kext
And rebooted. Guess what, it works!