mirror of
				https://github.com/oSoWoSo/DistroHopper.git
				synced 2024-08-14 22:46:53 +00:00 
			
		
		
		
	Merge branch 'fix-102'
This commit is contained in:
		
						commit
						330c238792
					
				
					 2 changed files with 121 additions and 45 deletions
				
			
		|  | @ -44,7 +44,7 @@ comprehensive support for macOS and Windows**. | ||||||
|   * Automatic SSH port forwarding to guests |   * Automatic SSH port forwarding to guests | ||||||
|   * Network port forwarding |   * Network port forwarding | ||||||
|   * Full duplex audio |   * Full duplex audio | ||||||
|   * EFI and Legacy BIOS booting |   * EFI (with or without SecureBoot) and Legacy BIOS boot | ||||||
|   * Graphical user interfaces available |   * Graphical user interfaces available | ||||||
| 
 | 
 | ||||||
| Quickemu is a wrapper for the excellent [QEMU](https://www.qemu.org/) that | Quickemu is a wrapper for the excellent [QEMU](https://www.qemu.org/) that | ||||||
|  | @ -62,6 +62,7 @@ See this (old) video where I explain some of my motivations for creating Quickem | ||||||
|   * [QEMU](https://www.qemu.org/) (*6.0.0 or newer*) |   * [QEMU](https://www.qemu.org/) (*6.0.0 or newer*) | ||||||
|   * [bash](https://www.gnu.org/software/bash/) (*4.0 or newer*) |   * [bash](https://www.gnu.org/software/bash/) (*4.0 or newer*) | ||||||
|   * [Coreutils](https://www.gnu.org/software/coreutils/) |   * [Coreutils](https://www.gnu.org/software/coreutils/) | ||||||
|  |   * [EDK II](https://github.com/tianocore/edk2) | ||||||
|   * [grep](https://www.gnu.org/software/grep/) |   * [grep](https://www.gnu.org/software/grep/) | ||||||
|   * [jq](https://stedolan.github.io/jq/) |   * [jq](https://stedolan.github.io/jq/) | ||||||
|   * [LSB](https://wiki.linuxfoundation.org/lsb/start) |   * [LSB](https://wiki.linuxfoundation.org/lsb/start) | ||||||
|  |  | ||||||
							
								
								
									
										163
									
								
								quickemu
									
										
									
									
									
								
							
							
						
						
									
										163
									
								
								quickemu
									
										
									
									
									
								
							|  | @ -175,8 +175,25 @@ function check_cpu_flag() { | ||||||
|   fi |   fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function efi_vars() { | ||||||
|  |   local VARS_IN="" | ||||||
|  |   local VARS_OUT="" | ||||||
|  |   VARS_IN="${1}" | ||||||
|  |   VARS_OUT="${2}" | ||||||
|  | 
 | ||||||
|  |   if [ ! -e "${VARS_OUT}" ]; then | ||||||
|  |     if [ -e "${VARS_IN}" ]; then | ||||||
|  |       cp "${VARS_IN}" "${VARS_OUT}" | ||||||
|  |     else | ||||||
|  |       echo "ERROR! ${VARS_IN} was not found. Please install edk2." | ||||||
|  |       exit 1 | ||||||
|  |     fi | ||||||
|  |   fi | ||||||
|  | } | ||||||
|  | 
 | ||||||
| function vm_boot() { | function vm_boot() { | ||||||
|   local BALLOON="-device virtio-balloon" |   local BALLOON="-device virtio-balloon" | ||||||
|  |   local BOOT_STATUS="" | ||||||
|   local CPU="" |   local CPU="" | ||||||
|   local DISK_USED="" |   local DISK_USED="" | ||||||
|   local DISPLAY_DEVICE="" |   local DISPLAY_DEVICE="" | ||||||
|  | @ -194,13 +211,15 @@ function vm_boot() { | ||||||
|   local KERNEL_NAME="Unknown" |   local KERNEL_NAME="Unknown" | ||||||
|   local KERNEL_NODE="" |   local KERNEL_NODE="" | ||||||
|   local KERNEL_VER="?" |   local KERNEL_VER="?" | ||||||
|   local LSB_DESCRIPTION="" |   local LSB_DESCRIPTION="Unknown OS" | ||||||
|   local MAC_BOOTLOADER="" |   local MAC_BOOTLOADER="" | ||||||
|   local MAC_MISSING="" |   local MAC_MISSING="" | ||||||
|   local MAC_DISK_DEV="ide-hd,bus=ahci.2" |   local MAC_DISK_DEV="ide-hd,bus=ahci.2" | ||||||
|   local MOUSE="usb-tablet" |   local MOUSE="usb-tablet" | ||||||
|   local NET_DEVICE="virtio-net" |   local NET_DEVICE="virtio-net" | ||||||
|   local OSK="" |   local OSK="" | ||||||
|  |   local QEMU_VER="" | ||||||
|  |   local SMM="off" | ||||||
|   local USB_HOST_PASSTHROUGH_CONTROLLER="qemu-xhci" |   local USB_HOST_PASSTHROUGH_CONTROLLER="qemu-xhci" | ||||||
|   local VIDEO="" |   local VIDEO="" | ||||||
| 
 | 
 | ||||||
|  | @ -210,6 +229,8 @@ function vm_boot() { | ||||||
| 
 | 
 | ||||||
|   if command -v lsb_release &>/dev/null; then |   if command -v lsb_release &>/dev/null; then | ||||||
|     LSB_DESCRIPTION=$(lsb_release --description --short) |     LSB_DESCRIPTION=$(lsb_release --description --short) | ||||||
|  |   elif [ -e /etc/os-release ]; then | ||||||
|  |     LSB_DESCRIPTION=$(grep PRETTY_NAME /etc/os-release | cut -d'"' -f2) | ||||||
|   fi |   fi | ||||||
| 
 | 
 | ||||||
|   echo "Quickemu ${VERSION} using ${QEMU} v${QEMU_VER_LONG}" |   echo "Quickemu ${VERSION} using ${QEMU} v${QEMU_VER_LONG}" | ||||||
|  | @ -306,7 +327,6 @@ function vm_boot() { | ||||||
|   # Always Boot macOS using EFI |   # Always Boot macOS using EFI | ||||||
|   if [ "${guest_os}" == "macos" ]; then |   if [ "${guest_os}" == "macos" ]; then | ||||||
|     boot="efi" |     boot="efi" | ||||||
|     echo " - BOOT:     EFI (${guest_os})" |  | ||||||
|     if [ -e "${VMDIR}/OVMF_CODE.fd" ] && [ -e "${VMDIR}/OVMF_VARS-1024x768.fd" ]; then |     if [ -e "${VMDIR}/OVMF_CODE.fd" ] && [ -e "${VMDIR}/OVMF_VARS-1024x768.fd" ]; then | ||||||
|       EFI_CODE="${VMDIR}/OVMF_CODE.fd" |       EFI_CODE="${VMDIR}/OVMF_CODE.fd" | ||||||
|       EFI_VARS="${VMDIR}/OVMF_VARS-1024x768.fd" |       EFI_VARS="${VMDIR}/OVMF_VARS-1024x768.fd" | ||||||
|  | @ -328,6 +348,7 @@ function vm_boot() { | ||||||
|       echo "       Use 'quickget' to download the required files." |       echo "       Use 'quickget' to download the required files." | ||||||
|       exit 1 |       exit 1 | ||||||
|     fi |     fi | ||||||
|  |     BOOT_STATUS="EFI (macOS), OVMF ($(basename "${EFI_CODE}")), SecureBoot (${secureboot})." | ||||||
|   elif [[ "${boot}" == *"efi"* ]]; then |   elif [[ "${boot}" == *"efi"* ]]; then | ||||||
|     EFI_VARS="${VMDIR}/OVMF_VARS.fd" |     EFI_VARS="${VMDIR}/OVMF_VARS.fd" | ||||||
| 
 | 
 | ||||||
|  | @ -338,36 +359,73 @@ function vm_boot() { | ||||||
|       mv "${VMDIR}/OVMF_VARS_4M.fd" "${EFI_VARS}" |       mv "${VMDIR}/OVMF_VARS_4M.fd" "${EFI_VARS}" | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|     if [ -e "/usr/share/OVMF/OVMF_CODE_4M.fd" ] || |     # OVMF_CODE_4M.fd is for booting guests in non-Secure Boot mode. | ||||||
|        [ -e "/usr/share/OVMF/x64/OVMF_CODE.fd" ] || |     # While this image technically supports Secure Boot, it does so | ||||||
|        [ -e "/usr/share/OVMF/OVMF_CODE.fd" ]; then |     # without requiring SMM support from QEMU | ||||||
|       echo " - BOOT:     EFI (${guest_os})" |  | ||||||
| 
 | 
 | ||||||
|       if [ -e "/usr/share/OVMF/OVMF_CODE_4M.fd" ]; then |     # OVMF_CODE.secboot.fd is like OVMF_CODE_4M.fd, but will abort if QEMU | ||||||
|         EFI_CODE="/usr/share/OVMF/OVMF_CODE_4M.fd" |     # does not support SMM. | ||||||
|       elif [ -e "/usr/share/OVMF/x64/OVMF_CODE.fd" ]; then |  | ||||||
|         EFI_CODE="/usr/share/OVMF/x64/OVMF_CODE.fd" |  | ||||||
|       elif [ -e "/usr/share/OVMF/OVMF_CODE.fd" ]; then |  | ||||||
|         EFI_CODE="/usr/share/OVMF/OVMF_CODE.fd" |  | ||||||
|       fi |  | ||||||
| 
 | 
 | ||||||
|       if [ ! -e "${EFI_VARS}" ]; then |     # https://bugzilla.redhat.com/show_bug.cgi?id=1929357#c5 | ||||||
|         if [ -e "/usr/share/OVMF/OVMF_VARS_4M.fd" ]; then |     case ${secureboot} in | ||||||
|           cp "/usr/share/OVMF/OVMF_VARS_4M.fd" "${EFI_VARS}" |       on) | ||||||
|         elif [ -e "/usr/share/OVMF/x64/OVMF_VARS.fd" ]; then |         if [ -e "/usr/share/OVMF/OVMF_CODE_4M.secboot.fd" ]; then | ||||||
|           cp "/usr/share/OVMF/x64/OVMF_VARS.fd" "${EFI_VARS}" |           EFI_CODE="/usr/share/OVMF/OVMF_CODE_4M.secboot.fd" | ||||||
|         elif [ -e "/usr/share/OVMF/OVMF_VARS.fd" ]; then |           efi_vars "/usr/share/OVMF/OVMF_VARS_4M.fd" "${EFI_VARS}" | ||||||
|           cp "/usr/share/OVMF/OVMF_VARS.fd" "${EFI_VARS}" |         elif [ -e "/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd" ]; then | ||||||
|  |           EFI_CODE="/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd" | ||||||
|  |           efi_vars "/usr/share/edk2/ovmf/OVMF_VARS.fd" "${EFI_VARS}" | ||||||
|  |         elif [ -e "/usr/share/OVMF/x64/OVMF_CODE.secboot.fd" ]; then | ||||||
|  |           EFI_CODE="/usr/share/OVMF/x64/OVMF_CODE.secboot.fd" | ||||||
|  |           efi_vars "/usr/share/OVMF/x64/OVMF_VARS.fd" "${EFI_VARS}" | ||||||
|  |         else | ||||||
|  |           echo "ERROR! SecureBoot was requested but no SecureBoot capable firmware was found." | ||||||
|  |           echo "       Please install OVMF firmware." | ||||||
|  |           exit 1 | ||||||
|         fi |         fi | ||||||
|       fi |         ;; | ||||||
|     else |       *) | ||||||
|       boot="legacy" |         if [ -e "/usr/share/OVMF/OVMF_CODE_4M.fd" ]; then | ||||||
|       echo " - BOOT:     Legacy BIOS (${guest_os}) - EFI requested but no EFI firmware found." |           EFI_CODE="/usr/share/OVMF/OVMF_CODE_4M.fd" | ||||||
|  |           efi_vars "/usr/share/OVMF/OVMF_VARS_4M.fd" "${EFI_VARS}" | ||||||
|  |         elif [ -e "/usr/share/edk2/ovmf/OVMF_CODE.fd" ]; then | ||||||
|  |           EFI_CODE="/usr/share/edk2/ovmf/OVMF_CODE.fd" | ||||||
|  |           efi_vars "/usr/share/edk2/ovmf/OVMF_VARS.fd" "${EFI_VARS}" | ||||||
|  |         elif [ -e "/usr/share/OVMF/x64/OVMF_CODE.fd" ]; then | ||||||
|  |           EFI_CODE="/usr/share/OVMF/x64/OVMF_CODE.fd" | ||||||
|  |           efi_vars "/usr/share/OVMF/x64/OVMF_VARS.fd" "${EFI_VARS}" | ||||||
|  |         else | ||||||
|  |           echo "ERROR! EFI boot requested but no EFI firmware found." | ||||||
|  |           echo "       Please install OVMF firmware." | ||||||
|  |           exit 1 | ||||||
|  |         fi | ||||||
|  |         ;; | ||||||
|  |     esac | ||||||
|  | 
 | ||||||
|  |     # Make sure EFI_VARS references an actual, writeable, file | ||||||
|  |     if [ ! -f "${EFI_VARS}" ] || [ ! -w "${EFI_VARS}" ]; then | ||||||
|  |       echo " - EFI:      ERROR! ${EFI_VARS} is not a regular file or not writeable." | ||||||
|  |       echo "             Deleting ${EFI_VARS}. Please re-run quickemu." | ||||||
|  |       rm -f "${EFI_VARS}" | ||||||
|  |       exit 1 | ||||||
|     fi |     fi | ||||||
|  | 
 | ||||||
|  |     # If EFI_CODE references a symlink, resolve it to the real file. | ||||||
|  |     if [ -L "${EFI_CODE}" ]; then | ||||||
|  |       echo " - EFI:      WARNING! ${EFI_CODE} is a symlink." | ||||||
|  |       echo -n "             Resolving to... " | ||||||
|  |       EFI_CODE=$(realpath "${EFI_CODE}") | ||||||
|  |       echo "${EFI_CODE}" | ||||||
|  |     fi | ||||||
|  |     BOOT_STATUS="EFI (${guest_os^}), OVMF (${EFI_CODE}), SecureBoot (${secureboot})." | ||||||
|   else |   else | ||||||
|     echo " - BOOT:     Legacy BIOS (${guest_os})" |     BOOT_STATUS="Legacy BIOS (${guest_os^})" | ||||||
|  |     boot="legacy" | ||||||
|  |     secureboot="off" | ||||||
|   fi |   fi | ||||||
| 
 | 
 | ||||||
|  |   echo " - BOOT:     ${BOOT_STATUS}" | ||||||
|  | 
 | ||||||
|   # Make any OS specific adjustments |   # Make any OS specific adjustments | ||||||
|   case ${guest_os} in |   case ${guest_os} in | ||||||
|     freebsd|linux|openbsd) |     freebsd|linux|openbsd) | ||||||
|  | @ -443,6 +501,7 @@ function vm_boot() { | ||||||
|       if [ -z "${disk_size}" ]; then |       if [ -z "${disk_size}" ]; then | ||||||
|         disk_size="64G" |         disk_size="64G" | ||||||
|       fi |       fi | ||||||
|  |       SMM="on" | ||||||
|       ;; |       ;; | ||||||
|     *) |     *) | ||||||
|       CPU="-cpu host,kvm=on" |       CPU="-cpu host,kvm=on" | ||||||
|  | @ -454,6 +513,11 @@ function vm_boot() { | ||||||
|       ;; |       ;; | ||||||
|   esac |   esac | ||||||
| 
 | 
 | ||||||
|  |   # Disable suspend to RAM if SecureBoot/SMM is enabled | ||||||
|  |   if [ "${secureboot}" == "on" ] || [ "${SMM}" == "on" ]; then | ||||||
|  |     GUEST_TWEAKS="${GUEST_TWEAKS} -global ICH9-LPC.disable_s3=1" | ||||||
|  |   fi | ||||||
|  | 
 | ||||||
|   echo " - Disk:     ${disk_img} (${disk_size})" |   echo " - Disk:     ${disk_img} (${disk_size})" | ||||||
|   if [ ! -f "${disk_img}" ]; then |   if [ ! -f "${disk_img}" ]; then | ||||||
|       # If there is no disk image, create a new image. |       # If there is no disk image, create a new image. | ||||||
|  | @ -531,20 +595,6 @@ function vm_boot() { | ||||||
|     echo " - CD-ROM:   ${fixed_iso}" |     echo " - CD-ROM:   ${fixed_iso}" | ||||||
|   fi |   fi | ||||||
| 
 | 
 | ||||||
|   # Enable TPM |  | ||||||
|   if [ "${tpm}" == "on" ]; then |  | ||||||
|     if command -v swtpm &>/dev/null; then |  | ||||||
|       swtpm socket \ |  | ||||||
|         --ctrl type=unixio,path="${VMDIR}/${VMNAME}.swtpm-sock" \ |  | ||||||
|         --terminate \ |  | ||||||
|         --tpmstate dir="${VMDIR}" \ |  | ||||||
|         --tpm2 & |  | ||||||
|       echo " - TPM:      ${VMDIR}/${VMNAME}.swtpm-sock (${!})" |  | ||||||
|     else |  | ||||||
|       echo " - TPM:      swtpm is not installed, TPM not available!" |  | ||||||
|     fi |  | ||||||
|   fi |  | ||||||
| 
 |  | ||||||
|   # Determine a sane resolution for Linux guests. |   # Determine a sane resolution for Linux guests. | ||||||
|   if [ "${guest_os}" == "linux" ]; then |   if [ "${guest_os}" == "linux" ]; then | ||||||
|     local X_RES=1152 |     local X_RES=1152 | ||||||
|  | @ -716,12 +766,29 @@ function vm_boot() { | ||||||
| 
 | 
 | ||||||
|   enable_usb_passthrough |   enable_usb_passthrough | ||||||
| 
 | 
 | ||||||
|  |   echo "#!/usr/bin/env bash" > "${VMDIR}/${VMNAME}.sh" | ||||||
|  | 
 | ||||||
|  |   # Start TPM | ||||||
|  |   if [ "${tpm}" == "on" ]; then | ||||||
|  |     local tpm_args=() | ||||||
|  |     # shellcheck disable=SC2054 | ||||||
|  |     tpm_args+=(socket | ||||||
|  |             --ctrl type=unixio,path="${VMDIR}/${VMNAME}.swtpm-sock" | ||||||
|  |             --terminate | ||||||
|  |             --tpmstate dir="${VMDIR}" | ||||||
|  |             --tpm2) | ||||||
|  |     echo "${SWTPM} ${tpm_args[@]} &" >> "${VMDIR}/${VMNAME}.sh" | ||||||
|  |     ${SWTPM} "${tpm_args[@]}" >> "${VMDIR}/${VMNAME}.log" & | ||||||
|  |     echo " - TPM:      ${VMDIR}/${VMNAME}.swtpm-sock (${!})" | ||||||
|  |     sleep 1 | ||||||
|  |   fi | ||||||
|  | 
 | ||||||
|   # Boot the VM |   # Boot the VM | ||||||
|   local args=() |   local args=() | ||||||
| 
 | 
 | ||||||
|   # shellcheck disable=SC2054,SC2206,SC2140 |   # shellcheck disable=SC2054,SC2206,SC2140 | ||||||
|   args+=(-name ${VMNAME},process=${VMNAME} -pidfile "${VMDIR}/${VMNAME}.pid" |   args+=(-name ${VMNAME},process=${VMNAME} -pidfile "${VMDIR}/${VMNAME}.pid" | ||||||
|          -enable-kvm -machine q35,vmport=off ${GUEST_TWEAKS} |          -enable-kvm -machine q35,smm=${SMM},vmport=off ${GUEST_TWEAKS} | ||||||
|          ${CPU} ${SMP} |          ${CPU} ${SMP} | ||||||
|          -m ${RAM_VM} ${BALLOON} |          -m ${RAM_VM} ${BALLOON} | ||||||
|          -smbios type=2,manufacturer="Wimpys World",product="Quickemu",version="${VERSION}",serial="jvzclfjbeyq.pbz",location="wimpysworld.com",asset="${VMNAME}" |          -smbios type=2,manufacturer="Wimpys World",product="Quickemu",version="${VERSION}",serial="jvzclfjbeyq.pbz",location="wimpysworld.com",asset="${VMNAME}" | ||||||
|  | @ -754,8 +821,9 @@ function vm_boot() { | ||||||
|   # - https://turlucode.com/qemu-disk-io-performance-comparison-native-or-threads-windows-10-version/ |   # - https://turlucode.com/qemu-disk-io-performance-comparison-native-or-threads-windows-10-version/ | ||||||
|   if [[ "${boot}" == *"efi"* ]]; then |   if [[ "${boot}" == *"efi"* ]]; then | ||||||
|     # shellcheck disable=SC2054 |     # shellcheck disable=SC2054 | ||||||
|     args+=(-drive if=pflash,format=raw,file="${EFI_CODE}",readonly=on |     args+=(-global driver=cfi.pflash01,property=secure,value=on | ||||||
|            -drive if=pflash,format=raw,file="${EFI_VARS}") |            -drive if=pflash,format=raw,unit=0,file="${EFI_CODE}",readonly=on | ||||||
|  |            -drive if=pflash,format=raw,unit=1,file="${EFI_VARS}") | ||||||
|   fi |   fi | ||||||
| 
 | 
 | ||||||
|   if [ -n "${floppy}" ]; then |   if [ -n "${floppy}" ]; then | ||||||
|  | @ -841,9 +909,7 @@ function vm_boot() { | ||||||
|   SHELL_ARGS="${SHELL_ARGS//)/\\)}" |   SHELL_ARGS="${SHELL_ARGS//)/\\)}" | ||||||
|   SHELL_ARGS="${SHELL_ARGS//Wimpys World/\"Wimpys World\"}" |   SHELL_ARGS="${SHELL_ARGS//Wimpys World/\"Wimpys World\"}" | ||||||
| 
 | 
 | ||||||
|   echo "#!/usr/bin/env bash" > "${VMDIR}/${VMNAME}.sh" |  | ||||||
|   echo "${QEMU}" "${SHELL_ARGS}" >> "${VMDIR}/${VMNAME}.sh" |   echo "${QEMU}" "${SHELL_ARGS}" >> "${VMDIR}/${VMNAME}.sh" | ||||||
| 
 |  | ||||||
|   ${QEMU} "${args[@]}" > "${VMDIR}/${VMNAME}.log" & |   ${QEMU} "${args[@]}" > "${VMDIR}/${VMNAME}.log" & | ||||||
| 
 | 
 | ||||||
|   # If output is 'none' then SPICE was requested. |   # If output is 'none' then SPICE was requested. | ||||||
|  | @ -909,6 +975,7 @@ macos_release="" | ||||||
| port_forwards=() | port_forwards=() | ||||||
| preallocation="off" | preallocation="off" | ||||||
| ram="" | ram="" | ||||||
|  | secureboot="off" | ||||||
| tpm="off" | tpm="off" | ||||||
| usb_devices=() | usb_devices=() | ||||||
| 
 | 
 | ||||||
|  | @ -1054,6 +1121,14 @@ if [ -n "${VM}" ] && [ -e "${VM}" ]; then | ||||||
|   if [ -n "${disk}" ]; then |   if [ -n "${disk}" ]; then | ||||||
|     disk_size="${disk}" |     disk_size="${disk}" | ||||||
|   fi |   fi | ||||||
|  | 
 | ||||||
|  |   if [ "${tpm}" == "on" ]; then | ||||||
|  |     SWTPM=$(command -v swtpm) | ||||||
|  |     if [ ! -e "${SWTPM}" ]; then | ||||||
|  |       echo "ERROR! TPM is enabled, but swtpm was not found." | ||||||
|  |       exit 1 | ||||||
|  |     fi | ||||||
|  |   fi | ||||||
| else | else | ||||||
|   echo "ERROR! Virtual machine configuration not found." |   echo "ERROR! Virtual machine configuration not found." | ||||||
|   usage |   usage | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue