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
|
||||
* Network port forwarding
|
||||
* Full duplex audio
|
||||
* EFI and Legacy BIOS booting
|
||||
* EFI (with or without SecureBoot) and Legacy BIOS boot
|
||||
* Graphical user interfaces available
|
||||
|
||||
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*)
|
||||
* [bash](https://www.gnu.org/software/bash/) (*4.0 or newer*)
|
||||
* [Coreutils](https://www.gnu.org/software/coreutils/)
|
||||
* [EDK II](https://github.com/tianocore/edk2)
|
||||
* [grep](https://www.gnu.org/software/grep/)
|
||||
* [jq](https://stedolan.github.io/jq/)
|
||||
* [LSB](https://wiki.linuxfoundation.org/lsb/start)
|
||||
|
|
163
quickemu
163
quickemu
|
@ -175,8 +175,25 @@ function check_cpu_flag() {
|
|||
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() {
|
||||
local BALLOON="-device virtio-balloon"
|
||||
local BOOT_STATUS=""
|
||||
local CPU=""
|
||||
local DISK_USED=""
|
||||
local DISPLAY_DEVICE=""
|
||||
|
@ -194,13 +211,15 @@ function vm_boot() {
|
|||
local KERNEL_NAME="Unknown"
|
||||
local KERNEL_NODE=""
|
||||
local KERNEL_VER="?"
|
||||
local LSB_DESCRIPTION=""
|
||||
local LSB_DESCRIPTION="Unknown OS"
|
||||
local MAC_BOOTLOADER=""
|
||||
local MAC_MISSING=""
|
||||
local MAC_DISK_DEV="ide-hd,bus=ahci.2"
|
||||
local MOUSE="usb-tablet"
|
||||
local NET_DEVICE="virtio-net"
|
||||
local OSK=""
|
||||
local QEMU_VER=""
|
||||
local SMM="off"
|
||||
local USB_HOST_PASSTHROUGH_CONTROLLER="qemu-xhci"
|
||||
local VIDEO=""
|
||||
|
||||
|
@ -210,6 +229,8 @@ function vm_boot() {
|
|||
|
||||
if command -v lsb_release &>/dev/null; then
|
||||
LSB_DESCRIPTION=$(lsb_release --description --short)
|
||||
elif [ -e /etc/os-release ]; then
|
||||
LSB_DESCRIPTION=$(grep PRETTY_NAME /etc/os-release | cut -d'"' -f2)
|
||||
fi
|
||||
|
||||
echo "Quickemu ${VERSION} using ${QEMU} v${QEMU_VER_LONG}"
|
||||
|
@ -306,7 +327,6 @@ function vm_boot() {
|
|||
# Always Boot macOS using EFI
|
||||
if [ "${guest_os}" == "macos" ]; then
|
||||
boot="efi"
|
||||
echo " - BOOT: EFI (${guest_os})"
|
||||
if [ -e "${VMDIR}/OVMF_CODE.fd" ] && [ -e "${VMDIR}/OVMF_VARS-1024x768.fd" ]; then
|
||||
EFI_CODE="${VMDIR}/OVMF_CODE.fd"
|
||||
EFI_VARS="${VMDIR}/OVMF_VARS-1024x768.fd"
|
||||
|
@ -328,6 +348,7 @@ function vm_boot() {
|
|||
echo " Use 'quickget' to download the required files."
|
||||
exit 1
|
||||
fi
|
||||
BOOT_STATUS="EFI (macOS), OVMF ($(basename "${EFI_CODE}")), SecureBoot (${secureboot})."
|
||||
elif [[ "${boot}" == *"efi"* ]]; then
|
||||
EFI_VARS="${VMDIR}/OVMF_VARS.fd"
|
||||
|
||||
|
@ -338,36 +359,73 @@ function vm_boot() {
|
|||
mv "${VMDIR}/OVMF_VARS_4M.fd" "${EFI_VARS}"
|
||||
fi
|
||||
|
||||
if [ -e "/usr/share/OVMF/OVMF_CODE_4M.fd" ] ||
|
||||
[ -e "/usr/share/OVMF/x64/OVMF_CODE.fd" ] ||
|
||||
[ -e "/usr/share/OVMF/OVMF_CODE.fd" ]; then
|
||||
echo " - BOOT: EFI (${guest_os})"
|
||||
# OVMF_CODE_4M.fd is for booting guests in non-Secure Boot mode.
|
||||
# While this image technically supports Secure Boot, it does so
|
||||
# without requiring SMM support from QEMU
|
||||
|
||||
if [ -e "/usr/share/OVMF/OVMF_CODE_4M.fd" ]; then
|
||||
EFI_CODE="/usr/share/OVMF/OVMF_CODE_4M.fd"
|
||||
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
|
||||
# OVMF_CODE.secboot.fd is like OVMF_CODE_4M.fd, but will abort if QEMU
|
||||
# does not support SMM.
|
||||
|
||||
if [ ! -e "${EFI_VARS}" ]; then
|
||||
if [ -e "/usr/share/OVMF/OVMF_VARS_4M.fd" ]; then
|
||||
cp "/usr/share/OVMF/OVMF_VARS_4M.fd" "${EFI_VARS}"
|
||||
elif [ -e "/usr/share/OVMF/x64/OVMF_VARS.fd" ]; then
|
||||
cp "/usr/share/OVMF/x64/OVMF_VARS.fd" "${EFI_VARS}"
|
||||
elif [ -e "/usr/share/OVMF/OVMF_VARS.fd" ]; then
|
||||
cp "/usr/share/OVMF/OVMF_VARS.fd" "${EFI_VARS}"
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1929357#c5
|
||||
case ${secureboot} in
|
||||
on)
|
||||
if [ -e "/usr/share/OVMF/OVMF_CODE_4M.secboot.fd" ]; then
|
||||
EFI_CODE="/usr/share/OVMF/OVMF_CODE_4M.secboot.fd"
|
||||
efi_vars "/usr/share/OVMF/OVMF_VARS_4M.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
|
||||
else
|
||||
boot="legacy"
|
||||
echo " - BOOT: Legacy BIOS (${guest_os}) - EFI requested but no EFI firmware found."
|
||||
;;
|
||||
*)
|
||||
if [ -e "/usr/share/OVMF/OVMF_CODE_4M.fd" ]; then
|
||||
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
|
||||
|
||||
# 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
|
||||
echo " - BOOT: Legacy BIOS (${guest_os})"
|
||||
BOOT_STATUS="Legacy BIOS (${guest_os^})"
|
||||
boot="legacy"
|
||||
secureboot="off"
|
||||
fi
|
||||
|
||||
echo " - BOOT: ${BOOT_STATUS}"
|
||||
|
||||
# Make any OS specific adjustments
|
||||
case ${guest_os} in
|
||||
freebsd|linux|openbsd)
|
||||
|
@ -443,6 +501,7 @@ function vm_boot() {
|
|||
if [ -z "${disk_size}" ]; then
|
||||
disk_size="64G"
|
||||
fi
|
||||
SMM="on"
|
||||
;;
|
||||
*)
|
||||
CPU="-cpu host,kvm=on"
|
||||
|
@ -454,6 +513,11 @@ function vm_boot() {
|
|||
;;
|
||||
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})"
|
||||
if [ ! -f "${disk_img}" ]; then
|
||||
# If there is no disk image, create a new image.
|
||||
|
@ -531,20 +595,6 @@ function vm_boot() {
|
|||
echo " - CD-ROM: ${fixed_iso}"
|
||||
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.
|
||||
if [ "${guest_os}" == "linux" ]; then
|
||||
local X_RES=1152
|
||||
|
@ -716,12 +766,29 @@ function vm_boot() {
|
|||
|
||||
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
|
||||
local args=()
|
||||
|
||||
# shellcheck disable=SC2054,SC2206,SC2140
|
||||
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}
|
||||
-m ${RAM_VM} ${BALLOON}
|
||||
-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/
|
||||
if [[ "${boot}" == *"efi"* ]]; then
|
||||
# shellcheck disable=SC2054
|
||||
args+=(-drive if=pflash,format=raw,file="${EFI_CODE}",readonly=on
|
||||
-drive if=pflash,format=raw,file="${EFI_VARS}")
|
||||
args+=(-global driver=cfi.pflash01,property=secure,value=on
|
||||
-drive if=pflash,format=raw,unit=0,file="${EFI_CODE}",readonly=on
|
||||
-drive if=pflash,format=raw,unit=1,file="${EFI_VARS}")
|
||||
fi
|
||||
|
||||
if [ -n "${floppy}" ]; then
|
||||
|
@ -841,9 +909,7 @@ function vm_boot() {
|
|||
SHELL_ARGS="${SHELL_ARGS//)/\\)}"
|
||||
SHELL_ARGS="${SHELL_ARGS//Wimpys World/\"Wimpys World\"}"
|
||||
|
||||
echo "#!/usr/bin/env bash" > "${VMDIR}/${VMNAME}.sh"
|
||||
echo "${QEMU}" "${SHELL_ARGS}" >> "${VMDIR}/${VMNAME}.sh"
|
||||
|
||||
${QEMU} "${args[@]}" > "${VMDIR}/${VMNAME}.log" &
|
||||
|
||||
# If output is 'none' then SPICE was requested.
|
||||
|
@ -909,6 +975,7 @@ macos_release=""
|
|||
port_forwards=()
|
||||
preallocation="off"
|
||||
ram=""
|
||||
secureboot="off"
|
||||
tpm="off"
|
||||
usb_devices=()
|
||||
|
||||
|
@ -1054,6 +1121,14 @@ if [ -n "${VM}" ] && [ -e "${VM}" ]; then
|
|||
if [ -n "${disk}" ]; then
|
||||
disk_size="${disk}"
|
||||
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
|
||||
echo "ERROR! Virtual machine configuration not found."
|
||||
usage
|
||||
|
|
Loading…
Reference in a new issue