rpi-eeprom-update: Specifiy a minimum version number for automatic updates

Add a new flag '-s' which init scripts should specify to indicate that
the bootloader is running silently to do an automatic update. If '-s'
is specified and the 'default' release is specified then the bootloader
is only updated if it is older than the minimum version number specified
within this script.
This allows the default release to be updated to support new hardware
without forcing updates for existing users. However, if the
configuration is updated then the latest release should be used.

E.g. If network boot is selected via raspi-config or the Raspberry Pi
Imager then it's desirable to get the latest production release to
benefit from any bug fixes. However, a bootloader updated to support
new hardware (e.g. CM4) should not require Pi4B users to to upgrade
their bootloader.

The min-version is set to pieeprom-2020-09-03.
This commit is contained in:
Tim Gover
2021-03-23 15:37:18 +00:00
parent 587683e8e5
commit a4d7bdbef0

View File

@@ -34,6 +34,10 @@ VCMAILBOX=${VCMAILBOX:-/opt/vc/bin/vcmailbox}
CM4_ENABLE_RPI_EEPROM_UPDATE=${CM4_ENABLE_RPI_EEPROM_UPDATE:-0} CM4_ENABLE_RPI_EEPROM_UPDATE=${CM4_ENABLE_RPI_EEPROM_UPDATE:-0}
RPI_EEPROM_UPDATE_CONFIG_TOOL="${RPI_EEPROM_UPDATE_CONFIG_TOOL:-raspi-config}" RPI_EEPROM_UPDATE_CONFIG_TOOL="${RPI_EEPROM_UPDATE_CONFIG_TOOL:-raspi-config}"
# Automatic, critical updates are not applied unless the current bootloader version
# is older than pieeprom-2020-09-03
BOOTLOADER_AUTO_UPDATE_MIN_VERSION="${BOOTLOADER_AUTO_UPDATE_MIN_VERSION:-1599135103}"
DT_BOOTLOADER_TS=${DT_BOOTLOADER_TS:-/proc/device-tree/chosen/bootloader/build-timestamp} DT_BOOTLOADER_TS=${DT_BOOTLOADER_TS:-/proc/device-tree/chosen/bootloader/build-timestamp}
EXIT_SUCCESS=0 EXIT_SUCCESS=0
@@ -301,9 +305,7 @@ checkDependencies() {
BOARD_INFO="$(vcgencmd otp_dump | grep '30:' | sed 's/.*://')" BOARD_INFO="$(vcgencmd otp_dump | grep '30:' | sed 's/.*://')"
fi fi
if [ $(((0x$BOARD_INFO >> 23) & 1)) -ne 0 ] && [ $(((0x$BOARD_INFO >> 12) & 15)) -eq 3 ]; then if [ $(((0x$BOARD_INFO >> 23) & 1)) -eq 0 ] || [ $(((0x$BOARD_INFO >> 12) & 15)) -ne 3 ]; then
echo "BCM2711 detected"
else
# Not a BCM2711, no EEPROMs to update. # Not a BCM2711, no EEPROMs to update.
echo "This tool only works with a Raspberry Pi 4" echo "This tool only works with a Raspberry Pi 4"
exit ${EXIT_SUCCESS} exit ${EXIT_SUCCESS}
@@ -319,10 +321,8 @@ checkDependencies() {
fi fi
if [ ${BOARD_TYPE} -eq 17 ] && [ ${BOARD_REVISION} -lt 4 ]; then if [ ${BOARD_TYPE} -eq 17 ] && [ ${BOARD_REVISION} -lt 4 ]; then
echo "Dedicated VL805 EEPROM detected"
HAVE_VL805_EEPROM=1 HAVE_VL805_EEPROM=1
else else
echo "VL805 firmware in bootloader EEPROM"
HAVE_VL805_EEPROM=0 HAVE_VL805_EEPROM=0
fi fi
@@ -409,7 +409,11 @@ Options:
-l Returns the full path to the latest available EEPROM image file according -l Returns the full path to the latest available EEPROM image file according
to the FIRMWARE_RELEASE_STATUS and FIRMWARE_IMAGE_DIR settings. to the FIRMWARE_RELEASE_STATUS and FIRMWARE_IMAGE_DIR settings.
-m Write status information to the given file when run without -a or -f -m Write status information to the given file when run without -a or -f
-r Removes temporary EEPROM update files from the boot partition. -r Removes temporary EEPROM update files from the boot partition. This also
reverts a pending update.
-s Skips silent, automatic upgrades for default releases if the current
bootloader release is newer than the the version specified by
BOOTLOADER_AUTO_UPDATE_MIN_VERSION ${BOOTLOADER_AUTO_UPDATE_MIN_VERSION}
-u Install the specified VL805 (USB EEPROM) image file. -u Install the specified VL805 (USB EEPROM) image file.
Environment: Environment:
@@ -436,19 +440,18 @@ directory first. The binaries are then promoted to 'latest' and finally 'default
so the 'default' binary is always the most tested release. so the 'default' binary is always the most tested release.
default: default:
The default bootloader image which is updated once new features in The default bootloader image which supports all current models and hardware
'latest' are stable or for critical hardware or security updates. revisions.
If a critical bug fix is required then the minimum default version number
Raspberry Pi OS automatically updates the bootloader when a newer 'default' image (BOOTLOADER_AUTO_UPDATE_MIN_VERSION) in the rpi-eeprom package is updated
is available following an APT update to the rpi-eeprom package. causing the bootloader to be automatically updated.
latest: latest:
Contains the latest features which have undergone testing via the 'beta' Contains the latest features which have undergone testing via the 'beta'
release. The configuration parameters are stable. release. Backwards compatiblity for configuration parameters is maintained
once a feature is in the latest release directory.
beta: If the 'latest' release is selected then bootloader is automatically upgraded
Contains experimental features and bug fixes. Configuration parameters may when the rpi-eeprom package is updated.
change in subsequent 'beta' releases.
As far as rpi-eeprom-update is concerned FIRMWARE_RELEASE_STATUS is just As far as rpi-eeprom-update is concerned FIRMWARE_RELEASE_STATUS is just
the subdirectory mapping under ${FIRMWARE_ROOT}. Therefore, custom release the subdirectory mapping under ${FIRMWARE_ROOT}. Therefore, custom release
@@ -504,31 +507,35 @@ EOF
printVersions() printVersions()
{ {
echo "Checking for updates in ${FIRMWARE_IMAGE_DIR}"
echo "Use ${RPI_EEPROM_UPDATE_CONFIG_TOOL} to select either the default-production release or latest update."
if [ "${ACTION_UPDATE_BOOTLOADER}" = 1 ]; then if [ "${ACTION_UPDATE_BOOTLOADER}" = 1 ]; then
echo "BOOTLOADER: update available" echo "BOOTLOADER: update available"
else else
echo "BOOTLOADER: up-to-date" echo "BOOTLOADER: up-to-date"
fi fi
echo "CURRENT: $(date -u "-d@${BOOTLOADER_CURRENT_VERSION}") (${BOOTLOADER_CURRENT_VERSION})" echo " CURRENT: $(date -u "-d@${BOOTLOADER_CURRENT_VERSION}") (${BOOTLOADER_CURRENT_VERSION})"
echo " LATEST: $(date -u "-d@${BOOTLOADER_UPDATE_VERSION}") (${BOOTLOADER_UPDATE_VERSION})" echo " LATEST: $(date -u "-d@${BOOTLOADER_UPDATE_VERSION}") (${BOOTLOADER_UPDATE_VERSION})"
echo "RELEASE: ${FIRMWARE_RELEASE_STATUS}" echo " RELEASE: ${FIRMWARE_RELEASE_STATUS} (${FIRMWARE_IMAGE_DIR})"
echo " Use ${RPI_EEPROM_UPDATE_CONFIG_TOOL} to change the release."
echo ""
if [ "${HAVE_VL805_EEPROM}" = 1 ]; then
echo " VL805_FW: Dedicated VL805 EEPROM"
else
echo " VL805_FW: Using bootloader EEPROM"
fi
if [ "${ACTION_UPDATE_VL805}" = 1 ]; then if [ "${ACTION_UPDATE_VL805}" = 1 ]; then
echo "VL805: update available" echo " VL805: update available"
else else
if [ "$(id -u)" = "0" ]; then if [ "$(id -u)" = "0" ]; then
echo "VL805: up-to-date" echo " VL805: up-to-date"
else else
echo "VL805: version unknown. Try sudo rpi-eeprom-update" echo " VL805: version unknown. Try sudo rpi-eeprom-update"
fi fi
fi fi
echo "CURRENT: ${VL805_CURRENT_VERSION}" echo " CURRENT: ${VL805_CURRENT_VERSION}"
echo " LATEST: ${VL805_UPDATE_VERSION}" echo " LATEST: ${VL805_UPDATE_VERSION}"
} }
findBootFS() findBootFS()
@@ -591,12 +598,30 @@ lookupVersionInfo()
getVL805CurrentVersion getVL805CurrentVersion
ACTION_UPDATE_BOOTLOADER=0
ACTION_UPDATE_VL805=0
if [ "${BOOTLOADER_UPDATE_VERSION}" -gt "${BOOTLOADER_CURRENT_VERSION}" ]; then if [ "${BOOTLOADER_UPDATE_VERSION}" -gt "${BOOTLOADER_CURRENT_VERSION}" ]; then
ACTION_UPDATE_BOOTLOADER=1 ACTION_UPDATE_BOOTLOADER=1
else else
BOOTLOADER_UPDATE_IMAGE="" BOOTLOADER_UPDATE_IMAGE=""
fi fi
# If the '-s' flag for silent updates is specified then only update the
# bootloader if the current version is older than the minimum version.
if [ "${SILENT_UPDATE}" = 1 ] && [ -n "${BOOTLOADER_AUTO_UPDATE_MIN_VERSION}" ] && [ "${ACTION_UPDATE_BOOTLOADER}" = 1 ]; then
if [ "${FIRMWARE_RELEASE_STATUS}" = "critical" ] || [ "${FIRMWARE_RELEASE_STATUS}" = "default" ]; then
if [ "${BOOTLOADER_CURRENT_VERSION}" -ge "${BOOTLOADER_AUTO_UPDATE_MIN_VERSION}" ]; then
echo "Skipping automatic bootloader upgrade. current ${BOOTLOADER_CURRENT_VERSION} >= min ${BOOTLOADER_AUTO_UPDATE_MIN_VERSION}"
echo ""
# Clear the update requried flag
ACTION_UPDATE_BOOTLOADER=0
BOOTLOADER_UPDATE_IMAGE=""
fi
fi
fi
if [ "${HAVE_VL805_EEPROM}" = 1 ]; then if [ "${HAVE_VL805_EEPROM}" = 1 ]; then
getVL805UpdateVersion getVL805UpdateVersion
if [ -n "${VL805_CURRENT_VERSION}" ] && [ -n "${VL805_UPDATE_VERSION}" ]; then if [ -n "${VL805_CURRENT_VERSION}" ] && [ -n "${VL805_UPDATE_VERSION}" ]; then
@@ -629,9 +654,13 @@ checkAndApply()
if [ "${ACTION_UPDATE_BOOTLOADER}" = 1 ] || [ "${ACTION_UPDATE_VL805}" = 1 ]; then if [ "${ACTION_UPDATE_BOOTLOADER}" = 1 ] || [ "${ACTION_UPDATE_VL805}" = 1 ]; then
echo "*** INSTALLING EEPROM UPDATES ***" echo "*** INSTALLING EEPROM UPDATES ***"
echo ""
printVersions printVersions
applyUpdate applyUpdate
echo ""
echo "EEPROM updates pending. Please reboot to apply the update." echo "EEPROM updates pending. Please reboot to apply the update."
echo "To cancel a pending update run \"sudo rpi-eeprom-update -r\"."
else else
printVersions printVersions
fi fi
@@ -676,7 +705,7 @@ checkVersion()
{ {
lookupVersionInfo lookupVersionInfo
if [ "${BOOTLOADER_UPDATE_VERSION}" -gt "${BOOTLOADER_CURRENT_VERSION}" ]; then if [ "${ACTION_UPDATE_BOOTLOADER}" = 1 ] || [ "${ACTION_UPDATE_VL805}" = 1 ]; then
echo "*** UPDATE AVAILABLE ***" echo "*** UPDATE AVAILABLE ***"
printVersions printVersions
write_status_info "EXIT_UPDATE_REQUIRED" write_status_info "EXIT_UPDATE_REQUIRED"
@@ -697,11 +726,13 @@ write_status_info()
bootloader_new="${BOOTLOADER_UPDATE_VERSION:-0}" bootloader_new="${BOOTLOADER_UPDATE_VERSION:-0}"
vl805_cur="${VL805_CURRENT_VERSION}" vl805_cur="${VL805_CURRENT_VERSION}"
vl805_new="${VL805_UPDATE_VERSION}" vl805_new="${VL805_UPDATE_VERSION}"
min_ver=${BOOTLOADER_AUTO_UPDATE_MIN_VERSION:-0}
if [ "${JSON_OUTPUT}" = "no" ]; then if [ "${JSON_OUTPUT}" = "no" ]; then
[ "${HAVE_VL805_EEPROM}" = "0" ] && vl805_eeprom="no" || vl805_eeprom="yes" [ "${HAVE_VL805_EEPROM}" = "0" ] && vl805_eeprom="no" || vl805_eeprom="yes"
cat > "${MACHINE_OUTPUT}" <<EOF cat > "${MACHINE_OUTPUT}" <<EOF
EXITCODE="${exit_code}" EXITCODE="${exit_code}"
BOOTLOADER_AUTO_UPDATE_MIN_VERSION=${min_ver}
BOOTLOADER_CURRENT=${bootloader_cur} BOOTLOADER_CURRENT=${bootloader_cur}
BOOTLOADER_LATEST=${bootloader_new} BOOTLOADER_LATEST=${bootloader_new}
VL805_CURRENT="${vl805_cur}" VL805_CURRENT="${vl805_cur}"
@@ -713,6 +744,7 @@ EOF
cat > "${MACHINE_OUTPUT}" <<EOF cat > "${MACHINE_OUTPUT}" <<EOF
{ {
"EXITCODE": "${exit_code}", "EXITCODE": "${exit_code}",
"BOOTLOADER_AUTO_UPDATE_MIN_VERSION": ${min_ver},
"BOOTLOADER_CURRENT": ${bootloader_cur}, "BOOTLOADER_CURRENT": ${bootloader_cur},
"BOOTLOADER_LATEST": ${bootloader_new}, "BOOTLOADER_LATEST": ${bootloader_new},
"VL805_CURRENT": "${vl805_cur}", "VL805_CURRENT": "${vl805_cur}",
@@ -726,6 +758,7 @@ EOF
AUTO_UPDATE_BOOTLOADER=0 AUTO_UPDATE_BOOTLOADER=0
AUTO_UPDATE_VL805=0 AUTO_UPDATE_VL805=0
SILENT_UPDATE=0
MACHINE_OUTPUT="" MACHINE_OUTPUT=""
JSON_OUTPUT="no" JSON_OUTPUT="no"
IGNORE_DPKG_CHECKSUMS=${LOCAL_MODE} IGNORE_DPKG_CHECKSUMS=${LOCAL_MODE}
@@ -735,7 +768,7 @@ if [ ! -d "${PACKAGE_INFO_DIR}" ]; then
fi fi
while getopts A:abdhilf:m:ju:r option; do while getopts A:abdhilf:m:ju:rs option; do
case "${option}" in case "${option}" in
A) A)
if [ "${OPTARG}" = "bootloader" ]; then if [ "${OPTARG}" = "bootloader" ]; then
@@ -776,6 +809,8 @@ while getopts A:abdhilf:m:ju:r option; do
removePreviousUpdates removePreviousUpdates
exit 0 exit 0
;; ;;
s) SILENT_UPDATE=1
;;
u) VL805_UPDATE_IMAGE="${OPTARG}" u) VL805_UPDATE_IMAGE="${OPTARG}"
;; ;;
*) echo "Unknown argument \"${option}\"" *) echo "Unknown argument \"${option}\""
@@ -787,7 +822,7 @@ done
checkDependencies checkDependencies
if [ "${AUTO_UPDATE_BOOTLOADER}" = 1 ] || [ "${AUTO_UPDATE_VL805}" = 1 ]; then if [ "${AUTO_UPDATE_BOOTLOADER}" = 1 ] || [ "${AUTO_UPDATE_VL805}" = 1 ]; then
if getBootloaderConfig | grep FREEZE_VERSION=1; then if getBootloaderConfig | grep FREEZE_VERSION=1; then
echo "EEPROM version is frozen. Skipping update" echo "EEPROM version is frozen. Skipping automatic update"
exit ${EXIT_EEPROM_FROZEN} exit ${EXIT_EEPROM_FROZEN}
else else
checkAndApply checkAndApply