From 56210943f80056bd6ac39b2603acb21cc0c6fbea Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 14 Mar 2022 09:13:35 -0700 Subject: [PATCH 1/5] boot-qemu.sh: Move kernel image path logic to its own function We will need to make some QEMU argument choices based on the kernel version, which we can only get reliably from the kernel image itself, which means we need to call this block in the case statement above. Signed-off-by: Nathan Chancellor --- boot-qemu.sh | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/boot-qemu.sh b/boot-qemu.sh index 074d038..b74d412 100755 --- a/boot-qemu.sh +++ b/boot-qemu.sh @@ -155,6 +155,21 @@ function get_default_smp_value() { fi } +# Expands '-k' to an absolute path to a kernel image if necessary +function get_full_kernel_path() { + # If '-k' is an path that ends in the kernel image, we can just use it directly + if [[ ${KERNEL_LOCATION##*/} = "${KIMAGE:=zImage}" ]]; then + KERNEL=${KERNEL_LOCATION} + # If not though, we need to find it based on the kernel build directory + else + # If the image is an uncompressed vmlinux, it is in the root of the build folder + # Otherwise, it is in the architecture's boot directory + [[ ${KIMAGE} == "vmlinux" ]] || BOOT_DIR=arch/${ARCH}/boot/ + KERNEL=${KERNEL_LOCATION}/${BOOT_DIR}${KIMAGE} + fi + [[ -f ${KERNEL} ]] || die "${KERNEL} does not exist!" +} + # Boot QEMU function setup_qemu_args() { # All arm32_* options share the same rootfs, under images/arm @@ -364,17 +379,8 @@ function setup_qemu_args() { esac checkbin "${QEMU[*]}" - # If '-k' is an path that ends in the kernel image, we can just use it directly - if [[ ${KERNEL_LOCATION##*/} = "${KIMAGE:=zImage}" ]]; then - KERNEL=${KERNEL_LOCATION} - # If not though, we need to find it based on the kernel build directory - else - # If the image is an uncompressed vmlinux, it is in the root of the build folder - # Otherwise, it is in the architecture's boot directory - [[ ${KIMAGE} == "vmlinux" ]] || BOOT_DIR=arch/${ARCH}/boot/ - KERNEL=${KERNEL_LOCATION}/${BOOT_DIR}${KIMAGE} - fi - [[ -f ${KERNEL} ]] || die "${KERNEL} does not exist!" + [[ -z ${KERNEL} ]] && get_full_kernel_path + if [[ -n ${DTB} ]]; then # If we are in a boot folder, look for them in the dts folder in it if [[ $(basename "${KERNEL%/*}") = "boot" ]]; then From 4320279166f7626f96f4d6dc4e2e91db757e0817 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 14 Mar 2022 09:43:36 -0700 Subject: [PATCH 2/5] boot-qemu.sh: Add a function to get the QEMU version as a number Similar to the Linux kernel's representation of compiler versions, add the ability to get the version of a QEMU as a five or six digit number to make decisions based on what version of QEMU is being used. Signed-off-by: Nathan Chancellor --- boot-qemu.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boot-qemu.sh b/boot-qemu.sh index b74d412..3ae9938 100755 --- a/boot-qemu.sh +++ b/boot-qemu.sh @@ -170,6 +170,13 @@ function get_full_kernel_path() { [[ -f ${KERNEL} ]] || die "${KERNEL} does not exist!" } +# Print QEMU version as a five or six digit number +function get_qemu_ver_code() { + QEMU_VER=$("${QEMU[@]}" --version | head -1 | cut -d ' ' -f 4) + IFS=. read -ra QEMU_VER <<<"${QEMU_VER}" + printf "%d%02d%02d" "${QEMU_VER[@]}" +} + # Boot QEMU function setup_qemu_args() { # All arm32_* options share the same rootfs, under images/arm From e53f47e3b304dbf497bd0e447a3cfe7b548acad1 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 14 Mar 2022 09:45:22 -0700 Subject: [PATCH 3/5] boot-qemu.sh: Add a function to get the kernel version as a number Similar to the Linux kernel's representation of compiler versions, add the ability to get the version of the kernel being booted as a six or seven digit number to make decisions based on that number. To do this, we need a decompressed kernel image, so that we can use "strings" + "grep". The arguments to the function are the command to dump the decompressed kernel image to stdout. For example, if the kernel image is Image.gz, the command would be "gzip -c -d ...". Signed-off-by: Nathan Chancellor --- boot-qemu.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/boot-qemu.sh b/boot-qemu.sh index 3ae9938..206eaa6 100755 --- a/boot-qemu.sh +++ b/boot-qemu.sh @@ -177,6 +177,14 @@ function get_qemu_ver_code() { printf "%d%02d%02d" "${QEMU_VER[@]}" } +# Print Linux version of a kernel image as a six or seven digit number +# Takes the command to dump a kernel image to stdout as its argument +function get_lnx_ver_code() { + LINUX_VER="$("${@}" |& strings |& grep -E "^Linux version [0-9]\.[0-9]+\.[0-9]+" | cut -d ' ' -f 3 | cut -d - -f 1)" + IFS=. read -ra LINUX_VER <<<"${LINUX_VER}" + printf "%d%02d%03d" "${LINUX_VER[@]}" +} + # Boot QEMU function setup_qemu_args() { # All arm32_* options share the same rootfs, under images/arm From d1daa35e64d5f828ff77c2fd68d6795205856acc Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 14 Mar 2022 13:55:48 -0700 Subject: [PATCH 4/5] boot-qemu.sh: Share version printing code between Linux and QEMU Refactor get_{lnx,qemu}_ver_code to share splitting the version into an array and printing it as a six or seven digit number. The QEMU sublevel is never more than 100 but that does not matter much. Signed-off-by: Nathan Chancellor --- boot-qemu.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/boot-qemu.sh b/boot-qemu.sh index 206eaa6..2bb96ec 100755 --- a/boot-qemu.sh +++ b/boot-qemu.sh @@ -170,19 +170,23 @@ function get_full_kernel_path() { [[ -f ${KERNEL} ]] || die "${KERNEL} does not exist!" } -# Print QEMU version as a five or six digit number +# Takes a version (x.y.z) and prints a six or seven digit number +# For example, QEMU 6.2.50 would become 602050 and Linux 5.10.100 +# would become 510100 +function print_ver_code() { + IFS=. read -ra VER_CODE <<<"${1}" + printf "%d%02d%03d" "${VER_CODE[@]}" +} + +# Print QEMU version as a six or seven digit number function get_qemu_ver_code() { - QEMU_VER=$("${QEMU[@]}" --version | head -1 | cut -d ' ' -f 4) - IFS=. read -ra QEMU_VER <<<"${QEMU_VER}" - printf "%d%02d%02d" "${QEMU_VER[@]}" + print_ver_code "$("${QEMU[@]}" --version | head -1 | cut -d ' ' -f 4)" } # Print Linux version of a kernel image as a six or seven digit number # Takes the command to dump a kernel image to stdout as its argument function get_lnx_ver_code() { - LINUX_VER="$("${@}" |& strings |& grep -E "^Linux version [0-9]\.[0-9]+\.[0-9]+" | cut -d ' ' -f 3 | cut -d - -f 1)" - IFS=. read -ra LINUX_VER <<<"${LINUX_VER}" - printf "%d%02d%03d" "${LINUX_VER[@]}" + print_ver_code "$("${@}" |& strings |& grep -E "^Linux version [0-9]\.[0-9]+\.[0-9]+" | cut -d ' ' -f 3 | cut -d - -f 1)" } # Boot QEMU From 11d3e43628b96821c5a2446ca64ddc2220940d1d Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 14 Mar 2022 13:54:15 -0700 Subject: [PATCH 5/5] boot-qemu.sh: arm64: Pass 'lpa2=off' when necessary Starting with QEMU commit 69b2265d5fe8e, aarch64 kernels older than 5.12.0 do not boot without "lpa2=off". Add this parameter when booting a kernel older than this version using a version of QEMU that has this commit. We cannot universally pass this for all QEMU versions because the property is not recognized on older version: qemu-system-aarch64: can't apply global max-arm-cpu.lpa2=off: Property 'max-arm-cpu.lpa2' not found We could pass this for all kernel versions but we miss out on testing a default QEMU change. Link: https://gitlab.com/qemu-project/qemu/-/commit/69b2265d5fe8e0f401d75e175e0a243a7d505e53 Signed-off-by: Nathan Chancellor --- boot-qemu.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/boot-qemu.sh b/boot-qemu.sh index 2bb96ec..66bfe3c 100755 --- a/boot-qemu.sh +++ b/boot-qemu.sh @@ -267,9 +267,16 @@ function setup_qemu_args() { arm64 | arm64be) ARCH=arm64 KIMAGE=Image.gz + QEMU=(qemu-system-aarch64) + get_full_kernel_path + # https://gitlab.com/qemu-project/qemu/-/commit/69b2265d5fe8e0f401d75e175e0a243a7d505e53 + if [[ $(get_lnx_ver_code gzip -c -d "${KERNEL}") -lt 512000 ]] && + [[ $(get_qemu_ver_code) -ge 602050 ]]; then + LPA2=,lpa2=off + fi APPEND_STRING+="console=ttyAMA0 earlycon " QEMU_ARCH_ARGS=( - -cpu max + -cpu "max${LPA2}" -machine "virt,gic-version=max" ) if [[ "$(uname -m)" = "aarch64" && -e /dev/kvm ]] && ${KVM}; then @@ -291,7 +298,6 @@ function setup_qemu_args() { QEMU_ARCH_ARGS+=(-smp "${SMP:-4}") fi fi - QEMU=(qemu-system-aarch64) ;; m68k)