From fc0f1e20d5bea04606d0ea0b5dc51caa1aecff7f Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Mon, 28 Feb 2022 16:49:34 +0100 Subject: [PATCH] Fix GRUB2 update using post-install hook (#1770) * Use shell functions for install hooks * Use post-install hook to initialize GRUB2 bootloader env Unfortunately the boot name to be updated (RAUC_SLOT_BOOTNAME) is not available when updating the "boot" slot. Instead, initialize the boot slot in a kernel post-install slot. --- buildroot-external/ota/rauc-hook | 146 ++++++++++++++++-------------- buildroot-external/scripts/ota.sh | 3 + 2 files changed, 82 insertions(+), 67 deletions(-) diff --git a/buildroot-external/ota/rauc-hook b/buildroot-external/ota/rauc-hook index fd3bedb65..a28077e80 100755 --- a/buildroot-external/ota/rauc-hook +++ b/buildroot-external/ota/rauc-hook @@ -2,6 +2,75 @@ set -o errexit +install_boot() { + BOOT_TMP=/tmp/boot-tmp + BOOT_NEW=/tmp/boot-new + BOOT_MNT=/mnt/boot + + mkdir -p "${BOOT_TMP}" + mkdir -p "${BOOT_NEW}" + + # Mount boot + if ! systemctl -q is-active mnt-boot.mount; then + systemctl start mnt-boot.mount + fi + mount "${RAUC_IMAGE_NAME}" "${BOOT_NEW}" + + # Backup boot config + cp -f "${BOOT_MNT}"/*.txt "${BOOT_TMP}/" + + # Update + cp -rf "${BOOT_NEW}"/* "${BOOT_MNT}/" + + # Restore boot config + cp -f "${BOOT_TMP}"/*.txt "${BOOT_MNT}/" + + umount "${BOOT_NEW}" + rm -rf "${BOOT_TMP}" "${BOOT_NEW}" +} + +install_spl() { + DEVICE_CHILD="$(findfs LABEL="hassos-boot")" + DEVICE_ROOT="/dev/$(lsblk -no pkname "${DEVICE_CHILD}")" + PART_TABLE="$(sfdisk -lqJ "${DEVICE_ROOT}")" + PART_LABEL="$(echo "${PART_TABLE}" | jq -r '.partitiontable.label')" + FLAGS="" + + if dd oflag=direct if=/dev/null 2> /dev/null; then + FLAGS="oflag=direct" + fi + + if [ "${PART_LABEL}" = "gpt" ]; then + dd if="${RAUC_IMAGE_NAME}" of="${DEVICE_ROOT}" conv=notrunc ${FLAGS} bs=512 seek=2 skip=2 + else + dd if="${RAUC_IMAGE_NAME}" of="${DEVICE_ROOT}" conv=notrunc ${FLAGS} bs=1 count=440 + dd if="${RAUC_IMAGE_NAME}" of="${DEVICE_ROOT}" conv=notrunc ${FLAGS} bs=512 seek=1 skip=1 + fi + + # Flash to eMMC boot partition if necessary + if [ "$RAUC_SYSTEM_COMPATIBLE" = "haos-odroid-xu4" ] && [ -b "${DEVICE_ROOT}boot0" ]; then + echo "Updating eMMC boot partition" + echo 0 > /sys/block/"$(basename "${DEVICE_ROOT}boot0")"/force_ro + dd if="${RAUC_IMAGE_NAME}" of="${DEVICE_ROOT}boot0" conv=notrunc ${FLAGS} bs=512 skip=1 count=2047 + echo 1 > /sys/block/"$(basename "${DEVICE_ROOT}boot0")"/force_ro + fi +} + +post_install_kernel() { + BOOT_MNT=/mnt/boot + + # Mount boot + if ! systemctl -q is-active mnt-boot.mount; then + systemctl start mnt-boot.mount + fi + + # If grubenv is missing, initialize with boot order which will try the right + # boot slot first + if [ -d "${BOOT_MNT}"/EFI/BOOT/ ] && [ ! -f "${BOOT_MNT}"/EFI/BOOT/grubenv ]; then + cp -f "${BOOT_MNT}/EFI/BOOT/grubenv-${RAUC_SLOT_BOOTNAME}" "${BOOT_MNT}"/EFI/BOOT/grubenv + fi +} + ## # Hooks @@ -26,77 +95,20 @@ case "$1" in exit 10 ;; slot-install) - # Use install handlers below + if [ "${RAUC_SLOT_CLASS}" = "boot" ]; then + install_boot + elif [ "${RAUC_SLOT_CLASS}" = "spl" ]; then + install_spl + fi + ;; + slot-post-install) + if [ "${RAUC_SLOT_CLASS}" = "kernel" ]; then + post_install_kernel + fi ;; *) exit 1 ;; esac -# Handle boot hocks -if [ "${RAUC_SLOT_CLASS}" = "boot" ]; then - BOOT_TMP=/tmp/boot-tmp - BOOT_NEW=/tmp/boot-new - BOOT_MNT=/mnt/boot - - mkdir -p "${BOOT_TMP}" - mkdir -p "${BOOT_NEW}" - - # Mount boot - if ! systemctl -q is-active mnt-boot.mount; then - systemctl start mnt-boot.mount - fi - mount "${RAUC_IMAGE_NAME}" "${BOOT_NEW}" - - # Backup boot config - cp -f "${BOOT_MNT}"/*.txt "${BOOT_TMP}/" - - # Update - cp -rf "${BOOT_NEW}"/* "${BOOT_MNT}/" - - # If grubenv is missing, initialize with boot order which will try the right - # boot slot - if [ -d "${BOOT_NEW}"/EFI/BOOT/ ] && [ ! -f "${BOOT_NEW}"/EFI/BOOT/grubenv ]; then - cp -f "${BOOT_NEW}/EFI/BOOT/grubenv-${RAUC_SLOT_BOOTNAME}" "${BOOT_NEW}"/EFI/BOOT/grubenv - fi - - # Restore boot config - cp -f "${BOOT_TMP}"/*.txt "${BOOT_MNT}/" - - umount "${BOOT_NEW}" - rm -rf "${BOOT_TMP}" "${BOOT_NEW}" -fi - -# Handle spl install -if [ "${RAUC_SLOT_CLASS}" = "spl" ]; then - DEVICE_CHILD="$(findfs LABEL="hassos-boot")" - DEVICE_ROOT="/dev/$(lsblk -no pkname "${DEVICE_CHILD}")" - PART_TABLE="$(sfdisk -lqJ "${DEVICE_ROOT}")" - PART_LABEL="$(echo "${PART_TABLE}" | jq -r '.partitiontable.label')" - FLAGS="" - - if dd oflag=direct if=/dev/null 2> /dev/null; then - FLAGS="oflag=direct" - fi - - if [ "${PART_LABEL}" = "gpt" ]; then - dd if="${RAUC_IMAGE_NAME}" of="${DEVICE_ROOT}" conv=notrunc ${FLAGS} bs=512 seek=2 skip=2 - else - dd if="${RAUC_IMAGE_NAME}" of="${DEVICE_ROOT}" conv=notrunc ${FLAGS} bs=1 count=440 - dd if="${RAUC_IMAGE_NAME}" of="${DEVICE_ROOT}" conv=notrunc ${FLAGS} bs=512 seek=1 skip=1 - fi - - # Flash to eMMC boot partition if necessary - if [ "$RAUC_SYSTEM_COMPATIBLE" = "haos-odroid-xu4" ] && [ -b "${DEVICE_ROOT}boot0" ]; then - echo "Updating eMMC boot partition" - echo 0 > /sys/block/"$(basename "${DEVICE_ROOT}boot0")"/force_ro - dd if="${RAUC_IMAGE_NAME}" of="${DEVICE_ROOT}boot0" conv=notrunc ${FLAGS} bs=512 skip=1 count=2047 - echo 1 > /sys/block/"$(basename "${DEVICE_ROOT}boot0")"/force_ro - fi -fi - -## -# Fixups - - exit 0 diff --git a/buildroot-external/scripts/ota.sh b/buildroot-external/scripts/ota.sh index 918a5f8ee..c4d344ce6 100755 --- a/buildroot-external/scripts/ota.sh +++ b/buildroot-external/scripts/ota.sh @@ -38,6 +38,9 @@ function create_ota_update() { echo "hooks=install" echo "[image.kernel]" echo "filename=kernel.img" + if [ "${BOOTLOADER}" == "grub" ]; then + echo "hooks=post-install" + fi echo "[image.rootfs]" echo "filename=rootfs.img" ) > "${rauc_folder}/manifest.raucm"