diff --git a/README.md b/README.md index 6de8fe0..f391ac8 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ See this (old) video where I explain some of my motivations for creating Quickem * [Coreutils](https://www.gnu.org/software/coreutils/) * [grep](https://www.gnu.org/software/grep/) * [jq](https://stedolan.github.io/jq/) + * [LSB](https://wiki.linuxfoundation.org/lsb/start) * [procps](https://gitlab.com/procps-ng/procps) * [python3](https://www.python.org/) * [macrecovery](https://github.com/acidanthera/OpenCorePkg/tree/master/Utilities/macrecovery) diff --git a/quickemu b/quickemu index 9b83678..c81a56b 100755 --- a/quickemu +++ b/quickemu @@ -143,6 +143,7 @@ function vm_boot() { local BALLOON="-device virtio-balloon" local CPU="" local DISK_USED="" + local DISPLAY_DEVICE="" local EFI_CODE="" local EFI_VARS="" local GUEST_CPU_CORES="" @@ -152,9 +153,12 @@ function vm_boot() { local HOST_CPU_SMT="" local HOST_CPU_SOCKETS="" local HOST_CPU_VENDOR="" - local DISPLAY_DEVICE="" local GL="on" local GUEST_TWEAKS="" + local KERNEL_NAME="Unknown" + local KERNEL_NODE="" + local KERNEL_VER="?" + local LSB_DESCRIPTION="" local MAC_BOOTLOADER="" local MAC_MISSING="" local MAC_DISK_DEV="ide-hd,bus=ahci.2" @@ -164,9 +168,101 @@ function vm_boot() { local QEMU_VER="" local USB_HOST_PASSTHROUGH_CONTROLLER="qemu-xhci" local VIDEO="" + + KERNEL_NAME=$(uname --kernel-name) + KERNEL_NODE="($(uname --nodename))" + KERNEL_VER=$(uname --kernel-release | cut -d'.' -f1-2) + + if command -v lsb_release &>/dev/null; then + LSB_DESCRIPTION=$(lsb_release --description --short) + fi + QEMU_VER=$(${QEMU} -version | head -n1 | cut -d' ' -f4 | cut -d'(' -f1) - echo "Quickemu ${VERSION} starting ${VM}" - echo " - QEMU: ${QEMU} v${QEMU_VER}" + echo "Quickemu ${VERSION} starting ${VM} on ${LSB_DESCRIPTION} ${KERNEL_NODE}" + echo " - QEMU: ${QEMU} v${QEMU_VER} on ${KERNEL_NAME} ${KERNEL_VER}" + + HOST_CPU_CORES=$(nproc --all) + HOST_CPU_MODEL=$(lscpu | grep '^Model name:' | cut -d':' -f2 | sed 's/ //g') + HOST_CPU_SOCKETS=$(lscpu | grep -E 'Socket' | cut -d':' -f2 | sed 's/ //g') + HOST_CPU_VENDOR=$(lscpu | grep -E 'Vendor' | cut -d':' -f2 | sed 's/ //g') + + # A CPU with Intel VT-x / AMD SVM support is required + if [ "${HOST_CPU_VENDOR}" == "AuthenticIntel" ]; then + if ! check_cpu_flag vmx; then + echo "ERROR! Intel VT-x support is required." + exit 1 + fi + elif [ "${HOST_CPU_VENDOR}" == "AuthenticAMD" ]; then + if ! check_cpu_flag svm; then + echo "ERROR! AMD SVM support is required." + exit 1 + fi + fi + + if [ -z "${cpu_cores}" ]; then + if [ "${HOST_CPU_CORES}" -ge 32 ]; then + GUEST_CPU_CORES="16" + elif [ "${HOST_CPU_CORES}" -ge 16 ]; then + GUEST_CPU_CORES="8" + elif [ "${HOST_CPU_CORES}" -ge 8 ]; then + GUEST_CPU_CORES="4" + elif [ "${HOST_CPU_CORES}" -ge 4 ]; then + GUEST_CPU_CORES="2" + else + GUEST_CPU_CORES="1" + fi + else + GUEST_CPU_CORES="${cpu_cores}" + fi + + # Account for Hyperthreading/SMT. + 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} + ;; + esac + else + GUEST_CPU_THREADS=1 + GUEST_CPU_LOGICAL_CORES=${GUEST_CPU_CORES} + fi + + local SMP="-smp cores=${GUEST_CPU_LOGICAL_CORES},threads=${GUEST_CPU_THREADS},sockets=${HOST_CPU_SOCKETS}" + echo " - CPU: ${HOST_CPU_MODEL}" + echo -n " - CPU VM: ${HOST_CPU_SOCKETS} Socket(s), ${GUEST_CPU_LOGICAL_CORES} Core(s), ${GUEST_CPU_THREADS} Thread(s)" + + local RAM_VM="2G" + if [ -z "${ram}" ]; then + local RAM_HOST="" + RAM_HOST=$(free --mega -h | grep Mem | cut -d':' -f2 | cut -d'G' -f1 | sed 's/ //g') + #Round up - https://github.com/wimpysworld/quickemu/issues/11 + RAM_HOST=$(printf '%.*f\n' 0 "${RAM_HOST}") + if [ "${RAM_HOST}" -ge 128 ]; then + RAM_VM="32G" + elif [ "${RAM_HOST}" -ge 64 ]; then + RAM_VM="16G" + elif [ "${RAM_HOST}" -ge 16 ]; then + RAM_VM="8G" + elif [ "${RAM_HOST}" -ge 8 ]; then + RAM_VM="4G" + fi + else + RAM_VM="${ram}" + fi + echo ", ${RAM_VM} RAM" + + if [ ${RAM_VM//G/} -lt 4 ]; then + if [ "${guest_os}" == "macos" ] || [ "${guest_os}" == "windows" ]; then + echo "ERROR! You have insufficient RAM to run ${guest_os} in a VM" + exit 1 + fi + fi # Force to lowercase. boot=${boot,,} @@ -237,87 +333,6 @@ function vm_boot() { echo " - BOOT: Legacy BIOS (${guest_os})" fi - HOST_CPU_CORES=$(nproc --all) - HOST_CPU_VENDOR=$(lscpu | grep -E 'Vendor' | cut -d':' -f2 | sed 's/ //g') - HOST_CPU_SOCKETS=$(lscpu | grep -E 'Socket' | cut -d':' -f2 | sed 's/ //g') - - # A CPU with Intel VT-x / AMD SVM support is required - if [ "${HOST_CPU_VENDOR}" == "AuthenticIntel" ]; then - if ! check_cpu_flag vmx; then - echo "ERROR! Intel VT-x support is required." - exit 1 - fi - elif [ "${HOST_CPU_VENDOR}" == "AuthenticAMD" ]; then - if ! check_cpu_flag svm; then - echo "ERROR! AMD SVM support is required." - exit 1 - fi - fi - - if [ -z "${cpu_cores}" ]; then - if [ "${HOST_CPU_CORES}" -ge 32 ]; then - GUEST_CPU_CORES="16" - elif [ "${HOST_CPU_CORES}" -ge 16 ]; then - GUEST_CPU_CORES="8" - elif [ "${HOST_CPU_CORES}" -ge 8 ]; then - GUEST_CPU_CORES="4" - elif [ "${HOST_CPU_CORES}" -ge 4 ]; then - GUEST_CPU_CORES="2" - else - GUEST_CPU_CORES="1" - fi - else - GUEST_CPU_CORES="${cpu_cores}" - fi - - # Account for Hyperthreading/SMT. - 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} - ;; - esac - else - GUEST_CPU_THREADS=1 - GUEST_CPU_LOGICAL_CORES=${GUEST_CPU_CORES} - fi - - local SMP="-smp cores=${GUEST_CPU_LOGICAL_CORES},threads=${GUEST_CPU_THREADS},sockets=${HOST_CPU_SOCKETS}" - echo -n " - CPU: ${HOST_CPU_SOCKETS} Socket(s), ${GUEST_CPU_LOGICAL_CORES} Core(s), ${GUEST_CPU_THREADS} Thread(s)" - - local RAM_VM="2G" - if [ -z "${ram}" ]; then - local RAM_HOST="" - RAM_HOST=$(free --mega -h | grep Mem | cut -d':' -f2 | cut -d'G' -f1 | sed 's/ //g') - #Round up - https://github.com/wimpysworld/quickemu/issues/11 - RAM_HOST=$(printf '%.*f\n' 0 "${RAM_HOST}") - if [ "${RAM_HOST}" -ge 128 ]; then - RAM_VM="32G" - elif [ "${RAM_HOST}" -ge 64 ]; then - RAM_VM="16G" - elif [ "${RAM_HOST}" -ge 16 ]; then - RAM_VM="8G" - elif [ "${RAM_HOST}" -ge 8 ]; then - RAM_VM="4G" - fi - else - RAM_VM="${ram}" - fi - echo ", ${RAM_VM} RAM" - - if [ ${RAM_VM//G/} -lt 4 ]; then - if [ "${guest_os}" == "macos" ] || [ "${guest_os}" == "windows" ]; then - echo "ERROR! You have insufficient RAM to run ${guest_os} in a VM" - exit 1 - fi - fi - # Make any OS specific adjustments case ${guest_os} in freebsd|linux)