From 63b9cc496a5d1a1094a710f38694e15076edc1bf Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Sat, 5 Apr 2025 11:05:46 +0100 Subject: [PATCH 1/4] Enable TRIM support for the macOS hard drive image. We need to tell macOS the emulated drive is an SSD *and* run `trimforce enable` in the guest because we can't emulate a specific (i.e. Apple-approved) drive. --- OpenCore-Boot.sh | 2 +- README.md | 2 ++ macOS-libvirt-Catalina.xml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/OpenCore-Boot.sh b/OpenCore-Boot.sh index e027851..08688fc 100755 --- a/OpenCore-Boot.sh +++ b/OpenCore-Boot.sh @@ -57,7 +57,7 @@ args=( -device ide-hd,bus=sata.3,drive=InstallMedia -drive id=InstallMedia,if=none,file="$REPO_PATH/BaseSystem.img",format=raw -drive id=MacHDD,if=none,file="$REPO_PATH/mac_hdd_ng.img",format=qcow2 - -device ide-hd,bus=sata.4,drive=MacHDD + -device ide-hd,bus=sata.4,drive=MacHDD,rotation_rate=1 # -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device virtio-net-pci,netdev=net0,id=net0,mac=52:54:00:c9:18:27 -netdev user,id=net0,hostfwd=tcp::2222-:22 -device virtio-net-pci,netdev=net0,id=net0,mac=52:54:00:c9:18:27 # -netdev user,id=net0 -device vmxnet3,netdev=net0,id=net0,mac=52:54:00:c9:18:27 # Note: Use this line for High Sierra diff --git a/README.md b/README.md index a7225bf..474ced2 100644 --- a/README.md +++ b/README.md @@ -235,6 +235,8 @@ work, patience, and a bit of luck (perhaps?). ### Post-Installation +* Run `sudo trimforce enable` to enable TRIM support on the macOS hard drive. + * See [networking notes](networking-qemu-kvm-howto.txt) on how to setup networking in your VM, outbound and also inbound for remote access to your VM via SSH, VNC, etc. * To passthrough GPUs and other devices, see [these notes](notes.md#gpu-passthrough-notes). diff --git a/macOS-libvirt-Catalina.xml b/macOS-libvirt-Catalina.xml index 05cb13f..d91657d 100644 --- a/macOS-libvirt-Catalina.xml +++ b/macOS-libvirt-Catalina.xml @@ -70,7 +70,7 @@ - +
From 9d3deb0222b778d2c91da47673322579b300b629 Mon Sep 17 00:00:00 2001 From: James Cuzella Date: Mon, 5 May 2025 20:54:48 -0600 Subject: [PATCH 2/4] Prevent qcow2 image ballooning with discard=unmap,detect-zeroes=unmap To prevent the `qcow2` image file from inevitably ballooning or expanding on the host, we need to tell qcow2 image format block driver to unmap on discard/TRIM. Due to how `qcow2` sparse images integrate with SSD TRIM (a.k.a. "`discard`"), we also must set `discard=unmap`, and `detect-zeroes=unmap`. However, these parameters are usually specified on the block device, so we must fallback to the more declarative `-blockdev ...` + `-device ...` form of QEMU CLI args to specify them [^1]. For example: ```console # need to specify 'discard=unmap, detect-zeroes=unmap' on blockdev -blockdev driver=qcow2,node-name=MacHDD,file.driver=file,file.filename="$REPO_PATH/mac_hdd_ng.img",file.aio=threads,discard=unmap,detect-zeroes=unmap -device ide-hd,bus=sata.4,drive=MacHDD,id=macssd,rotation_rate=1 ``` [^1]: See: [_QEMU User Documentation: Block device options_][1] or `man qemu` "_Block device options_" section: > The most explicit way to describe disks is to use a combination of > `-device` to specify the hardware device and `-blockdev` to describe the > backend. The device defines what the guest sees and the backend describes how > QEMU handles the data. _**It is the only guaranteed stable interface for > describing block devices and as such is recommended for management tools and scripting**_. > The `-drive` option combines the device and backend into a single command line > option which is a more human friendly. There is however > _no interface stability guarantee_ although some older board models still need > updating to work with the modern `blockdev` forms. Signed-off-by: James Cuzella Suggested-by: Daniel Collins --- OVMF_VARS-1920x1080.fd | Bin 131072 -> 131072 bytes OpenCore-Boot.sh | 12 ++++++++---- macOS-libvirt-Catalina.xml | 6 +++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/OVMF_VARS-1920x1080.fd b/OVMF_VARS-1920x1080.fd index 3b8bb9b61b0278fa5ac258b1a5b4460d1f681d16..d6de773a18e61ffc7527bff629c2acf0b854c028 100644 GIT binary patch literal 131072 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 TfC3bt00k&O0SZvy%P8<)RLgXn delta 31 gcmZo@;Am*zn2@sB(P{tM%>hn#9VdNIfN>O)0N-~G761SM diff --git a/OpenCore-Boot.sh b/OpenCore-Boot.sh index 08688fc..3764707 100755 --- a/OpenCore-Boot.sh +++ b/OpenCore-Boot.sh @@ -52,12 +52,16 @@ args=( -smbios type=2 -device ich9-intel-hda -device hda-duplex -device ich9-ahci,id=sata - -drive id=OpenCoreBoot,if=none,snapshot=on,format=qcow2,file="$REPO_PATH/OpenCore/OpenCore.qcow2" - -device ide-hd,bus=sata.2,drive=OpenCoreBoot + # Setup SSD trim support to keep qcow2 image sparse + -blockdev driver=qcow2,node-name=OpenCoreBoot,file.filename="$REPO_PATH/OpenCore/OpenCore.qcow2",file.aio=threads,file.driver=file,discard=unmap,detect-zeroes=unmap + -device ide-hd,bus=sata.2,drive=OpenCoreBoot,id=oc + -set device.oc.rotation_rate=1 -device ide-hd,bus=sata.3,drive=InstallMedia -drive id=InstallMedia,if=none,file="$REPO_PATH/BaseSystem.img",format=raw - -drive id=MacHDD,if=none,file="$REPO_PATH/mac_hdd_ng.img",format=qcow2 - -device ide-hd,bus=sata.4,drive=MacHDD,rotation_rate=1 + # Again, setup SSD trim so macOS disk qcow2 image remains sparse + -blockdev driver=qcow2,node-name=MacHDD,file.driver=file,file.filename="$REPO_PATH/mac_hdd_ng.img",file.aio=threads,discard=unmap,detect-zeroes=unmap + -device ide-hd,bus=sata.4,drive=MacHDD,id=macssd + -set device.macssd.rotation_rate=1 # -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device virtio-net-pci,netdev=net0,id=net0,mac=52:54:00:c9:18:27 -netdev user,id=net0,hostfwd=tcp::2222-:22 -device virtio-net-pci,netdev=net0,id=net0,mac=52:54:00:c9:18:27 # -netdev user,id=net0 -device vmxnet3,netdev=net0,id=net0,mac=52:54:00:c9:18:27 # Note: Use this line for High Sierra diff --git a/macOS-libvirt-Catalina.xml b/macOS-libvirt-Catalina.xml index d91657d..612c44b 100644 --- a/macOS-libvirt-Catalina.xml +++ b/macOS-libvirt-Catalina.xml @@ -61,14 +61,14 @@ /usr/bin/qemu-system-x86_64 - + - +
- + From beff6eb1d33ac88f301e8c08fc50c4b69e670614 Mon Sep 17 00:00:00 2001 From: James Cuzella Date: Tue, 6 May 2025 02:07:08 -0600 Subject: [PATCH 3/4] Document qcow2 + macOS SSD TRIM support further Signed-off-by: James Cuzella --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 474ced2..6488ddf 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,11 @@ processors work just fine (even for macOS Sonoma). qemu-img create -f qcow2 mac_hdd_ng.img 256G ``` - NOTE: Create this HDD image file on a fast SSD/NVMe disk for best results. +> [!NOTE] +> Create this HDD image file on a fast SSD/NVMe disk for best results. +> +> To enable TRIM support inside macOS, you must run: `sudo trimforce enable` from +> _inside the VM_ after it boots. * Now you are ready to install macOS 🚀 @@ -236,6 +240,10 @@ work, patience, and a bit of luck (perhaps?). ### Post-Installation * Run `sudo trimforce enable` to enable TRIM support on the macOS hard drive. + - NOTE: This is important so the `qcow2` image remains sparse, and does not + keep growing in size, even after deleting files to free space in the VM. + - This is supported by QEMU's `qcow2` image format block driver through the + `discard=unmap,detect-zeroes=unmap` parameters. * See [networking notes](networking-qemu-kvm-howto.txt) on how to setup networking in your VM, outbound and also inbound for remote access to your VM via SSH, VNC, etc. From 48992a435a8c97cbf24c676a17cf5fb835b5396c Mon Sep 17 00:00:00 2001 From: James Cuzella Date: Tue, 6 May 2025 05:32:41 -0600 Subject: [PATCH 4/4] Consolidate rotation_rate=1 into device args Signed-off-by: James Cuzella --- OpenCore-Boot.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/OpenCore-Boot.sh b/OpenCore-Boot.sh index 3764707..d3d0190 100755 --- a/OpenCore-Boot.sh +++ b/OpenCore-Boot.sh @@ -54,14 +54,12 @@ args=( -device ich9-ahci,id=sata # Setup SSD trim support to keep qcow2 image sparse -blockdev driver=qcow2,node-name=OpenCoreBoot,file.filename="$REPO_PATH/OpenCore/OpenCore.qcow2",file.aio=threads,file.driver=file,discard=unmap,detect-zeroes=unmap - -device ide-hd,bus=sata.2,drive=OpenCoreBoot,id=oc - -set device.oc.rotation_rate=1 + -device ide-hd,bus=sata.2,drive=OpenCoreBoot,id=oc,rotation_rate=1 -device ide-hd,bus=sata.3,drive=InstallMedia -drive id=InstallMedia,if=none,file="$REPO_PATH/BaseSystem.img",format=raw # Again, setup SSD trim so macOS disk qcow2 image remains sparse -blockdev driver=qcow2,node-name=MacHDD,file.driver=file,file.filename="$REPO_PATH/mac_hdd_ng.img",file.aio=threads,discard=unmap,detect-zeroes=unmap - -device ide-hd,bus=sata.4,drive=MacHDD,id=macssd - -set device.macssd.rotation_rate=1 + -device ide-hd,bus=sata.4,drive=MacHDD,id=macssd,rotation_rate=1 # -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device virtio-net-pci,netdev=net0,id=net0,mac=52:54:00:c9:18:27 -netdev user,id=net0,hostfwd=tcp::2222-:22 -device virtio-net-pci,netdev=net0,id=net0,mac=52:54:00:c9:18:27 # -netdev user,id=net0 -device vmxnet3,netdev=net0,id=net0,mac=52:54:00:c9:18:27 # Note: Use this line for High Sierra