diff --git a/configs/mender_grub_config b/configs/mender_grub_config index 615681e..e6bdc6b 100644 --- a/configs/mender_grub_config +++ b/configs/mender_grub_config @@ -33,3 +33,9 @@ MENDER_GRUB_KERNEL_IMAGETYPE="" MENDER_GRUB_INITRD_IMAGETYPE="" MENDER_GRUB_BINARY_STORAGE_URL="${MENDER_STORAGE_URL}/mender-convert/grub-efi/2.04" + +# Ignore broken UEFI support in certain U-Boot versions (see MEN-2404) +MENDER_IGNORE_UBOOT_BROKEN_UEFI="0" + +# Ignore missing EFI stub on ARM (see MEN-2404) +MENDER_IGNORE_MISSING_EFI_STUB="0" diff --git a/mender-convert-extract b/mender-convert-extract index 1f700a3..b1fc92f 100755 --- a/mender-convert-extract +++ b/mender-convert-extract @@ -18,6 +18,7 @@ echo "Running $(basename $0): $@" source modules/bootstrap.sh source modules/disk.sh +source modules/probe.sh # The mender_convert_config is always used and provides all the defaults declare -a configs=("configs/mender_convert_config") @@ -106,4 +107,10 @@ if [ "${MENDER_COPY_BOOT_GAP}" == "y" ]; then log_info "Extracting boot gap to work/boot-gap.bin" disk_extract_part "${disk_image}" \ 1 $(( $(disk_get_part_value ${disk_image} 1 START) - 1)) work/boot-gap.bin + + if [ "${MENDER_GRUB_EFI_INTEGRATION}" == "y" ]; then + # Check for known U-Boot problems in the boot gap (probable boot loader + # location). + check_for_broken_uboot_uefi_support work/boot-gap.bin + fi fi diff --git a/mender-convert-modify b/mender-convert-modify index 2073a38..42edc9d 100755 --- a/mender-convert-modify +++ b/mender-convert-modify @@ -103,6 +103,9 @@ if [ "${MENDER_ENABLE_SYSTEMD}" == "y" ]; then fi if [ "${MENDER_GRUB_EFI_INTEGRATION}" == "y" ]; then + # Check for known U-Boot problems in all files on the boot partition. + check_for_broken_uboot_uefi_support work/boot + run_and_log_cmd "wget -Nq '${MENDER_GRUBENV_URL}' -P work/" run_and_log_cmd "tar xvf work/${MENDER_GRUBENV_VERSION}.tar.gz -C work/" diff --git a/modules/probe.sh b/modules/probe.sh index 1bba5f7..3673e3c 100644 --- a/modules/probe.sh +++ b/modules/probe.sh @@ -191,13 +191,18 @@ probe_kernel_in_boot_and_root() { fi done - if [ -n "${kernel_imagetype_path}" ]; then - log_info "Found Linux kernel image: \n\n\t${kernel_imagetype_path}\n" - kernel_imagetype=$(basename ${kernel_imagetype_path}) - else + if [ -z "${kernel_imagetype_path}" ]; then log_warn "Unfortunately we where not able to find the Linux kernel image." log_fatal "Please specify the image name using MENDER_GRUB_KERNEL_IMAGETYPE" fi + + log_info "Found Linux kernel image: \n\n\t${kernel_imagetype_path}\n" + kernel_imagetype=$(basename ${kernel_imagetype_path}) + + if [ "${MENDER_GRUB_EFI_INTEGRATION}" == "y" ]; then + check_efi_compatible_kernel ${kernel_imagetype_path} + fi + echo "${kernel_imagetype}" } @@ -237,3 +242,40 @@ probe_initrd_in_boot_and_root() { echo "${initrd_imagetype}" } + +check_for_broken_uboot_uefi_support() { + local path="$1" + + # Broken UEFI support in range v2018.09 - v2019.07 (see MEN-2404) + local regex='U-Boot 20(18\.(09|1[0-2])|19\.0[1-7])' + + if egrep -qr "$regex" "$path"; then + local log_level=log_fatal + if [ "$MENDER_IGNORE_UBOOT_BROKEN_UEFI" = 1 ]; then + log_level=log_warn + fi + $log_level 'Detected a U-Boot version in the range v2018.09 - v2019.07. These U-Boot versions are known to have broken UEFI support, and therefore the MENDER_GRUB_EFI_INTEGRATION feature is unlikely to work. This only affects newly flashed devices using the partition image (extension ending in "img"). The Mender artifact should still work to upgrade an existing, working device. There are two possible workarounds for this issue: 1) Use either an older or a newer image that works, and use a Mender artifact afterwards to up/down-grade it to the version you want. 2) If the device has a non-UEFI U-Boot port in mender-convert, use that (look for a board specific file in `configs`) . If you want to ignore this error and force creation of the image, set the MENDER_IGNORE_UBOOT_BROKEN_UEFI=1 config option.' + fi +} + +check_efi_compatible_kernel() { + kernel_path="$1" + + case "$(probe_arch)" in + arm|aarch64) + # On ARM, as of version 2.04, GRUB can only boot kernels which have an EFI + # stub in them. See MEN-2404. + if ! file -k $kernel_path | fgrep 'EFI application'; then + local log_level=log_fatal + if [ "$MENDER_IGNORE_MISSING_EFI_STUB" = 1 ]; then + log_level=log_warn + fi + $log_level 'Detected a kernel which does not have an EFI stub. This kernel is not supported when booting with UEFI. Please consider using a U-Boot port if the board has one (look for a board specific file in `configs`), or find a kernel which has the CONFIG_EFI_STUB turned on. To ignore this message and proceed anyway, set the MENDER_IGNORE_MISSING_EFI_STUB=1 config option.' + fi + ;; + *) + # Other platforms are fine. + : + ;; + esac +}