mirror of
https://github.com/raspberrypi/rpi-eeprom.git
synced 2026-01-21 06:13:33 +08:00
Make up-to-date message specific to bootloader or vl805 and indicate if the tool was not run as root.
587 lines
19 KiB
Bash
Executable File
587 lines
19 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# Raspberry Pi4 boot EEPROM updater.
|
|
|
|
set -e
|
|
|
|
script_dir=$(cd "$(dirname "$0")" && pwd)
|
|
|
|
if [ -f /etc/default/rpi-eeprom-update ]; then
|
|
. /etc/default/rpi-eeprom-update
|
|
fi
|
|
|
|
FIRMWARE_ROOT=${FIRMWARE_ROOT:-/lib/firmware/raspberrypi/bootloader}
|
|
# May be used to select beta releases instead of the default critical
|
|
# updates.
|
|
FIRMWARE_RELEASE_STATUS=${FIRMWARE_RELEASE_STATUS:-critical}
|
|
FIRMWARE_IMAGE_DIR=${FIRMWARE_IMAGE_DIR:-${FIRMWARE_ROOT}/${FIRMWARE_RELEASE_STATUS}}
|
|
FIRMWARE_BACKUP_DIR=${FIRMWARE_BACKUP_DIR:-/var/lib/raspberrypi/bootloader/backup}
|
|
ENABLE_VL805_UPDATES=${ENABLE_VL805_UPDATES:-1}
|
|
USE_FLASHROM=${USE_FLASHROM:-0}
|
|
RECOVERY_BIN=${RECOVERY_BIN:-${FIRMWARE_ROOT}/${FIRMWARE_RELEASE_STATUS}/recovery.bin}
|
|
BOOTFS=${BOOTFS:-/boot}
|
|
|
|
EXIT_SUCCESS=0
|
|
EXIT_UPDATE_REQUIRED=1
|
|
EXIT_FAILED=2
|
|
EXIT_EEPROM_FROZEN=3
|
|
# Reserved
|
|
# EXIT_PREVIOUS_UPDATE_FAILED=4
|
|
|
|
OVERWRITE_CONFIG=0
|
|
# Maximum safe SPI speed for EEPROM access 16000, slower is ok.
|
|
SPI_SPEED=16000
|
|
# Timestamp for first release which doesn't have a timestamp field
|
|
BOOTLOADER_FIRST_VERSION=1557513636
|
|
EEPROM_SIZE=524288
|
|
|
|
# Simple bootloader which is able to load start.elf in the event of a power
|
|
# cut. This runs SDRAM at low speed and may have reduced functionality but
|
|
# should be enough to run flashrom again.
|
|
|
|
TMP_EEPROM_IMAGE=""
|
|
TMP_BOOTFS_MNT=""
|
|
|
|
VL805_CURRENT_VERSION=
|
|
VL805_UPDATE_VERSION=
|
|
|
|
# The update actions selected by the version check
|
|
ACTION_UPDATE_BOOTLOADER=0
|
|
ACTION_UPDATE_VL805=0
|
|
|
|
cleanup() {
|
|
if [ -f "${TMP_EEPROM_IMAGE}" ]; then
|
|
rm -f "${TMP_EEPROM_IMAGE}"
|
|
fi
|
|
if [ -f "${TMP_EEPROM_CONFIG}" ]; then
|
|
rm -f "${TMP_EEPROM_CONFIG}"
|
|
fi
|
|
if [ -d "${TMP_BOOTFS_MNT}" ]; then
|
|
umount "${TMP_BOOTFS_MNT}"
|
|
rmdir "${TMP_BOOTFS_MNT}"
|
|
fi
|
|
TMP_BOOTFS_MNT=
|
|
TMP_EEPROM_IMAGE=
|
|
TMP_EEPROM_CONFIG=
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
die() {
|
|
echo "$@" >&2
|
|
exit ${EXIT_FAILED}
|
|
}
|
|
|
|
prepareImage()
|
|
{
|
|
[ -f "${BOOTLOADER_UPDATE_IMAGE}" ] || die "EEPROM image \'${BOOTLOADER_UPDATE_IMAGE}\' not found"
|
|
TMP_EEPROM_IMAGE="$(mktemp)"
|
|
TMP_EEPROM_CONFIG="$(mktemp)"
|
|
|
|
mkdir -p "${FIRMWARE_BACKUP_DIR}"
|
|
|
|
# Backup the configuration of the currently loaded bootloader
|
|
vcgencmd bootloader_config > "${TMP_EEPROM_CONFIG}"
|
|
backup="${FIRMWARE_BACKUP_DIR}/pieeprom-backup-$(date +%Y%m%d-%H%M%S).conf"
|
|
cp -f "${TMP_EEPROM_CONFIG}" "${backup}"
|
|
|
|
if [ "$(wc -l "${TMP_EEPROM_CONFIG}" | awk '{print $1}')" -lt 3 ]; then
|
|
# Don't propagate empty EEPROM config files and also prevent the initial
|
|
# bootloader config with WAKE_ON_GPIO=0 propgating to newer versions by
|
|
# accident.
|
|
OVERWRITE_CONFIG=1
|
|
fi
|
|
|
|
cp -f "${BOOTLOADER_UPDATE_IMAGE}" "${TMP_EEPROM_IMAGE}"
|
|
|
|
if [ "${OVERWRITE_CONFIG}" = 0 ]; then
|
|
"${script_dir}/rpi-eeprom-config" \
|
|
--out "${TMP_EEPROM_IMAGE}" \
|
|
--config "${TMP_EEPROM_CONFIG}" "${BOOTLOADER_UPDATE_IMAGE}"
|
|
fi
|
|
}
|
|
|
|
applyRecoveryUpdate()
|
|
{
|
|
[ -n "${BOOTLOADER_UPDATE_IMAGE}" ] || [ -n "${VL805_UPDATE_IMAGE}" ] || die "No update images specified"
|
|
|
|
findBootFS
|
|
|
|
# A '.sig' file is created so that recovery.bin can check that the
|
|
# EEPROM image has not been created (e.g. SD card corruption).
|
|
# The .sig file format is currently just a SHA256 in ASCII hex. In future,
|
|
# if an actual public key signature is required then that plus any other
|
|
# data would be appended after the SHA256 signature.
|
|
if [ -n "${BOOTLOADER_UPDATE_IMAGE}" ]; then
|
|
[ -f "${BOOTLOADER_UPDATE_IMAGE}" ] || die "${BOOTLOADER_UPDATE_IMAGE} not found"
|
|
|
|
TMP_EEPROM_IMAGE="$(mktemp)"
|
|
prepareImage
|
|
# If recovery.bin encounters pieeprom.upd then it will select it in
|
|
# preference to pieeprom.bin. The .upd file also causes recovery.bin
|
|
# to rename itself to recovery.000 and reboot if the update is successful.
|
|
# The rename causes the ROM to ignore this file and use the newly flashed
|
|
# EEPROM image instead.
|
|
sha256sum "${TMP_EEPROM_IMAGE}" | awk '{print $1}' > "${BOOTFS}/pieeprom.sig" \
|
|
|| die "Failed to create ${BOOTFS}/pieeprom.sig"
|
|
|
|
cp -f "${TMP_EEPROM_IMAGE}" "${BOOTFS}/pieeprom.upd" \
|
|
|| die "Failed to copy ${TMP_EEPROM_IMAGE} to ${BOOTFS}"
|
|
fi
|
|
|
|
if [ -n "${VL805_UPDATE_IMAGE}" ]; then
|
|
sha256sum "${VL805_UPDATE_IMAGE}" | awk '{print $1}' > "${BOOTFS}/vl805.sig" \
|
|
|| die "Failed to create ${BOOTFS}/vl805.sig"
|
|
cp -f "${VL805_UPDATE_IMAGE}" "${BOOTFS}/vl805.bin"
|
|
fi
|
|
|
|
cp -f "${RECOVERY_BIN}" "${BOOTFS}/recovery.bin" \
|
|
|| die "Failed to copy ${RECOVERY_BIN} to ${BOOTFS}"
|
|
}
|
|
|
|
applyUpdate() {
|
|
checksums_file="/var/lib/dpkg/info/rpi-eeprom-images.md5sums"
|
|
|
|
[ "$(id -u)" = "0" ] || die "* Must be run as root - try 'sudo rpi-eeprom-update'"
|
|
|
|
if [ "${IGNORE_DPKG_CHECKSUMS}" = 0 ] && [ -f "${checksums_file}" ]; then
|
|
(
|
|
cd /
|
|
if ! md5sum -c "${checksums_file}" > /dev/null 2>&1; then
|
|
md5sum -c "${checksums_file}"
|
|
die "rpi-eeprom-images checksums failed - try reinstalling this package"
|
|
fi
|
|
)
|
|
fi
|
|
|
|
if [ "${USE_FLASHROM}" = 0 ]; then
|
|
applyRecoveryUpdate
|
|
return
|
|
fi
|
|
|
|
if [ -f "${BOOTLOADER_UPDATE_IMAGE}" ]; then
|
|
# Bootloader EEPROM chip-select is muxed with audio pin so disable audio
|
|
# LDO first to avoid sending noise to analog audio.
|
|
/opt/vc/bin/vcmailbox 0x00030056 4 4 0 > /dev/null || true
|
|
dtparam audio=off
|
|
|
|
# Switch the SPI pins to boot EEPROM
|
|
dtoverlay spi-gpio40-45
|
|
modprobe spidev
|
|
modprobe spi-bcm2835
|
|
|
|
prepareImage "${BOOTLOADER_UPDATE_IMAGE}"
|
|
|
|
echo "Applying bootloaer update ${BOOTLOADER_UPDATE_IMAGE}"
|
|
flashrom -p "linux_spi:dev=/dev/spidev0.0,spispeed=${SPI_SPEED}" -w "${TMP_EEPROM_IMAGE}" || die "flashrom EEPROM update failed"
|
|
|
|
dtparam -R spi-gpio40-45
|
|
dtparam audio=on
|
|
/opt/vc/bin/vcmailbox 0x00030056 4 4 1 > /dev/null || true
|
|
fi
|
|
|
|
if [ -f "${VL805_UPDATE_IMAGE}" ]; then
|
|
echo "Applying VL805 image ${VL805_UPDATE_IMAGE}"
|
|
vl805 -w "${VL805_UPDATE_IMAGE}"
|
|
fi
|
|
|
|
echo "Applying bootloader update ${BOOTLOADER_UPDATE_IMAGE}"
|
|
}
|
|
|
|
# Use the version reported by the loaded EEPROM instead of attempting to retrieve
|
|
# this via flashrom to avoid unnecessary audio glitches.
|
|
BOOTLOADER_CURRENT_VERSION=
|
|
getBootloaderCurrentVersion() {
|
|
if vcgencmd bootloader_version | grep -q timestamp; then
|
|
BOOTLOADER_CURRENT_VERSION=$(vcgencmd bootloader_version | grep timestamp | awk '{print $2}')
|
|
if [ "${BOOTLOADER_CURRENT_VERSION}" = "0" ]; then
|
|
# If a timestamp of zero is returned then it's new firmware but an
|
|
# old bootloader. Assume bootloader v0
|
|
BOOTLOADER_CURRENT_VERSION="${BOOTLOADER_FIRST_VERSION}"
|
|
fi
|
|
else
|
|
# New bootloader / old firmware ? Try to parse the date
|
|
BOOTLOADER_CURRENT_VERSION=$(date -u +%s --date "$(vcgencmd bootloader_version | head -n1)" 2>/dev/null || true)
|
|
fi
|
|
|
|
# Failed to parse the version. Default to the initial production release.
|
|
if [ -z "${BOOTLOADER_CURRENT_VERSION}" ]; then
|
|
BOOTLOADER_CURRENT_VERSION="${BOOTLOADER_FIRST_VERSION}"
|
|
fi
|
|
}
|
|
|
|
# Find latest applicable update version
|
|
BOOTLOADER_UPDATE_IMAGE=""
|
|
BOOTLOADER_UPDATE_VERSION=0
|
|
getBootloaderUpdateVersion() {
|
|
BOOTLOADER_UPDATE_VERSION=0
|
|
match=".*/pieeprom-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9].bin"
|
|
latest="$(find "${FIRMWARE_IMAGE_DIR}" -maxdepth 1 -type f -size "${EEPROM_SIZE}c" -regex "${match}" | sort -r | head -n1)"
|
|
if [ -f "${latest}" ]; then
|
|
BOOTLOADER_UPDATE_VERSION=$(strings "${latest}" | grep BUILD_TIMESTAMP | sed 's/.*=//g')
|
|
BOOTLOADER_UPDATE_IMAGE="${latest}"
|
|
fi
|
|
}
|
|
|
|
checkDependencies() {
|
|
CPU_VER="$(vcgencmd otp_dump | grep 30: | cut -c8)"
|
|
|
|
if [ "${CPU_VER}" != "3" ]; then
|
|
# Not a BCM2711, no EEPROMs to update.
|
|
exit ${EXIT_SUCCESS}
|
|
fi
|
|
|
|
if [ ! -d "${FIRMWARE_IMAGE_DIR}" ]; then
|
|
die "EEPROM updates directory ${FIRMWARE_IMAGE_DIR} not found."
|
|
fi
|
|
|
|
if ! command -v vl805 -h > /dev/null 2>&1; then
|
|
die "vl805 command not found"
|
|
fi
|
|
|
|
if vcgencmd bootloader_config | grep -qi "Command not registered"; then
|
|
die "vcgencmd: 'bootloader_config' command not supported. Please update VC firmware and reboot."
|
|
fi
|
|
|
|
if ! command -v sha256sum > /dev/null 2>&1; then
|
|
die "sha256sum not found. On Debian, try installing the coreutilities package"
|
|
fi
|
|
|
|
if ! command -v flashrom > /dev/null 2>&1; then
|
|
[ "${USE_FLASHROM}" = 0 ] || die "flashrom not found. On Debian, try installing the flashrom package."
|
|
fi
|
|
|
|
if [ "${USE_FLASHROM}" = 0 ]; then
|
|
[ -f "${RECOVERY_BIN}" ] || die "${RECOVERY_BIN} not found."
|
|
fi
|
|
}
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
rpi-eeprom-update [options]... [FILE]
|
|
Checks whether the Raspberry Pi bootloader and the VL805 USB controller
|
|
EEPROMs are up-to-date and optionally updates the EEPROMs at the next reboot.
|
|
|
|
The default update mechanism writes recovery.bin and the EEPROM update
|
|
image(s) (pieeprom.upd and vl805.bin) to the boot partition on the sd-card.
|
|
The SHA256 hash of the corresponding images are written to pieeprom.sig
|
|
and/or vl805.sig. This guards against file system corruption which could
|
|
cause the EEPROM to be flashed with an invalid image. This is is not a
|
|
security check.
|
|
|
|
At the next reboot the ROM runs recovery.bin which updates EEPROM(s).
|
|
If the update was successful recovery.bin renames itself to recovery.000
|
|
to prevent it from running a second time then resets the system.
|
|
The system should then boot normally.
|
|
|
|
If /boot does not correspond to the boot partition on the sd-card and this
|
|
is not a NOOBS system then the mount point for BOOTFS should be defined
|
|
in /etc/default/rpi-eeprom-update by defining the BOOTFS variable.
|
|
|
|
For reference, the flashrom update mechanism may be enabled by defining
|
|
USE_FLASHROM=1 in /etc/default/rpi-eeprom-update. This not recommended
|
|
because the SPI pins are muxed with audio and other device drivers may
|
|
be using SPI (e.g. HATs). This is also not safe in the event of a power
|
|
failure during the update of the EEPROM.
|
|
|
|
A backup of the current EEPROM config file is written to ${FIRMWARE_BACKUP_DIR}
|
|
before applying the update.
|
|
|
|
-a Automatically install bootloader and USB (VLI) EEPROM updates.
|
|
-A Specify which type of EEPROM to automatically update (vl805 or bootloader)
|
|
-d Use the default bootloader config instead of migrating the current settings
|
|
-f Install the given file instead of the latest applicable update
|
|
Ignores the FREEZE_VERSION flag in bootloader and is intended for manual
|
|
firmware updates.
|
|
WARNING: This command should only be run from console mode in order to
|
|
avoid conflicts/deadlock with dtoverlay/dtparam settings.
|
|
-h Display help text and exit
|
|
-i Ignore package checksums - for rpi-eeprom developers.
|
|
-j Write status information using JSON notation
|
|
-m Write status information to the given file when run without -a or -f
|
|
-r Removes temporary EEPROM update files from the boot partition.
|
|
-u Install the specified VL805 (USB EEPROM) image file.
|
|
|
|
To extract the configuration file from an EEPROM image:
|
|
rpi-eeprom-config pieeprom.bin --out bootconf.txt
|
|
|
|
To update the configuration file in an EEPROM image:
|
|
rpi-eeprom-config pieeprom.bin --config bootconf.txt --out pieeprom-new.bin
|
|
|
|
To flash the new image:
|
|
sudo rpi-eeprom-update -d -f ./pieeprom-new.bin
|
|
|
|
The syntax is the same as config.txt but section filters etc are not supported. See
|
|
online documentation for the list of parameters.
|
|
|
|
The official documentation for the Raspberry Pi bootloader EEPROM is available at
|
|
https://www.raspberrypi.org/documentation/hardware/raspberrypi/booteeprom.md
|
|
|
|
EOF
|
|
exit ${EXIT_SUCCESS}
|
|
}
|
|
|
|
printVersions()
|
|
{
|
|
if [ "${ACTION_UPDATE_BOOTLOADER}" = 1 ]; then
|
|
echo "BOOTLOADER: update required"
|
|
else
|
|
echo "BOOTLOADER: up-to-date"
|
|
fi
|
|
|
|
echo "CURRENT: $(date -u "-d@${BOOTLOADER_CURRENT_VERSION}") (${BOOTLOADER_CURRENT_VERSION})"
|
|
echo " LATEST: $(date -u "-d@${BOOTLOADER_UPDATE_VERSION}") (${BOOTLOADER_UPDATE_VERSION})"
|
|
|
|
if [ "${ACTION_UPDATE_VL805}" = 1 ]; then
|
|
echo "VL805: update required"
|
|
else
|
|
if [ "$(id -u)" = "0" ]; then
|
|
echo "VL805: up-to-date"
|
|
else
|
|
echo "VL805: version unknown. Try sudo rpi-eeprom-update"
|
|
fi
|
|
fi
|
|
|
|
echo "CURRENT: ${VL805_CURRENT_VERSION}"
|
|
echo " LATEST: ${VL805_UPDATE_VERSION}"
|
|
}
|
|
|
|
findBootFS()
|
|
{
|
|
# recovery.bin is loaded by the ROM from the boot partition, this is normally
|
|
# ${BOOTFS} but on NOOBS this is /dev/mmcblk0p1 with volume label RECOVERY
|
|
# If ${BOOTFS} is not writable OR is not on /dev/mmcblk0 then error because the ROM
|
|
# can only load recovery.bin from the on-board SD-CARD slot or the EEPROM.
|
|
|
|
if blkid | grep -qE "/dev/mmcblk0p1.*LABEL_FATBOOT.*RECOVERY.*TYPE.*vfat"; then
|
|
TMP_BOOTFS_MNT="$(mktemp -d)"
|
|
mount /dev/mmcblk0p1 "${TMP_BOOTFS_MNT}"
|
|
BOOTFS="${TMP_BOOTFS_MNT}"
|
|
fi
|
|
|
|
# If BOOTFS is not a directory or doesn't contain any .elf files then
|
|
# it's probably not the boot partition.
|
|
[ -d "${BOOTFS}" ] || die "BOOTFS: \"${BOOTFS}\" is not a directory"
|
|
[ "$(find "${BOOTFS}/" -name "*.elf" | wc -l)" -gt 0 ] || die "BOOTFS: \"${BOOTFS}\" contains no .elf files"
|
|
}
|
|
|
|
getVL805CurrentVersion()
|
|
{
|
|
# The version number is obtained by examing a section of PCI config
|
|
# space which is only accessible as root. If the command is not run as
|
|
# root then treat the version as unknown and skip VLI updates.
|
|
VL805_CURRENT_VERSION=""
|
|
if [ "$(id -u)" = "0" ]; then
|
|
if vl805 | grep -q "VL805 FW version"; then
|
|
VL805_CURRENT_VERSION=$(vl805 | grep "VL805 FW version" | awk '{print $4}')
|
|
fi
|
|
fi
|
|
}
|
|
|
|
getVL805UpdateVersion()
|
|
{
|
|
# The latest VL805 version is indicated by a file containing the version
|
|
# number. If the version file exists then verify that the corresponding
|
|
# VL805 binary exists before selecting it.
|
|
# There are no user modifiable sections in the VL805 firmware and there
|
|
# are unlikely to be many updates to it so just indicate the latest supported
|
|
# version. This also avoids making any assumptions about the VLI version numbers.
|
|
VL805_UPDATE_VERSION=""
|
|
if [ -f "${FIRMWARE_IMAGE_DIR}/vl805.latest" ]; then
|
|
ver="$(cat "${FIRMWARE_IMAGE_DIR}/vl805.latest")"
|
|
if [ -f "${FIRMWARE_IMAGE_DIR}/vl805-${ver}.bin" ]; then
|
|
VL805_UPDATE_VERSION="${ver}"
|
|
VL805_UPDATE_IMAGE="${FIRMWARE_IMAGE_DIR}/vl805-${ver}.bin"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Retrieve the version information and determine whether newer
|
|
# versions are available.
|
|
lookupVersionInfo()
|
|
{
|
|
getBootloaderCurrentVersion
|
|
getBootloaderUpdateVersion
|
|
|
|
getVL805CurrentVersion
|
|
getVL805UpdateVersion
|
|
|
|
if [ "${BOOTLOADER_UPDATE_VERSION}" -gt "${BOOTLOADER_CURRENT_VERSION}" ]; then
|
|
ACTION_UPDATE_BOOTLOADER=1
|
|
else
|
|
BOOTLOADER_UPDATE_IMAGE=""
|
|
fi
|
|
|
|
if [ -n "${VL805_CURRENT_VERSION}" ] && [ -n "${VL805_UPDATE_VERSION}" ]; then
|
|
if [ "${VL805_CURRENT_VERSION}" != "${VL805_UPDATE_VERSION}" ]; then
|
|
ACTION_UPDATE_VL805=1
|
|
else
|
|
VL805_UPDATE_IMAGE=""
|
|
fi
|
|
fi
|
|
}
|
|
|
|
checkAndApply()
|
|
{
|
|
lookupVersionInfo
|
|
removePreviousUpdates
|
|
|
|
# Restrict the automatic updates to the EEPROM types selected by the -A option.
|
|
if [ "${AUTO_UPDATE_VL805}" != 1 ]; then
|
|
ACTION_UPDATE_VL805=0
|
|
VL805_UPDATE_IMAGE=""
|
|
fi
|
|
if [ "${AUTO_UPDATE_BOOTLOADER}" != 1 ]; then
|
|
ACTION_UPDATE_BOOTLOADER=0
|
|
BOOTLOADER_UPDATE_IMAGE=""
|
|
fi
|
|
|
|
if [ "${ACTION_UPDATE_BOOTLOADER}" = 1 ] || [ "${ACTION_UPDATE_VL805}" = 1 ]; then
|
|
echo "*** INSTALLING EEPROM UPDATES ***"
|
|
printVersions
|
|
applyUpdate
|
|
echo "EEPROM updates pending. Please reboot to apply the update."
|
|
else
|
|
printVersions
|
|
fi
|
|
}
|
|
|
|
fileUpdate()
|
|
{
|
|
removePreviousUpdates
|
|
echo "*** INSTALLING ${BOOTLOADER_UPDATE_IMAGE} ${VL805_UPDATE_IMAGE} ***"
|
|
|
|
if [ -n "${BOOTLOADER_UPDATE_IMAGE}" ]; then
|
|
[ -f "${BOOTLOADER_UPDATE_IMAGE}" ] || die "Bootloader image \"${BOOTLOADER_UPDATE_IMAGE}\" not found"
|
|
fi
|
|
|
|
if [ -n "${VL805_UPDATE_IMAGE}" ]; then
|
|
[ -f "${VL805_UPDATE_IMAGE}" ] || die "VL805 image \"${VL805_UPDATE_IMAGE}\" not found"
|
|
fi
|
|
|
|
applyUpdate
|
|
echo "EEPROM update pending. Please reboot to apply the update."
|
|
}
|
|
|
|
removePreviousUpdates()
|
|
{
|
|
if [ "$(id -u)" = "0" ]; then
|
|
findBootFS
|
|
|
|
# Remove any stale recovery.bin files or EEPROM images
|
|
# N.B. recovery.bin is normally ignored by the ROM if is not a valid
|
|
# executable but it's best to not have the file at all.
|
|
rm -f "${BOOTFS}/recovery.bin"
|
|
rm -f "${BOOTFS}/pieeprom.bin" "${BOOTFS}/pieeprom.upd" "${BOOTFS}/pieeprom.sig"
|
|
rm -f "${BOOTFS}/vl805.bin" "${BOOTFS}/vl805.sig"
|
|
# Case insensitive for FAT bootfs
|
|
find "${BOOTFS}" -maxdepth 1 -type f -iname "recovery.*" -regex '.*\.[0-9][0-9][0-9]$' -exec rm -f {} \;
|
|
fi
|
|
}
|
|
|
|
checkVersion()
|
|
{
|
|
lookupVersionInfo
|
|
|
|
if [ "${BOOTLOADER_UPDATE_VERSION}" -gt "${BOOTLOADER_CURRENT_VERSION}" ]; then
|
|
echo "*** UPDATE REQUIRED ***"
|
|
printVersions
|
|
write_status_info "EXIT_UPDATE_REQUIRED"
|
|
exit ${EXIT_UPDATE_REQUIRED}
|
|
else
|
|
printVersions
|
|
write_status_info "EXIT_SUCCESS"
|
|
exit ${EXIT_SUCCESS}
|
|
fi
|
|
}
|
|
|
|
write_status_info()
|
|
{
|
|
[ -z "${MACHINE_OUTPUT}" ] && return 0
|
|
|
|
exit_code="${1:-EXIT_FAILED}"
|
|
bootloader_cur="${BOOTLOADER_CURRENT_VERSION:-0}"
|
|
bootloader_new="${BOOTLOADER_UPDATE_VERSION:-0}"
|
|
vl805_cur="${VL805_CURRENT_VERSION}"
|
|
vl805_new="${VL805_UPDATE_VERSION}"
|
|
|
|
if [ "${JSON_OUTPUT}" = "no" ]; then
|
|
cat > "${MACHINE_OUTPUT}" <<EOF
|
|
EXITCODE="${exit_code}"
|
|
BOOTLOADER_CURRENT=${bootloader_cur}
|
|
BOOTLOADER_LATEST=${bootloader_new}
|
|
VL805_CURRENT="${vl805_cur}"
|
|
VL805_LATEST="${vl805_new}"
|
|
EOF
|
|
else
|
|
cat > "${MACHINE_OUTPUT}" <<EOF
|
|
{
|
|
"EXITCODE": "${exit_code}",
|
|
"BOOTLOADER_CURRENT": ${bootloader_cur},
|
|
"BOOTLOADER_LATEST": ${bootloader_new},
|
|
"VL805_CURRENT": "${vl805_cur}",
|
|
"VL805_LATEST": "${vl805_new}"
|
|
}
|
|
EOF
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
AUTO_UPDATE_BOOTLOADER=0
|
|
AUTO_UPDATE_VL805=0
|
|
MACHINE_OUTPUT=""
|
|
JSON_OUTPUT="no"
|
|
IGNORE_DPKG_CHECKSUMS=0
|
|
|
|
while getopts A:adhif:m:ju:r option; do
|
|
case "${option}" in
|
|
A)
|
|
if [ "${OPTARG}" = "bootloader" ]; then
|
|
AUTO_UPDATE_BOOTLOADER=1
|
|
elif [ "${OPTARG}" = "vl805" ]; then
|
|
AUTO_UPDATE_VL805=1
|
|
else
|
|
die "Unknown update mode: ${OPTARG}"
|
|
fi
|
|
;;
|
|
a) AUTO_UPDATE_BOOTLOADER=1
|
|
AUTO_UPDATE_VL805=1
|
|
;;
|
|
d) OVERWRITE_CONFIG=1
|
|
;;
|
|
f) BOOTLOADER_UPDATE_IMAGE="${OPTARG}"
|
|
;;
|
|
i) IGNORE_DPKG_CHECKSUMS=1
|
|
;;
|
|
j) JSON_OUTPUT="yes"
|
|
;;
|
|
m) MACHINE_OUTPUT="${OPTARG}"
|
|
;;
|
|
h) usage
|
|
;;
|
|
r) [ "$(id -u)" = "0" ] || die "* Must be run as root - try 'sudo rpi-eeprom-update -r'"
|
|
echo "Removing temporary files from previous EEPROM update"
|
|
removePreviousUpdates
|
|
exit 0
|
|
;;
|
|
u) VL805_UPDATE_IMAGE="${OPTARG}"
|
|
;;
|
|
*) echo "Unknown argument \"${option}\""
|
|
usage
|
|
;;
|
|
esac
|
|
done
|
|
|
|
checkDependencies
|
|
if [ "${AUTO_UPDATE_BOOTLOADER}" = 1 ] || [ "${AUTO_UPDATE_VL805}" = 1 ]; then
|
|
if vcgencmd bootloader_config | grep FREEZE_VERSION=1; then
|
|
echo "EEPROM version is frozen. Skipping update"
|
|
exit ${EXIT_EEPROM_FROZEN}
|
|
else
|
|
checkAndApply
|
|
fi
|
|
elif [ -n "${BOOTLOADER_UPDATE_IMAGE}" ] || [ -n "${VL805_UPDATE_IMAGE}" ]; then
|
|
fileUpdate
|
|
else
|
|
checkVersion
|
|
fi
|