From 9147a1a1c62f68c797f229204f5274be1cd47da4 Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Mon, 25 Sep 2023 15:43:57 +0100 Subject: [PATCH] scripts: Add support for chip-specific firmware directories BCM2711 and BCM2712 require different EEPROM firmware and consequently the binaries have been moved to chip specific firmware directories. firmware-2711 / firmware-2712 --- .../{ => 2711-config}/boot-conf-default.txt | 0 .../{ => 2711-config}/boot-conf-network.txt | 0 imager/{ => 2711-config}/boot-conf-sd.txt | 0 imager/{ => 2711-config}/boot-conf-usb.txt | 0 imager/2712-config/boot-conf-default.txt | 4 + imager/2712-config/boot-conf-network.txt | 5 + imager/2712-config/boot-conf-sd.txt | 4 + imager/2712-config/boot-conf-usb.txt | 5 + imager/make-beta-release | 13 -- imager/make-imager-release | 6 +- imager/make-release | 22 ++-- releases.md | 7 +- rpi-eeprom-config | 31 +++-- rpi-eeprom-update | 117 ++++++++++++------ rpi-eeprom-update-default | 3 +- test/install | 11 +- test/test-rpi-eeprom-config | 14 +-- 17 files changed, 156 insertions(+), 86 deletions(-) rename imager/{ => 2711-config}/boot-conf-default.txt (100%) rename imager/{ => 2711-config}/boot-conf-network.txt (100%) rename imager/{ => 2711-config}/boot-conf-sd.txt (100%) rename imager/{ => 2711-config}/boot-conf-usb.txt (100%) create mode 100644 imager/2712-config/boot-conf-default.txt create mode 100644 imager/2712-config/boot-conf-network.txt create mode 100644 imager/2712-config/boot-conf-sd.txt create mode 100644 imager/2712-config/boot-conf-usb.txt delete mode 100755 imager/make-beta-release diff --git a/imager/boot-conf-default.txt b/imager/2711-config/boot-conf-default.txt similarity index 100% rename from imager/boot-conf-default.txt rename to imager/2711-config/boot-conf-default.txt diff --git a/imager/boot-conf-network.txt b/imager/2711-config/boot-conf-network.txt similarity index 100% rename from imager/boot-conf-network.txt rename to imager/2711-config/boot-conf-network.txt diff --git a/imager/boot-conf-sd.txt b/imager/2711-config/boot-conf-sd.txt similarity index 100% rename from imager/boot-conf-sd.txt rename to imager/2711-config/boot-conf-sd.txt diff --git a/imager/boot-conf-usb.txt b/imager/2711-config/boot-conf-usb.txt similarity index 100% rename from imager/boot-conf-usb.txt rename to imager/2711-config/boot-conf-usb.txt diff --git a/imager/2712-config/boot-conf-default.txt b/imager/2712-config/boot-conf-default.txt new file mode 100644 index 0000000..4928825 --- /dev/null +++ b/imager/2712-config/boot-conf-default.txt @@ -0,0 +1,4 @@ +[all] +BOOT_UART=1 +BOOT_ORDER=0xf41 +POWER_OFF_ON_HALT=0 diff --git a/imager/2712-config/boot-conf-network.txt b/imager/2712-config/boot-conf-network.txt new file mode 100644 index 0000000..8321993 --- /dev/null +++ b/imager/2712-config/boot-conf-network.txt @@ -0,0 +1,5 @@ +[all] +BOOT_UART=1 +BOOT_ORDER=0xf21 +POWER_OFF_ON_HALT=0 + diff --git a/imager/2712-config/boot-conf-sd.txt b/imager/2712-config/boot-conf-sd.txt new file mode 100644 index 0000000..4928825 --- /dev/null +++ b/imager/2712-config/boot-conf-sd.txt @@ -0,0 +1,4 @@ +[all] +BOOT_UART=1 +BOOT_ORDER=0xf41 +POWER_OFF_ON_HALT=0 diff --git a/imager/2712-config/boot-conf-usb.txt b/imager/2712-config/boot-conf-usb.txt new file mode 100644 index 0000000..020633e --- /dev/null +++ b/imager/2712-config/boot-conf-usb.txt @@ -0,0 +1,5 @@ +[all] +BOOT_UART=1 +BOOT_ORDER=0xf14 +POWER_OFF_ON_HALT=0 + diff --git a/imager/make-beta-release b/imager/make-beta-release deleted file mode 100755 index 25c3e71..0000000 --- a/imager/make-beta-release +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -set -e - -script_dir=$(cd "$(dirname "$0")" && pwd) - -firmware_status=${firmware_status:-"beta"} -firmware_dir=${script_dir}/../firmware/${firmware_status} -pieeprom_version=$(basename $(ls ${firmware_dir}/pieeprom-*.bin | sort -V | tail -1) .bin | cut -d- -f2-5) -vl805_version=$(basename $(ls ${firmware_dir}/vl805-*.bin | sort -V | tail -1) .bin | cut -d- -f2) - -${script_dir}/make-release ${firmware_status} ${pieeprom_version} ${vl805_version} "${script_dir}" ${firmware_status}_release rpi-boot-eeprom-recovery-${firmware_status} - diff --git a/imager/make-imager-release b/imager/make-imager-release index 1186326..5717b03 100755 --- a/imager/make-imager-release +++ b/imager/make-imager-release @@ -4,4 +4,8 @@ set -e script_dir=$(cd "$(dirname "$0")" && pwd) -${script_dir}/make-release critical 2023-01-11 000138c0 "${script_dir}" release rpi-boot-eeprom-recovery +# Pi4, Pi400, CM4, CM4-S +${script_dir}/make-release critical 2023-01-11 000138c0 "${script_dir}/2711-config" release-2711 rpi-boot-eeprom-recovery 2711 + +# Pi5 +${script_dir}/make-release critical 2023-09-21 "" "${script_dir}/2712-config" release-2712 rpi-boot-eeprom-recovery 2712 diff --git a/imager/make-release b/imager/make-release index e01fe70..26be575 100755 --- a/imager/make-release +++ b/imager/make-release @@ -32,8 +32,10 @@ gen_release() { cd "${tmp_dir}" cp "${script_dir}/README.txt" . cp "${firmware_dir}/recovery.bin" . - cp "${firmware_dir}/vl805-${vl805_version}.bin" vl805.bin - sha256sum vl805.bin | awk '{print $1}' > vl805.sig + if [ ${bcm_chip} = 2711 ]; then + cp "${firmware_dir}/vl805-${vl805_version}.bin" vl805.bin + sha256sum vl805.bin | awk '{print $1}' > vl805.sig + fi "${script_dir}/../rpi-eeprom-config" \ --config "${config}" --out pieeprom.bin \ @@ -61,20 +63,26 @@ vl805_version="${3}" config_dir="${4}" output_dir="${5}" output_basename="${6}" +bcm_chip="${7}" [ -n "${firmware_status}" ] || usage [ -n "${pieeprom_version}" ] || usage -[ -n "${vl805_version}" ] || usage [ -n "${config_dir}" ] || usage [ -n "${output_dir}" ] || usage [ -n "${output_basename}" ] || usage +[ -n "${bcm_chip}" ] || usage -firmware_dir=${script_dir}/../firmware/${firmware_status} +firmware_dir=${script_dir}/../firmware-${bcm_chip}/${firmware_status} [ -d "${firmware_dir}" ] || (echo "${firmware_dir} doesn't exist" && exit 1) [ -f "${firmware_dir}/pieeprom-${pieeprom_version}.bin" ] || (echo "${firmware_status}/pieeprom-${pieeprom_version}.bin doesn't exist" && exit 1) -[ -f "${firmware_dir}/vl805-${vl805_version}.bin" ] || (echo "${firmware_status}/vl805-${vl805_version}.bin doesn't exist" && exit 1) -[ -d "${config_dir}" ] || (echo "${config_dir} doesn't exist" && exit 1) -tag="${pieeprom_version}-vl805-${vl805_version}" + +if [ "${bcm_chip}" = 2711 ]; then + [ -f "${firmware_dir}/vl805-${vl805_version}.bin" ] || (echo "${firmware_status}/vl805-${vl805_version}.bin doesn't exist" && exit 1) + [ -d "${config_dir}" ] || (echo "${config_dir} doesn't exist" && exit 1) + tag="${pieeprom_version}-vl805-${vl805_version}" +else + tag="${pieeprom_version}" +fi # use realpath to ensure paths are absolute config_dir=$(realpath "${config_dir}") output_dir=$(realpath "${output_dir}") diff --git a/releases.md b/releases.md index 849b183..f2f9ea0 100644 --- a/releases.md +++ b/releases.md @@ -1,12 +1,13 @@ -# Raspberry Pi 4B, 400 and CM4 bootloader EEPROM releases -This page provides links to the production and development release images for the bootloader EEPROM on BCM2711-based Raspberry Pi computers. Normally, the +# Raspberry Pi 4 and Raspberry Pi 5 bootloader EEPROM releases. +This page provides links to the production and development release images for the bootloader EEPROM on BCM2711 and BCM2712 based Raspberry Pi computers. Normally, the bootloader is automatically updated after an APT update via the [rpi-eeprom-update](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#automatic-updates) utility. ## Release notes Release notes are available [here](https://github.com/raspberrypi/rpi-eeprom/blob/master/firmware/release-notes.md). ## Default release -The default production EEPROM image release is [2022-11-25](https://github.com/raspberrypi/rpi-eeprom/releases/tag/v2022.11.25-138a1) and can be installed via the [Raspberry Pi Imager](https://www.raspberrypi.com/software/). +### Raspberry Pi 4, CM4, CM4-s, Pi400 +The default production EEPROM image release is [2023-01-11](https://github.com/raspberrypi/rpi-eeprom/releases/tag/v2023.01.11-138c0) and can be installed via the [Raspberry Pi Imager](https://www.raspberrypi.com/software/). ## USB MSD boot Please see the [USB mass storage boot](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#usb-mass-storage-boot) guide. diff --git a/rpi-eeprom-config b/rpi-eeprom-config index a5dd19f..ccfc538 100755 --- a/rpi-eeprom-config +++ b/rpi-eeprom-config @@ -14,7 +14,7 @@ import sys import tempfile import time -IMAGE_SIZE = 512 * 1024 +VALID_IMAGE_SIZES = [512 * 1024, 2 * 1024 * 1024] BOOTCONF_TXT = 'bootconf.txt' BOOTCONF_SIG = 'bootconf.sig' @@ -55,6 +55,15 @@ def rpi4(): return True return False +def rpi5(): + compatible_path = "/sys/firmware/devicetree/base/compatible" + if os.path.exists(compatible_path): + with open(compatible_path, "rb") as f: + compatible = f.read().decode('utf-8') + if "bcm2712" in compatible: + return True + return False + def exit_handler(): """ Delete any temporary files. @@ -233,6 +242,7 @@ class BootloaderImage(object): """ self._filename = filename self._sections = [] + self._image_size = 0 try: self._bytes = bytearray(open(filename, 'rb').read()) except IOError as err: @@ -241,9 +251,10 @@ class BootloaderImage(object): if output is not None: self._out = open(output, 'wb') - if len(self._bytes) != IMAGE_SIZE: + self._image_size = len(self._bytes) + if self._image_size not in VALID_IMAGE_SIZES: exit_error("%s: Expected size %d bytes actual size %d bytes" % - (filename, IMAGE_SIZE, len(self._bytes))) + (filename, self._image_size, len(self._bytes))) self.parse() def parse(self): @@ -252,7 +263,7 @@ class BootloaderImage(object): """ offset = 0 magic = 0 - while offset < IMAGE_SIZE: + while offset < self._image_size: magic, length = struct.unpack_from('>LL', self._bytes, offset) if magic == 0x0 or magic == 0xffffffff: break # EOF @@ -278,7 +289,7 @@ class BootloaderImage(object): length = -1 is_last = False - next_offset = IMAGE_SIZE - ERASE_ALIGN_SIZE # Don't create padding inside the bootloader scratch page + next_offset = self._image_size - ERASE_ALIGN_SIZE # Don't create padding inside the bootloader scratch page for i in range(0, len(self._sections)): s = self._sections[i] if s.magic == FILE_MAGIC and s.filename == filename: @@ -306,7 +317,7 @@ class BootloaderImage(object): hdr_offset, length, is_last, next_offset = self.find_file(dst_filename) update_len = len(src_bytes) + FILE_HDR_LEN - if hdr_offset + update_len > IMAGE_SIZE - ERASE_ALIGN_SIZE: + if hdr_offset + update_len > self._image_size - ERASE_ALIGN_SIZE: raise Exception('No space available - image past EOF.') if hdr_offset < 0: @@ -406,10 +417,10 @@ class BootloaderImage(object): def main(): """ Utility for reading and writing the configuration file in the - Raspberry Pi 4 bootloader EEPROM image. + Raspberry Pi bootloader EEPROM image. """ description = """\ -Bootloader EEPROM configuration tool for the Raspberry Pi 4. +Bootloader EEPROM configuration tool for the Raspberry Pi 4 and Raspberry Pi 5. Operating modes: 1. Outputs the current bootloader configuration to STDOUT if no arguments are @@ -493,8 +504,8 @@ See 'rpi-eeprom-update -h' for more information about the available EEPROM image if (args.edit or args.apply is not None) and os.getuid() != 0: exit_error("--edit/--apply must be run as root") - if (args.edit or args.apply is not None) and not rpi4(): - exit_error("--edit/--apply must run on a Raspberry Pi 4") + if (args.edit or args.apply is not None) and not rpi4() and not rpi5(): + exit_error("--edit/--apply must run on a Raspberry Pi 4 or Raspberry Pi 5") if args.edit: edit_config(args.eeprom) diff --git a/rpi-eeprom-update b/rpi-eeprom-update index 3880b74..38bb840 100755 --- a/rpi-eeprom-update +++ b/rpi-eeprom-update @@ -1,6 +1,6 @@ #!/bin/sh -# Raspberry Pi4 boot EEPROM updater. +# Raspberry Pi bootloader EEPROM updater. set -e @@ -14,8 +14,7 @@ LOCAL_MODE=0 if [ -n "$FIRMWARE_ROOT" ]; then # Provided by environment true -elif [ -d /lib/firmware/raspberrypi/bootloader ]; then - # Default firmware root exists +elif [ -d /lib/firmware/raspberrypi/bootloader ] || [ -d /lib/firmware/raspberrypi/bootloader-2711 ] || [ -d /lib/firmware/raspberrypi/bootloader-2712 ]; then FIRMWARE_ROOT=/lib/firmware/raspberrypi/bootloader else # Work from local git checkout @@ -25,10 +24,8 @@ fi # Selects the release sub-directory FIRMWARE_RELEASE_STATUS=${FIRMWARE_RELEASE_STATUS:-default} -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} -RECOVERY_BIN=${RECOVERY_BIN:-${FIRMWARE_ROOT}/${FIRMWARE_RELEASE_STATUS}/recovery.bin} CM4_ENABLE_RPI_EEPROM_UPDATE=${CM4_ENABLE_RPI_EEPROM_UPDATE:-0} RPI_EEPROM_UPDATE_CONFIG_TOOL="${RPI_EEPROM_UPDATE_CONFIG_TOOL:-raspi-config}" @@ -43,10 +40,6 @@ RPI_EEPROM_UPDATE_CONFIG_TOOL="${RPI_EEPROM_UPDATE_CONFIG_TOOL:-raspi-config}" RPI_EEPROM_SELF_UPDATE="${RPI_EEPROM_SELF_UPDATE:-0}" RPI_EEPROM_SELF_UPDATE_MIN_VER=1650968668 -# 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} EXIT_SUCCESS=0 @@ -63,6 +56,7 @@ EEPROM_SIZE=524288 BOARD_INFO= BOARD_REVISION= BOARD_TYPE= +BCM_CHIP= # Newer board revisions embed the VLI firmware in the bootloader EEPROM and # there is no way to separately update the VLI firmware. Consequently, @@ -244,8 +238,8 @@ applyRecoveryUpdate() [ "${BOOTLOADER_CURRENT_VERSION}" -ge "${RPI_EEPROM_SELF_UPDATE_MIN_VER}" ] || RPI_EEPROM_SELF_UPDATE=0 if [ "${RPI_EEPROM_SELF_UPDATE}" != "1" ]; then - echo "Using recovery.bin for EEPROM update" - cp -f "${RECOVERY_BIN}" "${BOOTFS}/recovery.bin" || die "Failed to copy ${RECOVERY_BIN} to ${BOOTFS}" + echo "Using recovery.bin for EEPROM update" + cp -f "${RECOVERY_BIN}" "${BOOTFS}/recovery.bin" || die "Failed to copy ${RECOVERY_BIN} to ${BOOTFS}" fi echo "" @@ -314,6 +308,11 @@ getBootloaderUpdateVersion() { fi } +chipNotSupported() { + echo "This tool only works with Raspberry Pi4 and Rapberry Pi5" + exit ${EXIT_SUCCESS} +} + checkDependencies() { if [ -f "/sys/firmware/devicetree/base/system/linux,revision" ]; then @@ -327,12 +326,32 @@ checkDependencies() { exit ${EXIT_SUCCESS} fi - if [ $(((0x$BOARD_INFO >> 23) & 1)) -eq 0 ] || [ $(((0x$BOARD_INFO >> 12) & 15)) -ne 3 ]; then - # Not a BCM2711, no EEPROMs to update. - echo "This tool only works with a Raspberry Pi 4" - exit ${EXIT_SUCCESS} + if [ $(((0x$BOARD_INFO >> 23) & 1)) = 0 ]; then + chipNotSupported fi + if [ $(((0x$BOARD_INFO >> 12) & 15)) = 3 ]; then + BCM_CHIP=2711 + EEPROM_SIZE=524288 + BOOTLOADER_AUTO_UPDATE_MIN_VERSION="${BOOTLOADER_AUTO_UPDATE_MIN_VERSION:-1599135103}" + elif [ $(((0x$BOARD_INFO >> 12) & 15)) = 4 ]; then + # BCM2712 always supports self-update so recovery.bin is only used for RPi imager + # bootloader updated SD cards or with RPIBOOT. + BCM_CHIP=2712 + EEPROM_SIZE=2097152 + RPI_EEPROM_SELF_UPDATE=1 + BOOTLOADER_AUTO_UPDATE_MIN_VERSION="${BOOTLOADER_AUTO_UPDATE_MIN_VERSION:-1694601426}" + else + chipNotSupported + fi + + FIRMWARE_IMAGE_DIR="${FIRMWARE_ROOT}-${BCM_CHIP}/${FIRMWARE_RELEASE_STATUS}" + if ! [ -d "${FIRMWARE_IMAGE_DIR}" ]; then + # Use unadorned name for backwards compatiblity + FIRMWARE_IMAGE_DIR="${FIRMWARE_ROOT}/${FIRMWARE_RELEASE_STATUS}" + fi + RECOVERY_BIN=${RECOVERY_BIN:-${FIRMWARE_IMAGE_DIR}/recovery.bin} + BOARD_TYPE=$(((0x$BOARD_INFO >> 4) & 0xff)) BOARD_REVISION=$((0x$BOARD_INFO & 0xf)) @@ -385,7 +404,7 @@ checkDependencies() { die "sha256sum not found. Try installing the coreutilities package." fi - if [ ! -f "${RECOVERY_BIN}" ]; then + if [ "${BCM_CHIP}" = 2711 ] && [ ! -f "${RECOVERY_BIN}" ]; then die "${RECOVERY_BIN} not found." fi } @@ -394,13 +413,15 @@ usage() { cat <