From e9185966f2af25b64e85d4448c6d416a34cd722d Mon Sep 17 00:00:00 2001 From: Jon Carstens Date: Fri, 8 Sep 2023 14:23:02 -0600 Subject: [PATCH] Upgrade `fwup-revert.conf` to more capable `fwup-ops.conf` --- fwup-revert.conf => fwup-ops.conf | 114 ++++++++++++++++++++++++++++++ mix.exs | 2 +- post-build.sh | 8 ++- 3 files changed, 120 insertions(+), 4 deletions(-) rename fwup-revert.conf => fwup-ops.conf (71%) diff --git a/fwup-revert.conf b/fwup-ops.conf similarity index 71% rename from fwup-revert.conf rename to fwup-ops.conf index 2a604df..6cd317b 100644 --- a/fwup-revert.conf +++ b/fwup-ops.conf @@ -1,3 +1,23 @@ +# Post-installation firmware operations firmware on the OSD32MP1 +# +# Tasks include: +# +# * `factory-reset` - Clear out the writable filesystem and possibly other +# locations +# * `prevent-revert` - Clear out the previous firmware slot +# * `revert` - Revert to the previous firmware if it's still available +# * `status` - Print out which partition is active (`a` or `b`) +# * `validate` - Mark this firmware as good +# +# To use: +# 1. Run `fwup -c -f fwup-opts.conf -o ops.fw` and copy ops.fw to +# the device. This is done automatically as part of the Nerves system +# build process. The file is stored in `/usr/share/fwup/ops.fw`. +# 2. On the device, run `fwup -t ops.fw -d $NERVES_FW_DEVPATH`. +# 3. Reboot after running `revert` or `factory-reset`. +# +# It is critical that this is kept in sync with the main fwup.conf. + require-fwup-version="1.4.0" # For the GPT support define(NERVES_FW_PRODUCT, "Nerves Firmware") @@ -192,6 +212,60 @@ uboot-environment uboot-env { block-count = ${UBOOT_ENV_COUNT} } +## +# factory-reset +## +task factory-reset { + on-init { + info("Erasing all writable data") + # This requires --enable-trim + trim(${APP_PART_OFFSET}, ${APP_PART_COUNT}) + raw_memset(${APP_PART_OFFSET}, 256, 0xff) + } +} + +## +# prevent-revert +# +# Pass `--enable-trim` to also clear out the partition that no longer should be used. +## +task prevent-revert.a { + # Check that we're running on B + require-uboot-variable(uboot-env, "nerves_fw_active", "b") + + on-init { + info("Preventing reverts to partition A") + # Remove U-Boot variables that fwup uses to allow reverting images + uboot_unsetenv(uboot-env, "a.nerves_fw_platform") + uboot_unsetenv(uboot-env, "a.nerves_fw_architecture") + # Clear out the old image using TRIM. This requires --enable-trim + trim(${EFI_A_PART_OFFSET}, ${EFI_A_PART_COUNT}) + trim(${ROOTFS_A_PART_OFFSET}, ${ROOTFS_A_PART_COUNT}) + } +} +task prevent-revert.b { + # Check that we're running on A + require-uboot-variable(uboot-env, "nerves_fw_active", "a") + + on-init { + info("Preventing reverts to partition B") + # Remove U-Boot variables that fwup uses to allow reverting images + uboot_unsetenv(uboot-env, "b.nerves_fw_platform") + uboot_unsetenv(uboot-env, "b.nerves_fw_architecture") + # Clear out the old image using TRIM. This requires --enable-trim + trim(${EFI_B_PART_OFFSET}, ${EFI_B_PART_COUNT}) + trim(${ROOTFS_B_PART_OFFSET}, ${ROOTFS_B_PART_COUNT}) + } +} +task prevent-revert.fail { + on-init { + error("Error detecting active partition") + } +} + +## +# revert +## task revert.a { # This task reverts to the A partition, so check that we're running on B require-uboot-variable(uboot-env, "nerves_fw_active", "b") @@ -249,3 +323,43 @@ task revert.wrongplatform { error("Expecting platform=${NERVES_FW_PLATFORM} and architecture=${NERVES_FW_ARCHITECTURE}") } } + +## +# status +## +# Run "fwup /usr/share/fwup/ops.fw -t status -d /dev/mmcblk0 -q -U" to check the status. +task status.aa { + require-path-on-device("/", "/dev/mmcblk0p5") + require-uboot-variable(uboot-env, "nerves_fw_active", "a") + on-init { info("a") } +} +task status.ab { + require-path-on-device("/", "/dev/mmcblk0p5") + require-uboot-variable(uboot-env, "nerves_fw_active", "b") + on-init { info("a->b") } +} +task status.bb { + require-path-on-device("/", "/dev/mmcblk0p6") + require-uboot-variable(uboot-env, "nerves_fw_active", "b") + on-init { info("b") } +} +task status.ba { + require-path-on-device("/", "/dev/mmcblk0p6") + require-uboot-variable(uboot-env, "nerves_fw_active", "a") + on-init { info("b->a") } +} +task status.fail { + on-init { error("fail") } +} + +## +# validate +## +task validate { + on-init { + info("Validate") + uboot_setenv(uboot-env, "nerves_fw_validated", "1") + uboot_setenv(uboot-env, "upgrade_available", "0") + uboot_setenv(uboot-env, "bootcount", "1") + } +} diff --git a/mix.exs b/mix.exs index c1b9cf8..1b0ece7 100644 --- a/mix.exs +++ b/mix.exs @@ -107,7 +107,7 @@ defmodule NervesSystemOsd32mp1.MixProject do "uboot", "CHANGELOG.md", "extlinux.conf", - "fwup-revert.conf", + "fwup-ops.conf", "fwup.conf", "LICENSE", "mix.exs", diff --git a/post-build.sh b/post-build.sh index cae7fd7..e6c0878 100755 --- a/post-build.sh +++ b/post-build.sh @@ -2,10 +2,12 @@ set -e -# Create the revert script for manually switching back to the previously -# active firmware. +# Create the fwup ops script to handling MicroSD/eMMC operations at runtime +# NOTE: revert.fw is the previous, more limited version of this. ops.fw is +# backwards compatible. mkdir -p $TARGET_DIR/usr/share/fwup -$HOST_DIR/usr/bin/fwup -c -f $NERVES_DEFCONFIG_DIR/fwup-revert.conf -o $TARGET_DIR/usr/share/fwup/revert.fw +$HOST_DIR/usr/bin/fwup -c -f $NERVES_DEFCONFIG_DIR/fwup-ops.conf -o $TARGET_DIR/usr/share/fwup/ops.fw +ln -sf ops.fw $TARGET_DIR/usr/share/fwup/revert.fw # Copy the fwup includes to the images dir cp -rf $NERVES_DEFCONFIG_DIR/fwup_include $BINARIES_DIR