mirror of
				https://github.com/oSoWoSo/DistroHopper.git
				synced 2024-08-14 22:46:53 +00:00 
			
		
		
		
	Add macOS support
This commit is contained in:
		
							parent
							
								
									7a5433f8fc
								
							
						
					
					
						commit
						0b19d918d9
					
				
					 2 changed files with 194 additions and 40 deletions
				
			
		
							
								
								
									
										72
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										72
									
								
								README.md
									
										
									
									
									
								
							|  | @ -155,6 +155,78 @@ Starting /media/martin/Quickemu/windows10.conf | |||
|   * Complete the installation as you normally would. | ||||
|   * Post-install you should run the VirtIO installer from the CD-ROM: drive. | ||||
| 
 | ||||
| ### macOS | ||||
| 
 | ||||
| There are some considerations when running macOS via Quickemu. | ||||
| 
 | ||||
|   * `quickemu` will automatically download the required [Clover EFI bootloader](https://sourceforge.net/projects/cloverefiboot/) and OVMF firmware from [the macOS-Simple-KVM project](https://github.com/foxlet/macOS-Simple-KVM). | ||||
|   * **macOS 10.14.3 or newer is supported**: | ||||
|     * [VirtIO block devices QEMU standard VGA are supported](https://www.kraxel.org/blog/2019/06/macos-qemu-guest/) since macOS 10.14.3 (Mohave). | ||||
|     * [VirtIO `usb-tablet` devices are supported](http://philjordan.eu/osx-virt/) since macOS 10.11 (El Capitan). | ||||
|     * [vmxnet3 network devices are supported](https://github.com/foxlet/macOS-Simple-KVM/blob/master/docs/guide-networking.md) since macOS 10.11 (El Capitan). | ||||
|     * Running macOS on QEMU required the guest CPU is set to `Penryn`. | ||||
|     *   This is a very old architecture, [so to unlock higher CPU performance; AVX, AES-NI, SSE et al are enabled](https://www.nicksherlock.com/2017/10/passthrough-of-advanced-cpu-features-for-macos-high-sierra-guests/). | ||||
|   * UHCI USB (USB 2.0) is the fastest supported. | ||||
|     * USB pass-through has not been tested. | ||||
| 
 | ||||
| You can use `quickemu` to run a macOS virtual machine. | ||||
| 
 | ||||
|   * Download macOS using `fetch-macos.py` | ||||
| 
 | ||||
| ``` | ||||
| wget https://raw.githubusercontent.com/foxlet/macOS-Simple-KVM/master/tools/FetchMacOS/fetch-macos.py -O fetch-macos.py | ||||
| chmod +x fetch-macos.py | ||||
| ./fetch-macos.py | ||||
| qemu-virgil.qemu-img convert BaseSystem/BaseSystem.dmg -O raw BaseSystem.img | ||||
| ``` | ||||
| 
 | ||||
|   * Create a VM configuration file; for example `macos.conf` | ||||
|     * The `guest_os="macos"` line instructs `quickemu` to use optimise for macOS. | ||||
|     * The `img=` sets the boot disk that you downloaded with `fetch-macos.py` | ||||
| 
 | ||||
| ``` | ||||
| guest_os="macos" | ||||
| img="/media/$USER/Quickemu/macos/BaseSystem.img" | ||||
| disk_img="/media/$USER/Quickemu/macos/macos.qcow2" | ||||
| disk=128G | ||||
| usb_devices=("046d:082d" "046d:085e") | ||||
| ``` | ||||
| 
 | ||||
|   * Use `quickemu` to start the virtual machine: | ||||
| 
 | ||||
| ``` | ||||
| ./quickemu --vm macos.conf | ||||
| ``` | ||||
| 
 | ||||
| Which will output something like this: | ||||
| 
 | ||||
| ``` | ||||
| Starting macos.conf | ||||
|  - QEMU:     /snap/bin/qemu-virgil v4.2.0 | ||||
|  - BOOT:     EFI | ||||
|  - Guest:    Macos optimised | ||||
|  - Disk:     /media/martin/Quickemu/macos/macos.qcow2 (64G) | ||||
|              Just created, booting from /media/martin/Quickemu/macos/BaseSystem.img | ||||
|  - CPU:      4 Core(s) | ||||
|  - RAM:      4G | ||||
|  - Screen:   1664x936 | ||||
|  - Video:    VGA | ||||
|  - GL:       ON | ||||
|  - Virgil3D: OFF | ||||
|  - Display:  SDL | ||||
|  - smbd:     /home/martin will be exported to the guest via smb://10.0.2.4/qemu | ||||
|  - ssh:      22223/tcp is connected. Login via 'ssh user@localhost -p 22223' | ||||
| ``` | ||||
| 
 | ||||
|   * Boot from the BaseSystem | ||||
|     * Click **Disk Utility** and **Continue** | ||||
|     * Select `Apple Inc. VirtIO Block Media` that is ~68GB from the list and click **Erase**. | ||||
|     * Enter a `Name:` for the disk and click **Erase**. | ||||
|     * Click **Done**. | ||||
|     * Close Disk Utility | ||||
|     * Click **Reinstall macOS** and **Continue** | ||||
|   * Complete the installation as you normally would. | ||||
| 
 | ||||
| ### All the options | ||||
| 
 | ||||
| Here are the full usage instructions: | ||||
|  |  | |||
							
								
								
									
										108
									
								
								quickemu
									
										
									
									
									
								
							
							
						
						
									
										108
									
								
								quickemu
									
										
									
									
									
								
							|  | @ -1,6 +1,18 @@ | |||
| #!/usr/bin/env bash | ||||
| export LC_ALL=C | ||||
| 
 | ||||
| function web_get() { | ||||
|   local URL="${1}" | ||||
|   local FILE=$(echo "${URL##*/}") | ||||
|   if [ ! -e "${VMDIR}/${FILE}" ]; then | ||||
|     wget -q -c "${URL}" -O "${VMDIR}/${FILE}" | ||||
|     if [ $? -ne 0 ]; then | ||||
|       echo "ERROR! Failed to download ${URL}" | ||||
|       exit 1 | ||||
|     fi | ||||
|   fi | ||||
| } | ||||
| 
 | ||||
| function disk_delete() { | ||||
|   if [ -e "${disk_img}" ]; then | ||||
|     rm "${disk_img}" | ||||
|  | @ -113,8 +125,7 @@ enable_usb_passthrough() { | |||
|       USB_DEV=$(lsusb -d ${VENDOR_ID}:${PRODUCT_ID} | cut -d' ' -f4 | cut -d':' -f1) | ||||
|       USB_NAME=$(lsusb -d ${VENDOR_ID}:${PRODUCT_ID} | cut -d' ' -f7-) | ||||
|       echo "              - ${USB_NAME}" | ||||
|       USB_PASSTHROUGH="${USB_PASSTHROUGH} -usb -device usb-host,vendorid=0x${VENDOR_ID},productid=0x${PRODUCT_ID}" | ||||
|        | ||||
|       USB_PASSTHROUGH="${USB_PASSTHROUGH} -device usb-host,vendorid=0x${VENDOR_ID},productid=0x${PRODUCT_ID},bus=usb.0" | ||||
|       if [ ! -w /dev/bus/usb/${USB_BUS}/${USB_DEV} ]; then | ||||
|         local EXEC_SCRIPT=1 | ||||
|         echo "chown root:${USER} /dev/bus/usb/${USB_BUS}/${USB_DEV}" >> "${TEMP_SCRIPT}" | ||||
|  | @ -156,13 +167,27 @@ function vm_boot() { | |||
| 
 | ||||
|   # Force to lowercase. | ||||
|   boot=$(echo ${boot,,}) | ||||
| 
 | ||||
|   # A;ways Boot macOS using EFI | ||||
|   if [ "${guest_os}" == "macos" ]; then | ||||
|     boot="efi" | ||||
|   fi | ||||
| 
 | ||||
|   if [ "${boot}" == "efi" ] || [ "${boot}" == "uefi" ]; then | ||||
|     if [ -e "${VIRGIL_PATH}/usr/share/qemu/edk2-x86_64-code.fd" ] ; then | ||||
|       if [ "${guest_os}" == "macos" ]; then | ||||
|         web_get "https://github.com/foxlet/macOS-Simple-KVM/raw/master/ESP.qcow2" | ||||
|         web_get "https://github.com/foxlet/macOS-Simple-KVM/raw/master/firmware/OVMF_CODE.fd" | ||||
|         web_get "https://github.com/foxlet/macOS-Simple-KVM/raw/master/firmware/OVMF_VARS-1024x768.fd" | ||||
|         local EFI_CODE="${VMDIR}/OVMF_CODE.fd" | ||||
|         local EFI_VARS="${VMDIR}/OVMF_VARS-1024x768.fd" | ||||
|       else | ||||
|         local EFI_CODE="${VIRGIL_PATH}/usr/share/qemu/edk2-x86_64-code.fd" | ||||
|         local EFI_VARS="${VMDIR}/${VMNAME}-vars.fd" | ||||
|         if [ ! -e "${EFI_VARS}" ]; then | ||||
|           cp "${VIRGIL_PATH}/usr/share/qemu/edk2-i386-vars.fd" "${EFI_VARS}" | ||||
|         fi | ||||
|       fi | ||||
|       echo " - BOOT:     EFI" | ||||
|     else | ||||
|       echo " - BOOT:     Legacy BIOS" | ||||
|  | @ -179,6 +204,14 @@ function vm_boot() { | |||
|     linux) | ||||
|       DISPLAY_DEVICE="virtio-vga" | ||||
|       ;; | ||||
|     macos) | ||||
|       CPU="-cpu Penryn,vendor=GenuineIntel,kvm=on,+aes,+avx,+avx2,+bmi1,+bmi2,+fma,+invtsc,+movbe,+pcid,+smep,+sse3,+sse4.2,+xgetbv1,+xsave,+xsavec,+xsaveopt" | ||||
|       readonly ROT_OSK="bheuneqjbexolgurfrjbeqfthneqrqcyrnfrqbagfgrny(p)NccyrPbzchgreVap" | ||||
|       readonly OSK=$(echo ${ROT_OSK} | rot13) | ||||
|       GUEST_TWEAKS="-device isa-applesmc,osk=${OSK}" | ||||
|       DISPLAY_DEVICE="VGA" | ||||
|       VIRGL="off" | ||||
|       ;; | ||||
|     windows) | ||||
|       CPU="${CPU},hv_time" | ||||
|       GUEST_TWEAKS="-no-hpet" | ||||
|  | @ -200,11 +233,11 @@ function vm_boot() { | |||
|         echo "ERROR! Failed to create ${disk_img}" | ||||
|         exit 1 | ||||
|       fi | ||||
|       if [ -z "${iso}" ]; then | ||||
|         echo "ERROR! You haven't specified a .iso image to boot from." | ||||
|       if [ -z "${iso}" ] && [ -z "${img}" ]; then | ||||
|         echo "ERROR! You haven't specified a .iso or .img image to boot from." | ||||
|         exit 1 | ||||
|       fi | ||||
|       echo "             Just created, booting from ${iso}" | ||||
|       echo "             Just created, booting from ${iso}${img}" | ||||
|     if [ $? -ne 0 ]; then | ||||
|       echo "ERROR! Failed to create ${disk_img} of ${disk}. Stopping here." | ||||
|       exit 1 | ||||
|  | @ -218,15 +251,16 @@ function vm_boot() { | |||
|     else | ||||
|       DISK_CURR_SIZE=$(stat -c%s "${disk_img}") | ||||
|       if [ ${DISK_CURR_SIZE} -le ${DISK_MIN_SIZE} ]; then | ||||
|         echo "             Looks unused, booting from ${iso}" | ||||
|         if [ -z "${iso}" ]; then | ||||
|           echo "ERROR! You haven't specified a .iso image to boot from." | ||||
|         echo "             Looks unused, booting from ${iso}${img}" | ||||
|         if [ -z "${iso}" ] && [ -z "${img}" ]; then | ||||
|           echo "ERROR! You haven't specified a .iso or .img image to boot from." | ||||
|           exit 1 | ||||
|         fi | ||||
|       else | ||||
|         # If there is a disk image, that appears to have an install | ||||
|         # then do not boot from the iso | ||||
|         # then do not boot from the iso/img | ||||
|         iso="" | ||||
|         img="" | ||||
|       fi | ||||
|     fi | ||||
|   fi | ||||
|  | @ -251,6 +285,7 @@ function vm_boot() { | |||
|   elif [ ${CORES_HOST} -ge 4 ]; then | ||||
|     CORES_VM="2" | ||||
|   fi | ||||
|   local SMP="-smp ${CORES_VM},sockets=1,cores=${CORES_VM},threads=1" | ||||
|   echo " - CPU:      ${CORES_VM} Core(s)" | ||||
| 
 | ||||
|   local RAM_VM="2G" | ||||
|  | @ -331,10 +366,55 @@ function vm_boot() { | |||
| 
 | ||||
|   # Boot the iso image | ||||
|   if [ "${boot}" == "efi" ] || [ "${boot}" == "uefi" ]; then | ||||
|     if [ "${guest_os}" == "macos" ]; then | ||||
|       if [ -z "${img}" ]; then | ||||
|         ${QEMU} \ | ||||
|           -name ${VMNAME},process=${VMNAME} \ | ||||
|           -enable-kvm -machine q35 ${GUEST_TWEAKS} \ | ||||
|       ${CPU} -smp ${CORES_VM} \ | ||||
|           ${CPU} ${SMP} \ | ||||
|           -m ${RAM_VM} -device virtio-balloon \ | ||||
|           -drive if=pflash,format=raw,readonly,file="${EFI_CODE}" \ | ||||
|           -drive if=pflash,format=raw,file="${EFI_VARS}" \ | ||||
|           -drive id=ESP,cache=directsync,aio=native,if=none,format=qcow2,file="${VMDIR}/ESP.qcow2" \ | ||||
|           -device virtio-blk-pci,drive=ESP,scsi=off \ | ||||
|           -drive id=SystemDisk,cache=directsync,aio=native,if=none,format=qcow2,file="${disk_img}" ${STATUS_QUO} \ | ||||
|           -device virtio-blk-pci,drive=SystemDisk,scsi=off \ | ||||
|           ${VIDEO} -display ${OUTPUT},gl=${GL}${OUTPUT_EXTRA} \ | ||||
|           -device usb-ehci,id=usb -device usb-kbd,bus=usb.0 -device usb-tablet,bus=usb.0 ${USB_PASSTHROUGH} \ | ||||
|           -device vmxnet3,netdev=nic -netdev ${NET},id=nic \ | ||||
|           -audiodev pa,id=pa,server=unix:${XDG_RUNTIME_DIR}/pulse/native,out.stream-name=${LAUNCHER}-${VMNAME},in.stream-name=${LAUNCHER}-${VMNAME} \ | ||||
|           -device intel-hda -device hda-duplex,audiodev=pa,mixer=off \ | ||||
|           -rtc base=localtime,clock=host \ | ||||
|           -serial mon:stdio \ | ||||
|           "${@}" | ||||
|       else | ||||
|         ${QEMU} \ | ||||
|           -name ${VMNAME},process=${VMNAME} \ | ||||
|           -enable-kvm -machine q35 ${GUEST_TWEAKS} \ | ||||
|           ${CPU} ${SMP} \ | ||||
|           -m ${RAM_VM} -device virtio-balloon \ | ||||
|           -drive if=pflash,format=raw,readonly,file="${EFI_CODE}" \ | ||||
|           -drive if=pflash,format=raw,file="${EFI_VARS}" \ | ||||
|           -drive id=ESP,cache=directsync,aio=native,if=none,format=qcow2,file="${VMDIR}/ESP.qcow2" \ | ||||
|           -device virtio-blk-pci,drive=ESP,scsi=off \ | ||||
|           -drive id=InstallMedia,cache=directsync,aio=native,if=none,format=raw,readonly,file="${img}" \ | ||||
|           -device virtio-blk-pci,drive=InstallMedia,scsi=off \ | ||||
|           -drive id=SystemDisk,cache=directsync,aio=native,if=none,format=qcow2,file="${disk_img}" ${STATUS_QUO} \ | ||||
|           -device virtio-blk-pci,drive=SystemDisk,scsi=off \ | ||||
|           ${VIDEO} -display ${OUTPUT},gl=${GL}${OUTPUT_EXTRA} \ | ||||
|           -device usb-ehci,id=usb -device usb-kbd,bus=usb.0 -device usb-tablet,bus=usb.0 ${USB_PASSTHROUGH} \ | ||||
|           -device vmxnet3,netdev=nic -netdev ${NET},id=nic \ | ||||
|           -audiodev pa,id=pa,server=unix:${XDG_RUNTIME_DIR}/pulse/native,out.stream-name=${LAUNCHER}-${VMNAME},in.stream-name=${LAUNCHER}-${VMNAME} \ | ||||
|           -device intel-hda -device hda-duplex,audiodev=pa,mixer=off \ | ||||
|           -rtc base=localtime,clock=host \ | ||||
|           -serial mon:stdio \ | ||||
|           "${@}" | ||||
|         fi | ||||
|     else | ||||
|       ${QEMU} \ | ||||
|         -name ${VMNAME},process=${VMNAME} \ | ||||
|         -enable-kvm -machine q35 ${GUEST_TWEAKS} \ | ||||
|         ${CPU} ${SMP} \ | ||||
|         -m ${RAM_VM} -device virtio-balloon \ | ||||
|         -drive if=pflash,format=raw,readonly,file="${EFI_CODE}" \ | ||||
|         -drive if=pflash,format=raw,file="${EFI_VARS}" \ | ||||
|  | @ -343,7 +423,7 @@ function vm_boot() { | |||
|         -drive if=none,id=drive0,cache=directsync,aio=native,format=qcow2,file="${disk_img}" \ | ||||
|         -device virtio-blk-pci,drive=drive0,scsi=off ${STATUS_QUO} \ | ||||
|         ${VIDEO} -display ${OUTPUT},gl=${GL}${OUTPUT_EXTRA} \ | ||||
|       -device qemu-xhci,id=xhci,p2=8,p3=8 -device usb-kbd,bus=xhci.0 -device usb-tablet,bus=xhci.0 ${USB_PASSTHROUGH} \ | ||||
|         -device qemu-xhci,id=usb,p2=8,p3=8 -device usb-kbd,bus=usb.0 -device usb-tablet,bus=usb.0 ${USB_PASSTHROUGH} \ | ||||
|         -device virtio-net,netdev=nic -netdev ${NET},id=nic \ | ||||
|         -audiodev pa,id=pa,server=unix:${XDG_RUNTIME_DIR}/pulse/native,out.stream-name=${LAUNCHER}-${VMNAME},in.stream-name=${LAUNCHER}-${VMNAME} \ | ||||
|         -device intel-hda -device hda-duplex,audiodev=pa,mixer=off \ | ||||
|  | @ -356,18 +436,19 @@ function vm_boot() { | |||
|         -chardev spicevmc,id=spicechannel0,name=vdagent \ | ||||
|         -serial mon:stdio \ | ||||
|         "${@}" | ||||
|       fi | ||||
|   else | ||||
|     ${QEMU} \ | ||||
|       -name ${VMNAME},process=${VMNAME} \ | ||||
|       -enable-kvm -machine q35 ${GUEST_TWEAKS} \ | ||||
|       ${CPU} -smp ${CORES_VM} \ | ||||
|       ${CPU} ${SMP} \ | ||||
|       -m ${RAM_VM} -device virtio-balloon \ | ||||
|       -drive media=cdrom,index=0,file="${iso}" \ | ||||
|       -drive media=cdrom,index=1,file="${driver_iso}" \ | ||||
|       -drive if=none,id=drive0,cache=directsync,aio=native,format=qcow2,file="${disk_img}" \ | ||||
|       -device virtio-blk-pci,drive=drive0,scsi=off ${STATUS_QUO} \ | ||||
|       ${VIDEO} -display ${OUTPUT},gl=${GL}${OUTPUT_EXTRA} \ | ||||
|       -device qemu-xhci,id=xhci,p2=8,p3=8 -device usb-kbd,bus=xhci.0 -device usb-tablet,bus=xhci.0 ${USB_PASSTHROUGH} \ | ||||
|       -device qemu-xhci,id=usb,p2=8,p3=8 -device usb-kbd,bus=usb.0 -device usb-tablet,bus=usb.0 ${USB_PASSTHROUGH} \ | ||||
|       -device virtio-net,netdev=nic -netdev ${NET},id=nic \ | ||||
|       -audiodev pa,id=pa,server=unix:${XDG_RUNTIME_DIR}/pulse/native,out.stream-name=${LAUNCHER}-${VMNAME},in.stream-name=${LAUNCHER}-${VMNAME} \ | ||||
|       -device intel-hda -device hda-duplex,audiodev=pa,mixer=off \ | ||||
|  | @ -418,6 +499,7 @@ function usage() { | |||
| # Lowercase variables are used in the VM config file only | ||||
| boot="legacy" | ||||
| guest_os="linux" | ||||
| img="" | ||||
| iso="" | ||||
| driver_iso="" | ||||
| disk_img="" | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue