Catalina
This guide is based on OSX-KVM checked out at commit bda4cc8e698356510c27747b7a929339f450890c.
NOTE: All commands not run inside the macOS VM are expected to be run while inside the contained
nix-shell
.
Diffs
The upstream OSX-KVM repo is patched to use our own qcow's and OVMF files.
Installation
-
Follow the installation preparation steps from OSX-KVM:
-
Configure KVM to
ignore_msrs
on the host running the VM(s) -- this can be achieved by adding the following configuration (a configuration switch and reboot will be necessary):{ boot.kernelParams = [ "kvm.ignore_msrs=1" # according to OSX-KVM, this is required "kvm.report_ignored_msrs=0" # these ignored msrs are harmless, so don't let them clog up dmesg ]; }
NOTE: To apply these without a reboot, you may
echo 1 > /sys/module/kvm/parameters/ignore_msrs
andecho 0 > /sys/module/kvm/parameters/report_ignored_msrs
(as root). -
Run
./fetch-macOS.py
and select the latest version of Catalina -
Run
qemu-img convert BaseSystem.dmg -O raw BaseSystem.img
-
Run
qemu-img create -f qcow2 mac_hdd_ng.img 128G
-
You may ignore the networking setup; our modified
./boot-macOS-Catalina.sh
script sets up user-mode networking instead
-
-
Run
./boot-macOS-Catalina.sh
and boot from the install disk (may take a while)- You will want a VNC client -- I used tigervnc's
vncviewer
and forwarded the VNC port to my local system withssh -L 5900:localhost:5900 user@remote-machine-running-qemu
thennix-shell -p tigervnc --run "vncviewer 127.0.0.1:5900"
- You will want a VNC client -- I used tigervnc's
-
Select the "English" language
-
Select "Disk Utility"
-
Select the "QEMU HARDDISK Media" disk (around 130GB, "uninitialized")
-
Click "Erase" (in the top middle), set the Name to "system" (exactly; case matters!), Format to "Mac OS Extended (Journaled)", and Scheme to "GUID Partition Map"
-
Click "Erase" and then "Done"
-
Exit Disk Utility by clicking the red exit button at the top left
-
Select "Reinstall macOS" and click "Continue"
-
Click "Continue"
-
Click "Agree" and click "Agree" in the dialog that pops up
-
Select the "system" disk and click "Install"
- This will take a bit of time (roughly 30 minutes, but may be more or less)
-
Once the install process gets to the "Welcome" screen where you select a physical location, Ctrl-C the QEMU process and copy the disk image (
mac_hdd_ng.img
) to another location for safe keeping. This duplicated image will be used for future fresh re-setting-up like major upgrades. -
Restart the VM with
./boot-macOS-Catalina.sh
and reconnect to VNC- Wait 3 seconds for macOS to automatically boot
-
Select "United States" and click "Continue"
-
Click "Continue" on the "Written and Spoken Languages" page
-
Click "Continue" on the "Data & Privacy" page
-
Select "Don't transfer any information now" (if it isn't already) and click "Continue" on the "Transfer Information to This Mac" page
-
Click "Set Up Later" on the "Sign In with Your Apple ID" page
- Confirm by clicking "Skip" on the dialog that pops up
-
Click "Agree" on the "Terms and Conditions" page
- Confirm by clicking "Agree" on the dialog that pops up
-
Create a user:
- Full name:
nixos
- Account name:
nixos
- Password: generate a new one each time, note: nixos is not a good password =)
- NOTE: You will need to remember this
- Hint: leave blank for no hint
- Full name:
-
Click "Customize Settings" on the "Express Set Up" page
-
Ensure the box next to "Enable Location Services on this Mac" is unticked (disabled) on the "Enable Location Services" page
- Confirm by clicking "Don't Use" on the dialog that pops up
-
Select your timezone: "UTC - United Kingdom" and click "Continue"
-
Ensure both boxes on the "Analytics" page are not ticked ("Share Mac Analytics with Apple" was enabled by default -- untick that)
-
Click "Set Up Later" on the "Screen Time" page
-
Ensure the box next to "Enable Ask Siri" on the "Siri" page is not ticked and click "Continue"
-
Click "Continue" on the "Choose Your Look" page
-
You'll reach the desktop where macOS will try to configure the keyboard; click "Continue", press
z
and then/
, make sureANSI
is selected, and click "Done" -
Set up Full Disk Access for the terminal:
- Click the magnifying glass in the top bar (top right corner), search for "term", and press Enter on "Terminal"
- Close the "Terminal" window
- Click the Apple icon (top left)
- Select "System Preferences" from the drop down
- Click on "Security & Privacy"
- Select the "Privacy" tab
- Scroll down to "Full Disk Access" and select it
- Click the lock icon on the bottom left, enter the password you set earlier, and click "Unlock" (or hit enter) to confirm
- Click the "+" icon
- In the window that opens up, search for "terminal" (search box is top right) and select "Name matches: terminal"
- Then select the "Terminal" application under the "Today" header
- NOTE: To ensure this is the right "Terminal" make sure the path displayed on the bottom of the window starts with "system" (the Name we defined when erasing the disk earlier) and not "macOS Base System"
- Close that window by clicking the red close button on the top left
-
Open the "Terminal" again by clicking the magnifying glass in the top bar (top right corner), searching for "term", and pressing Enter on "Terminal"
-
Run
sudo systemsetup -setremotelogin on
to turn on SSH.- IMPORTANT: DO NOT TEST SSH AT THIS STAGE! Testing SSH now would cause the image to generate an SSH host key, and cause it to be fixed in a generic disk image too soon.
-
Disable the protections preventing you from running unsigned software:
sudo spctl --master-disable
-
Disable sleep:
sudo systemsetup -setcomputersleep Never
-
Enable automatically mounting ISOs, even before users log in:
sudo defaults write /Library/Preferences/SystemConfiguration/autodiskmount AutomountDisksWithoutUserLogin -bool YES
-
Bypass new Catalina protections that prevent autorunning scripts from
/Volumes
:sudo ln -s /Volumes/CONFIG/apply.sh ~root/apply.sh
-
Create an autorun script by writing the following contents to
/Library/LaunchDaemons/org.nixos.bootup.plist
:- You can curl the GitHub shortlink https://git.io/JtyI9 (which points to https://gist.githubusercontent.com/grahamc/126b1a28d50d99db315fb5b6fce551c7/raw/db5a95ca6b3002e3518fb5817437b4314e6f4085/catalina-----%2520org.nixos.bootup.plist) to prevent having to type this mess
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.nixos.bootup</string>
<key>ProgramArguments</key>
<array>
<string>bash</string>
<string>/var/root/apply.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartOnMount</key>
<true/>
</dict>
</plist>
- Close the terminal and select "Shut Down" from the Apple menu
- Deselect "Reopen windows when logging back in" and click "Shut Down"
- Duplicate
mac_hdd_ng.img
once more, tomac_hdd_ng.configured.img
This image is used as the basis for hydra and ofborg builders.
Notes
- To generate a
config.iso
for use with the VM:
cd cdrom
ssh-keygen -A -f . # to generate host keys that will be used in the VM
genisoimage -v -J -r -V CONFIG -o ../OSX-KVM/config.iso .
-
To watch the logs generated by a VM (where the
LOGHOST
variable inapply.sh
was properly configured), runnc -dklun 1514 | tr '<' $'\n'
(from anix-shell
using the providedshell.nix
) on theLOGHOST
.- NOTE: You'll need to open port 1514 for UDP. To do so temporarily (on NixOS), you may use the following command:
iptables -w -I nixos-fw -p udp --dport 1514 -j nixos-fw-accept
.
- NOTE: You'll need to open port 1514 for UDP. To do so temporarily (on NixOS), you may use the following command:
-
If you run into issues with QEMU and macOS not playing nice, you may need to use a new templated config,
config.plist.qemu.templated
:
config.plist.qemu.templated
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ACPI</key>
<dict>
<key>DSDT</key>
<dict>
<key>Debug</key>
<false/>
<key>DropOEM_DSM</key>
<true/>
<key>Fixes</key>
<dict>
<key>AddDTGP</key>
<true/>
<key>AddMCHC</key>
<false/>
<key>AddPNLF</key>
<false/>
<key>DeleteUnused</key>
<false/>
<key>FakeLPC</key>
<false/>
<key>FixACST</key>
<false/>
<key>FixADP1</key>
<false/>
<key>FixDarwin</key>
<false/>
<key>FixHDA</key>
<false/>
<key>FixHPET</key>
<false/>
<key>FixIPIC</key>
<false/>
<key>FixLAN</key>
<false/>
<key>FixRTC</key>
<false/>
<key>FixRegions</key>
<true/>
<key>FixS3D</key>
<false/>
<key>FixSATA</key>
<false/>
<key>FixUSB</key>
<false/>
</dict>
<key>Name</key>
<string>i440fx-acpi-dsdt.aml</string>
<key>ReuseFFFF</key>
<false/>
<key>Rtc8Allowed</key>
<false/>
</dict>
<key>DisableASPM</key>
<true/>
<key>PatchAPIC</key>
<true/>
<key>SSDT</key>
<dict>
<key>DropOem</key>
<true/>
<key>Generate</key>
<dict>
<key>APLF</key>
<false/>
<key>APSN</key>
<false/>
<key>CStates</key>
<false/>
<key>PStates</key>
<false/>
<key>PluginType</key>
<false/>
</dict>
<key>NoDynamicExtract</key>
<false/>
<key>NoOemTableId</key>
<true/>
<key>UseSystemIO</key>
<true/>
</dict>
</dict>
<key>Boot</key>
<dict>
<key>Arguments</key>
<string>@params@</string>
<string>Apple</string>
<key>Debug</key>
<key>DefaultVolume</key>
<string>system</string>
<key>HibernationFixup</key>
<false/>
<key>Legacy</key>
<string>PBR</string>
<key>Log</key>
<true/>
<key>Secure</key>
<false/>
<key>Timeout</key>
<integer>@timeout@</integer>
</dict>
<key>GUI</key>
<dict>
<key>Scan</key>
<dict>
<key>Entries</key>
<true/>
<key>Tool</key>
<true/>
</dict>
<key>ScreenResolution</key>
<string>@resolution@</string>
<key>Theme</key>
<string>embedded</string>
</dict>
<key>Graphics</key>
<dict>
<key>Inject</key>
<dict>
<key>ATI</key>
<false/>
<key>Intel</key>
<false/>
<key>NVidia</key>
<false/>
</dict>
<key>NvidiaSingle</key>
<false/>
</dict>
<key>KernelAndKextPatches</key>
<dict>
<key>AppleIntelCPUPM</key>
<true/>
<key>AppleRTC</key>
<true/>
<key>Debug</key>
<false/>
<key>KernelCpu</key>
<true/>
<key>KernelLapic</key>
<true/>
<key>KernelPm</key>
<true/>
<key>KernelXCPM</key>
<false/>
</dict>
<key>RtVariables</key>
<dict>
<key>BooterConfig</key>
<string>0x28</string>
<key>CsrActiveConfig</key>
<string>@csrFlag@</string>
<key>ROM</key>
<data>
xDCPKu+o
</data>
</dict>
<key>SMBIOS</key>
<dict>
<key>BiosReleaseDate</key>
<string>06/26/2018</string>
<key>BiosVendor</key>
<string>Apple Inc.</string>
<key>BiosVersion</key>
<string>IM183.88Z.0161.B00.1806260901</string>
<key>Board-ID</key>
<string>Mac-BE088AF8C5EB4FA2</string>
<key>BoardManufacturer</key>
<string>Apple Inc.</string>
<key>BoardSerialNumber</key>
<string>C02736902GUDJWM8C</string>
<key>BoardType</key>
<integer>10</integer>
<key>BoardVersion</key>
<string>1.0</string>
<key>ChassisAssetTag</key>
<string>iMac-Aluminum</string>
<key>ChassisManufacturer</key>
<string>Apple Inc.</string>
<key>ChassisType</key>
<string>0x09</string>
<key>Family</key>
<string>iMac</string>
<key>FirmwareFeatures</key>
<string>0xFC0FE137</string>
<key>FirmwareFeaturesMask</key>
<string>0xFF1FFF3F</string>
<key>LocationInChassis</key>
<string>Part Component</string>
<key>Manufacturer</key>
<string>Apple Inc.</string>
<key>Mobile</key>
<false/>
<key>PlatformFeature</key>
<string>0x00</string>
<key>ProductName</key>
<string>iMac18,3</string>
<key>SerialNumber</key>
<string>C02VCVICJ1GJ</string>
<key>Version</key>
<string>1.0</string>
</dict>
<key>SystemParameters</key>
<dict>
<key>CustomUUID</key>
<string>3AF3E5AC-42B1-5FE1-A965-AC7D442AEFA8</string>
<key>InjectKexts</key>
<string>Yes</string>
<key>InjectSystemID</key>
<true/>
</dict>
</dict>
</plist>