diff --git a/quickemu b/quickemu index 6c54bb4..f2dbc94 100755 --- a/quickemu +++ b/quickemu @@ -299,14 +299,10 @@ function vm_boot() { if [ -e /sys/devices/system/cpu/smt/control ] && [ "${GUEST_CPU_CORES}" -ge 2 ]; then HOST_CPU_SMT=$(cat /sys/devices/system/cpu/smt/control) case ${HOST_CPU_SMT} in - on) - GUEST_CPU_THREADS=2 - GUEST_CPU_LOGICAL_CORES=$(( GUEST_CPU_CORES / GUEST_CPU_THREADS )) - ;; - *) - GUEST_CPU_THREADS=1 - GUEST_CPU_LOGICAL_CORES=${GUEST_CPU_CORES} - ;; + on) GUEST_CPU_THREADS=2 + GUEST_CPU_LOGICAL_CORES=$(( GUEST_CPU_CORES / GUEST_CPU_THREADS ));; + *) GUEST_CPU_THREADS=1 + GUEST_CPU_LOGICAL_CORES=${GUEST_CPU_CORES};; esac else GUEST_CPU_THREADS=1 @@ -400,29 +396,25 @@ function vm_boot() { # https://bugzilla.redhat.com/show_bug.cgi?id=1929357#c5 if [ -n "${EFI_CODE}" ] || [ ! -e "${EFI_CODE}" ]; then case ${secureboot} in - on) - # shellcheck disable=SC2054,SC2140 - ovmfs=("/usr/share/OVMF/OVMF_CODE_4M.secboot.fd","/usr/share/OVMF/OVMF_VARS_4M.fd" \ - "/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd","/usr/share/edk2/ovmf/OVMF_VARS.fd" \ - "/usr/share/OVMF/x64/OVMF_CODE.secboot.fd","/usr/share/OVMF/x64/OVMF_VARS.fd" \ - "/usr/share/edk2-ovmf/OVMF_CODE.secboot.fd","/usr/share/edk2-ovmf/OVMF_VARS.fd" \ - "/usr/share/qemu/ovmf-x86_64-smm-ms-code.bin","/usr/share/qemu/ovmf-x86_64-smm-ms-vars.bin" \ - "/usr/share/qemu/edk2-x86_64-secure-code.fd","/usr/share/qemu/edk2-x86_64-code.fd" \ - "/usr/share/edk2-ovmf/x64/OVMF_CODE.secboot.fd","/usr/share/edk2-ovmf/x64/OVMF_VARS.fd" - ) - ;; - *) - # shellcheck disable=SC2054,SC2140 - ovmfs=("/usr/share/OVMF/OVMF_CODE_4M.fd","/usr/share/OVMF/OVMF_VARS_4M.fd" \ - "/usr/share/edk2/ovmf/OVMF_CODE.fd","/usr/share/edk2/ovmf/OVMF_VARS.fd" \ - "/usr/share/OVMF/OVMF_CODE.fd","/usr/share/OVMF/OVMF_VARS.fd" \ - "/usr/share/OVMF/x64/OVMF_CODE.fd","/usr/share/OVMF/x64/OVMF_VARS.fd" \ - "/usr/share/edk2-ovmf/OVMF_CODE.fd","/usr/share/edk2-ovmf/OVMF_VARS.fd" \ - "/usr/share/qemu/ovmf-x86_64-4m-code.bin","/usr/share/qemu/ovmf-x86_64-4m-vars.bin" \ - "/usr/share/qemu/edk2-x86_64-code.fd","/usr/share/qemu/edk2-x86_64-code.fd" \ - "/usr/share/edk2-ovmf/x64/OVMF_CODE.fd","/usr/share/edk2-ovmf/x64/OVMF_VARS.fd" - ) - ;; + on) # shellcheck disable=SC2054,SC2140 + ovmfs=("/usr/share/OVMF/OVMF_CODE_4M.secboot.fd","/usr/share/OVMF/OVMF_VARS_4M.fd" \ + "/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd","/usr/share/edk2/ovmf/OVMF_VARS.fd" \ + "/usr/share/OVMF/x64/OVMF_CODE.secboot.fd","/usr/share/OVMF/x64/OVMF_VARS.fd" \ + "/usr/share/edk2-ovmf/OVMF_CODE.secboot.fd","/usr/share/edk2-ovmf/OVMF_VARS.fd" \ + "/usr/share/qemu/ovmf-x86_64-smm-ms-code.bin","/usr/share/qemu/ovmf-x86_64-smm-ms-vars.bin" \ + "/usr/share/qemu/edk2-x86_64-secure-code.fd","/usr/share/qemu/edk2-x86_64-code.fd" \ + "/usr/share/edk2-ovmf/x64/OVMF_CODE.secboot.fd","/usr/share/edk2-ovmf/x64/OVMF_VARS.fd" + );; + *) # shellcheck disable=SC2054,SC2140 + ovmfs=("/usr/share/OVMF/OVMF_CODE_4M.fd","/usr/share/OVMF/OVMF_VARS_4M.fd" \ + "/usr/share/edk2/ovmf/OVMF_CODE.fd","/usr/share/edk2/ovmf/OVMF_VARS.fd" \ + "/usr/share/OVMF/OVMF_CODE.fd","/usr/share/OVMF/OVMF_VARS.fd" \ + "/usr/share/OVMF/x64/OVMF_CODE.fd","/usr/share/OVMF/x64/OVMF_VARS.fd" \ + "/usr/share/edk2-ovmf/OVMF_CODE.fd","/usr/share/edk2-ovmf/OVMF_VARS.fd" \ + "/usr/share/qemu/ovmf-x86_64-4m-code.bin","/usr/share/qemu/ovmf-x86_64-4m-vars.bin" \ + "/usr/share/qemu/edk2-x86_64-code.fd","/usr/share/qemu/edk2-x86_64-code.fd" \ + "/usr/share/edk2-ovmf/x64/OVMF_CODE.fd","/usr/share/edk2-ovmf/x64/OVMF_VARS.fd" + );; esac # Attempt each EFI_CODE file one by one, selecting the corresponding code and vars # when an existing file is found. @@ -480,178 +472,168 @@ function vm_boot() { # Make any OS specific adjustments case ${guest_os} in - batocera|*bsd|freedos|haiku|linux*|*solaris) - CPU="-cpu host,kvm=on" - if [ "${HOST_CPU_VENDOR}" == "AuthenticAMD" ]; then - CPU="${CPU},topoext" - fi + batocera|*bsd|freedos|haiku|linux*|*solaris) + CPU="-cpu host,kvm=on" + if [ "${HOST_CPU_VENDOR}" == "AuthenticAMD" ]; then + CPU="${CPU},topoext" + fi - if [ "${guest_os}" == "freebsd" ] || [ "${guest_os}" == "ghostbsd" ]; then - MOUSE="usb" - elif [ "${guest_os}" == "batocera" ] || [ "${guest_os}" == "freedos" ] || [ "${guest_os}" == "haiku" ]; then + if [ "${guest_os}" == "freebsd" ] || [ "${guest_os}" == "ghostbsd" ]; then + MOUSE="usb" + elif [ "${guest_os}" == "batocera" ] || [ "${guest_os}" == "freedos" ] || [ "${guest_os}" == "haiku" ]; then + MACHINE_TYPE="pc" + NET_DEVICE="rtl8139" + fi + + if [ "${guest_os}" == "freedos" ] ; then + # fix for #382 + SMM="on" + SOUND_CARD="sb16" + fi + + if [[ "${guest_os}" == *"solaris" ]]; then + MACHINE_TYPE="pc" + USB_CONTROLLER="xhci" + SOUND_CARD="ac97" + fi + + if [ -z "${disk_size}" ]; then + disk_size="16G" + fi + ;; + kolibrios|reactos) + CPU="-cpu qemu32,kvm=on" + if [ "${HOST_CPU_VENDOR}" == "AuthenticAMD" ]; then + CPU="${CPU},topoext" + fi MACHINE_TYPE="pc" - NET_DEVICE="rtl8139" - fi + case ${guest_os} in + kolibrios) NET_DEVICE="rtl8139";; + reactos) NET_DEVICE="e1000" + KEYBOARD="ps2";; + esac + ;; + macos) + # https://www.nicksherlock.com/2020/04/installing-macos-catalina-on-proxmox-with-opencore/ + # https://www.nicksherlock.com/2022/10/installing-macos-13-ventura-on-proxmox/ + # noTSX stops cpuid errors https://duckduckgo.com/?t=ffab&q=CPUID.07H%3AEBX.rtm+%5Bbit+11%5D&ia=web also cited by NickSherlock for Ventura install + # Penryn https://github.com/search?q=repo%3Akholia%2FOSX-KVM%20%20GenuineIntel&type=code + # https://en.wikipedia.org/wiki/MacOS_version_history#Releases + # quickget current list: mojave catalina big-sur monterey ventura sonoma + # A CPU with SSE4.1 support is required for >= macOS Sierra + # A CPU with SSE4.2 support is required for >= macOS Catalina + # A CPU with AVX2 support is required for >= macOS Ventura + case ${macos_release} in + ventura|sonoma) + if check_cpu_flag sse4_2 && check_cpu_flag avx2; then + CPU="-cpu Haswell-v4,kvm=on,vendor=GenuineIntel,+avx,+avx2,+sse,+sse2,+sse3,+sse4.2,vmware-cpuid-freq=on" + else + echo "ERROR! macOS ${macos_release} requires a CPU with SSE 4.2 and AVX2 support." + exit 1 + fi;; + catalina|big-sur|monterey) + if check_cpu_flag sse4_2; then + CPU="-cpu Haswell-v4,kvm=on,vendor=GenuineIntel,+avx,+sse,+sse2,+sse3,+sse4.2,vmware-cpuid-freq=on" + else + echo "ERROR! macOS ${macos_release} requires a CPU with SSE 4.2 support." + exit 1 + fi;; + *) + if check_cpu_flag sse4_1; then + CPU="-cpu Penryn,kvm=on,vendor=GenuineIntel,+avx,+sse,+sse2,+sse3,+sse4.1,vmware-cpuid-freq=on" + else + echo "ERROR! macOS ${macos_release} requires a CPU with SSE 4.1 support." + exit 1 + fi;; + esac - if [ "${guest_os}" == "freedos" ] ; then - # fix for #382 + # https://www.techpowerup.com/cpu-specs/xeon-w-2140b.c2953 8 cores 16 threads # skylake server + # https://en.wikipedia.org/wiki/IMac_Pro#Technical_specifications Orig: High Sierra Max: Sonoma + # https://en.wikipedia.org/wiki/MacOS#Hardware_compatibility needs 8GB RAM + # https://qemu.readthedocs.io/en/v9.0.0/system/qemu-cpu-models.html#important-cpu-features-for-amd-x86-hosts + # https://www.reddit.com/r/hackintosh/comments/141wnjk/state_of_macos_14_sonoma_on_x86/ + for FLAG in abm adx aes amd-ssbd bmi1 bmi2 cx8 eist ept f16c fma invtsc \ + mmx movbe mpx pdpe1gb smep vaes vbmi2 vpclmulqdq \ + xgetbv1 xsave xsaveopt; do + if check_cpu_flag "${FLAG}"; then + CPU+=",+${FLAG}" + fi + done + + OSK=$(echo "bheuneqjbexolgurfrjbeqfthneqrqcyrnfrqbagfgrny(p)NccyrPbzchgreVap" | tr 'A-Za-z' 'N-ZA-Mn-za-m') + # Disable S3 support in the VM to prevent macOS suspending during install + GUEST_TWEAKS="-global kvm-pit.lost_tick_policy=discard -global ICH9-LPC.disable_s3=1 -device isa-applesmc,osk=${OSK}" + + # Disable High Precision Timer + if [ "${QEMU_VER_SHORT}" -ge 70 ]; then + MACHINE_TYPE+=",hpet=off" + else + GUEST_TWEAKS+=" -no-hpet" + fi + + # Tune Qemu optimisations based on the macOS release, or fallback to lowest + # common supported options if none is specified. + # * VirtIO Block Media doesn't work in High Sierra (at all) or the Mojave (Recovery Image) + # * VirtIO Network is supported since Big Sur + # * VirtIO Memory Balloning is supported since Big Sur (https://pmhahn.github.io/virtio-balloon/) + # * VirtIO RNG is supported since Big Sur, but exposed to all guests by default. + case ${macos_release} in + catalina) + BALLOON="" + MAC_DISK_DEV="virtio-blk-pci" + NET_DEVICE="vmxnet3" + USB_HOST_PASSTHROUGH_CONTROLLER="usb-ehci";; + big-sur|monterey|ventura|sonoma) + BALLOON="-device virtio-balloon" + MAC_DISK_DEV="virtio-blk-pci" + NET_DEVICE="virtio-net" + USB_HOST_PASSTHROUGH_CONTROLLER="nec-usb-xhci" + GUEST_TWEAKS="${GUEST_TWEAKS} -global nec-usb-xhci.msi=off" + USB_CONTROLLER="xhci";; + *) + # Backwards compatibility if no macos_release is specified. + # Also safe catch all for High Sierra and Mojave + BALLOON="" + MAC_DISK_DEV="ide-hd,bus=ahci.2" + NET_DEVICE="vmxnet3" + USB_HOST_PASSTHROUGH_CONTROLLER="usb-ehci";; + esac + + if [ -z "${disk_size}" ]; then + disk_size="96G" + fi + ;; + windows|windows-server) + if [ "${QEMU_VER_SHORT}" -gt 60 ]; then + CPU="-cpu host,kvm=on,+hypervisor,+invtsc,l3-cache=on,migratable=no,hv_passthrough" + else + CPU="-cpu host,kvm=on,+hypervisor,+invtsc,l3-cache=on,migratable=no,hv_frequencies,kvm_pv_unhalt,hv_reenlightenment,hv_relaxed,hv_spinlocks=8191,hv_stimer,hv_synic,hv_time,hv_vapic,hv_vendor_id=1234567890ab,hv_vpindex" + fi + if [ "${HOST_CPU_VENDOR}" == "AuthenticAMD" ]; then + CPU="${CPU},topoext" + fi + # Disable S3 support in the VM to ensure Windows can boot with SecureBoot enabled + # - https://wiki.archlinux.org/title/QEMU#VM_does_not_boot_when_using_a_Secure_Boot_enabled_OVMF + GUEST_TWEAKS="-global kvm-pit.lost_tick_policy=discard -global ICH9-LPC.disable_s3=1" + + # Disable High Precision Timer + if [ "${QEMU_VER_SHORT}" -ge 70 ]; then + MACHINE_TYPE+=",hpet=off" + else + GUEST_TWEAKS+=" -no-hpet" + fi + + if [ -z "${disk_size}" ]; then + disk_size="64G" + fi SMM="on" - SOUND_CARD="sb16" - fi - - if [[ "${guest_os}" == *"solaris" ]]; then - MACHINE_TYPE="pc" - USB_CONTROLLER="xhci" - SOUND_CARD="ac97" - fi - - if [ -z "${disk_size}" ]; then - disk_size="16G" - fi - ;; - kolibrios|reactos) - CPU="-cpu qemu32,kvm=on" - if [ "${HOST_CPU_VENDOR}" == "AuthenticAMD" ]; then - CPU="${CPU},topoext" - fi - MACHINE_TYPE="pc" - case ${guest_os} in - kolibrios) NET_DEVICE="rtl8139";; - reactos) - NET_DEVICE="e1000" - KEYBOARD="ps2" ;; - esac - ;; - macos) - # https://www.nicksherlock.com/2020/04/installing-macos-catalina-on-proxmox-with-opencore/ - # https://www.nicksherlock.com/2022/10/installing-macos-13-ventura-on-proxmox/ - # noTSX stops cpuid errors https://duckduckgo.com/?t=ffab&q=CPUID.07H%3AEBX.rtm+%5Bbit+11%5D&ia=web also cited by NickSherlock for Ventura install - # Penryn https://github.com/search?q=repo%3Akholia%2FOSX-KVM%20%20GenuineIntel&type=code - # https://en.wikipedia.org/wiki/MacOS_version_history#Releases - # quickget current list: mojave catalina big-sur monterey ventura sonoma - # A CPU with SSE4.1 support is required for >= macOS Sierra - # A CPU with SSE4.2 support is required for >= macOS Catalina - # A CPU with AVX2 support is required for >= macOS Ventura - case ${macos_release} in - ventura|sonoma) - if check_cpu_flag sse4_2 && check_cpu_flag avx2; then - CPU="-cpu Haswell-v4,kvm=on,vendor=GenuineIntel,+avx,+avx2,+sse,+sse2,+sse3,+sse4.2,vmware-cpuid-freq=on" - else - echo "ERROR! macOS ${macos_release} requires a CPU with SSE 4.2 and AVX2 support." - exit 1 - fi - ;; - catalina|big-sur|monterey) - if check_cpu_flag sse4_2; then - CPU="-cpu Haswell-v4,kvm=on,vendor=GenuineIntel,+avx,+sse,+sse2,+sse3,+sse4.2,vmware-cpuid-freq=on" - else - echo "ERROR! macOS ${macos_release} requires a CPU with SSE 4.2 support." - exit 1 - fi - ;; - *) - if check_cpu_flag sse4_1; then - CPU="-cpu Penryn,kvm=on,vendor=GenuineIntel,+avx,+sse,+sse2,+sse3,+sse4.1,vmware-cpuid-freq=on" - else - echo "ERROR! macOS ${macos_release} requires a CPU with SSE 4.1 support." - exit 1 - fi - ;; - esac - - # https://www.techpowerup.com/cpu-specs/xeon-w-2140b.c2953 8 cores 16 threads # skylake server - # https://en.wikipedia.org/wiki/IMac_Pro#Technical_specifications Orig: High Sierra Max: Sonoma - # https://en.wikipedia.org/wiki/MacOS#Hardware_compatibility needs 8GB RAM - # https://qemu.readthedocs.io/en/v9.0.0/system/qemu-cpu-models.html#important-cpu-features-for-amd-x86-hosts - # https://www.reddit.com/r/hackintosh/comments/141wnjk/state_of_macos_14_sonoma_on_x86/ - for FLAG in abm adx aes amd-ssbd bmi1 bmi2 cx8 eist ept f16c fma invtsc \ - mmx movbe mpx pdpe1gb smep vaes vbmi2 vpclmulqdq \ - xgetbv1 xsave xsaveopt; do - if check_cpu_flag "${FLAG}"; then - CPU+=",+${FLAG}" - fi - done - - OSK=$(echo "bheuneqjbexolgurfrjbeqfthneqrqcyrnfrqbagfgrny(p)NccyrPbzchgreVap" | tr 'A-Za-z' 'N-ZA-Mn-za-m') - # Disable S3 support in the VM to prevent macOS suspending during install - GUEST_TWEAKS="-global kvm-pit.lost_tick_policy=discard -global ICH9-LPC.disable_s3=1 -device isa-applesmc,osk=${OSK}" - - # Disable High Precision Timer - if [ "${QEMU_VER_SHORT}" -ge 70 ]; then - MACHINE_TYPE+=",hpet=off" - else - GUEST_TWEAKS+=" -no-hpet" - fi - - # Tune Qemu optimisations based on the macOS release, or fallback to lowest - # common supported options if none is specified. - # * VirtIO Block Media doesn't work in High Sierra (at all) or the Mojave (Recovery Image) - # * VirtIO Network is supported since Big Sur - # * VirtIO Memory Balloning is supported since Big Sur (https://pmhahn.github.io/virtio-balloon/) - # * VirtIO RNG is supported since Big Sur, but exposed to all guests by default. - case ${macos_release} in - catalina) - BALLOON="" - MAC_DISK_DEV="virtio-blk-pci" - NET_DEVICE="vmxnet3" - USB_HOST_PASSTHROUGH_CONTROLLER="usb-ehci" - ;; - big-sur|monterey|ventura|sonoma) - BALLOON="-device virtio-balloon" - MAC_DISK_DEV="virtio-blk-pci" - NET_DEVICE="virtio-net" - USB_HOST_PASSTHROUGH_CONTROLLER="nec-usb-xhci" - GUEST_TWEAKS="${GUEST_TWEAKS} -global nec-usb-xhci.msi=off" - USB_CONTROLLER="xhci" - ;; - *) - # Backwards compatibility if no macos_release is specified. - # Also safe catch all for High Sierra and Mojave - BALLOON="" - MAC_DISK_DEV="ide-hd,bus=ahci.2" - NET_DEVICE="vmxnet3" - USB_HOST_PASSTHROUGH_CONTROLLER="usb-ehci" - ;; - esac - - if [ -z "${disk_size}" ]; then - disk_size="96G" - fi - ;; - windows|windows-server) - if [ "${QEMU_VER_SHORT}" -gt 60 ]; then - CPU="-cpu host,kvm=on,+hypervisor,+invtsc,l3-cache=on,migratable=no,hv_passthrough" - else - CPU="-cpu host,kvm=on,+hypervisor,+invtsc,l3-cache=on,migratable=no,hv_frequencies,kvm_pv_unhalt,hv_reenlightenment,hv_relaxed,hv_spinlocks=8191,hv_stimer,hv_synic,hv_time,hv_vapic,hv_vendor_id=1234567890ab,hv_vpindex" - fi - if [ "${HOST_CPU_VENDOR}" == "AuthenticAMD" ]; then - CPU="${CPU},topoext" - fi - # Disable S3 support in the VM to ensure Windows can boot with SecureBoot enabled - # - https://wiki.archlinux.org/title/QEMU#VM_does_not_boot_when_using_a_Secure_Boot_enabled_OVMF - GUEST_TWEAKS="-global kvm-pit.lost_tick_policy=discard -global ICH9-LPC.disable_s3=1" - - # Disable High Precision Timer - if [ "${QEMU_VER_SHORT}" -ge 70 ]; then - MACHINE_TYPE+=",hpet=off" - else - GUEST_TWEAKS+=" -no-hpet" - fi - - if [ -z "${disk_size}" ]; then - disk_size="64G" - fi - SMM="on" - ;; - *) - CPU="-cpu host,kvm=on" - NET_DEVICE="rtl8139" - if [ -z "${disk_size}" ]; then - disk_size="32G" - fi - echo "WARNING! Unrecognised guest OS: ${guest_os}" - ;; + *) CPU="-cpu host,kvm=on" + NET_DEVICE="rtl8139" + if [ -z "${disk_size}" ]; then + disk_size="32G" + fi + echo "WARNING! Unrecognised guest OS: ${guest_os}";; esac echo " - Disk: ${disk_img} (${disk_size})" @@ -659,10 +641,9 @@ function vm_boot() { # If there is no disk image, create a new image. mkdir -p "${VMDIR}" 2>/dev/null case ${preallocation} in - off|metadata|falloc|full) true;; - *) - echo "ERROR! ${preallocation} is an unsupported disk preallocation option." - exit 1;; + off|metadata|falloc|full) true;; + *) echo "ERROR! ${preallocation} is an unsupported disk preallocation option." + exit 1;; esac # https://blog.programster.org/qcow2-performance @@ -727,8 +708,8 @@ function vm_boot() { # Setup the appropriate audio device based on the display output # https://www.kraxel.org/blog/2020/01/qemu-sound-audiodev/ case ${OUTPUT} in - none|spice|spice-app) AUDIO_DEV="spice,id=audio0";; - *) AUDIO_DEV="pa,id=audio0";; + none|spice|spice-app) AUDIO_DEV="spice,id=audio0";; + *) AUDIO_DEV="pa,id=audio0";; esac # Determine a sane resolution for Linux guests. @@ -772,10 +753,8 @@ function vm_boot() { DISPLAY_DEVICE="vmware-svga" elif [ "${guest_os}" == "linux" ]; then case ${OUTPUT} in - none|spice|spice-app) - DISPLAY_DEVICE="virtio-gpu";; - *) - DISPLAY_DEVICE="virtio-vga";; + none|spice|spice-app) DISPLAY_DEVICE="virtio-gpu";; + *) DISPLAY_DEVICE="virtio-vga";; esac elif [ "${guest_os}" == "macos" ]; then # qxl-vga supports seamless mouse and sane resolutions if only one scanout @@ -783,10 +762,10 @@ function vm_boot() { DISPLAY_DEVICE="qxl-vga" elif [ "${guest_os}" == "windows" ] || [ "${guest_os}" == "windows-server" ]; then case ${OUTPUT} in - # virtio-gpu "works" with gtk but is limited to 1024x1024 and exhibits other issues. - # https://kevinlocke.name/bits/2021/12/10/windows-11-guest-virtio-libvirt/#video - gtk|none|spice) DISPLAY_DEVICE="qxl-vga";; - sdl|spice-app) DISPLAY_DEVICE="virtio-vga";; + # virtio-gpu "works" with gtk but is limited to 1024x1024 and exhibits other issues. + # https://kevinlocke.name/bits/2021/12/10/windows-11-guest-virtio-libvirt/#video + gtk|none|spice) DISPLAY_DEVICE="qxl-vga";; + sdl|spice-app) DISPLAY_DEVICE="virtio-vga";; esac elif [ "${guest_os}" == "solaris" ]; then DISPLAY_DEVICE="vmware-svga" @@ -796,11 +775,11 @@ function vm_boot() { # Map Quickemu OUTPUT to QEMU -display case ${OUTPUT} in - gtk) DISPLAY_RENDER="${OUTPUT},grab-on-hover=on,zoom-to-fit=off,gl=${gl}";; - none|spice) DISPLAY_RENDER="none";; - sdl) DISPLAY_RENDER="${OUTPUT},gl=${gl}";; - spice-app) DISPLAY_RENDER="${OUTPUT},gl=${gl}";; - *) DISPLAY_RENDER="${OUTPUT}";; + gtk) DISPLAY_RENDER="${OUTPUT},grab-on-hover=on,zoom-to-fit=off,gl=${gl}";; + none|spice) DISPLAY_RENDER="none";; + sdl) DISPLAY_RENDER="${OUTPUT},gl=${gl}";; + spice-app) DISPLAY_RENDER="${OUTPUT},gl=${gl}";; + *) DISPLAY_RENDER="${OUTPUT}";; esac # https://www.kraxel.org/blog/2021/05/virtio-gpu-qemu-graphics-update/ @@ -829,9 +808,9 @@ function vm_boot() { # Allocate VRAM to VGA devices case ${DISPLAY_DEVICE} in - bochs-display) VIDEO="${VIDEO},vgamem=67108864";; - qxl|qxl-vga) VIDEO="${VIDEO},ram_size=65536,vram_size=65536,vgamem_mb=64";; - ati-vga|cirrus-vga|VGA|vmware-svga) VIDEO="${VIDEO},vgamem_mb=64";; + bochs-display) VIDEO="${VIDEO},vgamem=67108864";; + qxl|qxl-vga) VIDEO="${VIDEO},ram_size=65536,vram_size=65536,vgamem_mb=64";; + ati-vga|cirrus-vga|VGA|vmware-svga) VIDEO="${VIDEO},vgamem_mb=64";; esac # Configure multiscreen if max_outputs was provided in the .conf file @@ -938,15 +917,14 @@ function vm_boot() { if [ -n "${PUBLIC}" ]; then case ${guest_os} in - macos) - if [ "${OUTPUT}" == "none" ] || [ "${OUTPUT}" == "spice" ] || [ "${OUTPUT}" == "spice-app" ]; then - # Reference: https://gitlab.gnome.org/GNOME/phodav/-/issues/5 - echo " - WebDAV: On guest: build spice-webdavd (https://gitlab.gnome.org/GNOME/phodav/-/merge_requests/24)" - echo " - WebDAV: On guest: Finder -> Connect to Server -> http://localhost:9843/" - fi - ;; - *) - echo " - WebDAV: On guest: dav://localhost:9843/";; + macos) + if [ "${OUTPUT}" == "none" ] || [ "${OUTPUT}" == "spice" ] || [ "${OUTPUT}" == "spice-app" ]; then + # Reference: https://gitlab.gnome.org/GNOME/phodav/-/issues/5 + echo " - WebDAV: On guest: build spice-webdavd (https://gitlab.gnome.org/GNOME/phodav/-/merge_requests/24)" + echo " - WebDAV: On guest: Finder -> Connect to Server -> http://localhost:9843/" + fi;; + *) + echo " - WebDAV: On guest: dav://localhost:9843/";; esac fi @@ -1341,7 +1319,7 @@ function vm_boot() { if [ ${VM_UP} -eq 0 ]; then # Enable grab-on-hover for SDL: https://github.com/quickemu-project/quickemu/issues/541 case "${OUTPUT}" in - sdl) export SDL_MOUSE_FOCUS_CLICKTHROUGH=1;; + sdl) export SDL_MOUSE_FOCUS_CLICKTHROUGH=1;; esac echo "${QEMU}" "${SHELL_ARGS}" "2>/dev/null" >> "${VMDIR}/${VMNAME}.sh" sed -i -e 's/ -/ \\\n -/g' "${VMDIR}/${VMNAME}.sh" @@ -1544,18 +1522,15 @@ function monitor_send_cmd { fi case "${monitor_channel}" in - socket) - echo -e " - Sending: ${MSG}" - echo -e "${MSG}" | socat -,shut-down unix-connect:"${VM_MONITOR_SOCKETPATH}" 2>&1 > /dev/null - ;; - telnet) - echo -e " - Sending: ${MSG}" - echo -e "${MSG}" | socat - tcp:"${MONITOR_TELNET_HOST}":"${MONITOR_TELNET_PORT}" 2>&1 > /dev/null - ;; - *) - echo "ERROR! This should never happen!" - exit 1 - ;; + socket) + echo -e " - Sending: ${MSG}" + echo -e "${MSG}" | socat -,shut-down unix-connect:"${VM_MONITOR_SOCKETPATH}" 2>&1 > /dev/null;; + telnet) + echo -e " - Sending: ${MSG}" + echo -e "${MSG}" | socat - tcp:"${MONITOR_TELNET_HOST}":"${MONITOR_TELNET_PORT}" 2>&1 > /dev/null;; + *) + echo "ERROR! This should never happen!" + exit 1;; esac return 0 @@ -1676,159 +1651,159 @@ if [ $# -lt 1 ]; then else while [ $# -gt 0 ]; do case "${1}" in - -access|--access) - ACCESS="${2}" - shift - shift;; - -braille|--braille) - BRAILLE="on" - shift;; - -delete|--delete|-delete-disk|--delete-disk) - DELETE_DISK=1 - shift;; - -delete-vm|--delete-vm) - DELETE_VM=1 - shift;; - -display|--display) - OUTPUT="${2}" - display_param_check - shift - shift;; - -fullscreen|--fullscreen|-full-screen|--full-screen) - FULLSCREEN="-full-screen" - FULLSPICY="--full-screen" - shift;; - -ignore-msrs-always|--ignore-msrs-always) - ignore_msrs_always - exit;; - -screen|--screen) - SCREEN="${2}" - shift - shift;; - -screenpct|--screenpct) - if [ -n "${2##*[!0-9]*}" ] ; then - if [[ ${2} -ge 25 && ${2} -lt 100 ]] ; then - SCREENPCT=${2} + -access|--access) + ACCESS="${2}" + shift + shift;; + -braille|--braille) + BRAILLE="on" + shift;; + -delete|--delete|-delete-disk|--delete-disk) + DELETE_DISK=1 + shift;; + -delete-vm|--delete-vm) + DELETE_VM=1 + shift;; + -display|--display) + OUTPUT="${2}" + display_param_check + shift + shift;; + -fullscreen|--fullscreen|-full-screen|--full-screen) + FULLSCREEN="-full-screen" + FULLSPICY="--full-screen" + shift;; + -ignore-msrs-always|--ignore-msrs-always) + ignore_msrs_always + exit;; + -screen|--screen) + SCREEN="${2}" + shift + shift;; + -screenpct|--screenpct) + if [ -n "${2##*[!0-9]*}" ] ; then + if [[ ${2} -ge 25 && ${2} -lt 100 ]] ; then + SCREENPCT=${2} + else + echo "screenpct invalid must be 25 <= pct < 100" + usage + exit 1 + fi else - echo "screenpct invalid must be 25 <= pct < 100" + echo "screenpct needs to be an integer in range 25 <= pct < 100" usage exit 1 fi - else - echo "screenpct needs to be an integer in range 25 <= pct < 100" - usage - exit 1 - fi - shift - shift;; - -snapshot|--snapshot) - SNAPSHOT_ACTION="${2}" - if [ -z "${SNAPSHOT_ACTION}" ]; then - echo "ERROR! No snapshot action provided." - exit 1 - fi - shift - SNAPSHOT_TAG="${2}" - if [ -z "${SNAPSHOT_TAG}" ] && [ "${SNAPSHOT_ACTION}" != "info" ]; then - echo "ERROR! No snapshot tag provided." - exit 1 - fi - shift - shift;; - -status-quo|--status-quo) - STATUS_QUO="-snapshot" - shift;; - -shortcut|--shortcut) - SHORTCUT=1 - shift;; - -vm|--vm) - VM="${2}" - shift - shift;; - -viewer|--viewer) - VIEWER="${2}" - shift - shift;; - -width|--width) - WIDTH="${2}" - shift; - shift;; - -height|--height) - HEIGHT="${2}" - shift; - shift;; - -ssh-port|--ssh-port) - SSH_PORT="${2}" - shift; - shift;; - -spice-port|--spice-port) - SPICE_PORT="${2}" - shift; - shift;; - -public-dir|--public-dir) - PUBLIC="${2}" - shift; - shift;; - -monitor|--monitor) - MONITOR="${2}" - shift; - shift;; - -monitor-cmd|--monitor-cmd) - MONITOR_CMD="${2}" - shift; - shift;; - -monitor-telnet-host|--monitor-telnet-host) - MONITOR_TELNET_HOST="${2}" - shift; - shift;; - -monitor-telnet-port|--monitor-telnet-port) - MONITOR_TELNET_PORT="${2}" - shift; - shift;; - -serial|--serial) - SERIAL="${2}" - shift; - shift;; - -serial-telnet-host|--serial-telnet-host) - SERIAL_TELNET_HOST="${2}" - shift; - shift;; - -serial-telnet-port|--serial-telnet-port) - SERIAL_TELNET_PORT="${2}" - shift; - shift;; - -keyboard|--keyboard) - KEYBOARD="${2}" - shift; - shift;; - -keyboard_layout|--keyboard_layout) - KEYBOARD_LAYOUT="${2}" - shift; - shift;; - -mouse|--mouse) - MOUSE="${2}" - shift; - shift;; - -usb-controller|--usb-controller) - USB_CONTROLLER="${2}" - shift; - shift;; - -extra_args|--extra_args) - EXTRA_ARGS="${2}" - shift; - shift;; - -sound-card|--sound-card) - SOUND_CARD="${2}" - shift; - shift;; - -version|--version) - echo "${VERSION}" - exit;; - -h|--h|-help|--help) - usage;; - *) - echo "ERROR! \"${1}\" is not a supported parameter." - usage;; + shift + shift;; + -snapshot|--snapshot) + SNAPSHOT_ACTION="${2}" + if [ -z "${SNAPSHOT_ACTION}" ]; then + echo "ERROR! No snapshot action provided." + exit 1 + fi + shift + SNAPSHOT_TAG="${2}" + if [ -z "${SNAPSHOT_TAG}" ] && [ "${SNAPSHOT_ACTION}" != "info" ]; then + echo "ERROR! No snapshot tag provided." + exit 1 + fi + shift + shift;; + -status-quo|--status-quo) + STATUS_QUO="-snapshot" + shift;; + -shortcut|--shortcut) + SHORTCUT=1 + shift;; + -vm|--vm) + VM="${2}" + shift + shift;; + -viewer|--viewer) + VIEWER="${2}" + shift + shift;; + -width|--width) + WIDTH="${2}" + shift; + shift;; + -height|--height) + HEIGHT="${2}" + shift; + shift;; + -ssh-port|--ssh-port) + SSH_PORT="${2}" + shift; + shift;; + -spice-port|--spice-port) + SPICE_PORT="${2}" + shift; + shift;; + -public-dir|--public-dir) + PUBLIC="${2}" + shift; + shift;; + -monitor|--monitor) + MONITOR="${2}" + shift; + shift;; + -monitor-cmd|--monitor-cmd) + MONITOR_CMD="${2}" + shift; + shift;; + -monitor-telnet-host|--monitor-telnet-host) + MONITOR_TELNET_HOST="${2}" + shift; + shift;; + -monitor-telnet-port|--monitor-telnet-port) + MONITOR_TELNET_PORT="${2}" + shift; + shift;; + -serial|--serial) + SERIAL="${2}" + shift; + shift;; + -serial-telnet-host|--serial-telnet-host) + SERIAL_TELNET_HOST="${2}" + shift; + shift;; + -serial-telnet-port|--serial-telnet-port) + SERIAL_TELNET_PORT="${2}" + shift; + shift;; + -keyboard|--keyboard) + KEYBOARD="${2}" + shift; + shift;; + -keyboard_layout|--keyboard_layout) + KEYBOARD_LAYOUT="${2}" + shift; + shift;; + -mouse|--mouse) + MOUSE="${2}" + shift; + shift;; + -usb-controller|--usb-controller) + USB_CONTROLLER="${2}" + shift; + shift;; + -extra_args|--extra_args) + EXTRA_ARGS="${2}" + shift; + shift;; + -sound-card|--sound-card) + SOUND_CARD="${2}" + shift; + shift;; + -version|--version) + echo "${VERSION}" + exit;; + -h|--h|-help|--help) + usage;; + *) + echo "ERROR! \"${1}\" is not a supported parameter." + usage;; esac done fi @@ -1986,24 +1961,24 @@ fi if [ -n "${SNAPSHOT_ACTION}" ]; then case ${SNAPSHOT_ACTION} in - apply) - snapshot_apply "${SNAPSHOT_TAG}" - snapshot_info - exit;; - create) - snapshot_create "${SNAPSHOT_TAG}" - snapshot_info - exit;; - delete) - snapshot_delete "${SNAPSHOT_TAG}" - snapshot_info - exit;; - info) - snapshot_info - exit;; - *) - echo "ERROR! \"${SNAPSHOT_ACTION}\" is not a supported snapshot action." - usage;; + apply) + snapshot_apply "${SNAPSHOT_TAG}" + snapshot_info + exit;; + create) + snapshot_create "${SNAPSHOT_TAG}" + snapshot_info + exit;; + delete) + snapshot_delete "${SNAPSHOT_TAG}" + snapshot_info + exit;; + info) + snapshot_info + exit;; + *) + echo "ERROR! \"${SNAPSHOT_ACTION}\" is not a supported snapshot action." + usage;; esac fi