Merge branch 'fix-102'

pull/158/head
Martin Wimpress 3 years ago
commit 330c238792
No known key found for this signature in database
GPG Key ID: 61DF940515E06DA3
  1. 3
      README.md
  2. 165
      quickemu

@ -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)

@ -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})"
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_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
# 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…
Cancel
Save