mirror of
https://github.com/raspberrypi/rpi-eeprom.git
synced 2026-01-20 21:13:36 +08:00
Merge branch 'master' into debian/bookworm
This commit is contained in:
BIN
firmware-2712/default/pieeprom-2023-11-20.bin
Normal file
BIN
firmware-2712/default/pieeprom-2023-11-20.bin
Normal file
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2023-11-20.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2023-11-20.bin
Normal file
Binary file not shown.
@@ -1,5 +1,16 @@
|
||||
# Raspberry Pi5 bootloader EEPROM release notes
|
||||
|
||||
2023-11-20: Auto-detect support for PCIe expansion HAT (default + latest)
|
||||
|
||||
* Add autodetect support for PCIe expansion HATs
|
||||
* Add PCIE_PROBE=1 to the EEPROM config for custom PCIe exapansion
|
||||
designs that do not support the upcoming HAT spec. This gives
|
||||
similar behaviour to CM4 where PCIe x1 is enumerated to discover NVMe
|
||||
devices.
|
||||
* Fix loading of multiple initramfs images that are not 32-bit aligned sizes
|
||||
https://github.com/raspberrypi/firmware/issues/1843
|
||||
* Kernel load performance improvement - remove a memcpy
|
||||
|
||||
2023-10-30: UPG watchdog support + SD reset fixes (default + latest)
|
||||
|
||||
* Fix SDIO / WiFi clock-setup for BOOT_ORDER=0xf14
|
||||
|
||||
@@ -109,7 +109,7 @@ def exit_error(msg):
|
||||
sys.stderr.write("ERROR: %s\n" % msg)
|
||||
sys.exit(1)
|
||||
|
||||
def shell_cmd(args):
|
||||
def shell_cmd(args, timeout=5, echo=False):
|
||||
"""
|
||||
Executes a shell command waits for completion returning STDOUT. If an
|
||||
error occurs then exit and output the subprocess stdout, stderr messages
|
||||
@@ -117,9 +117,14 @@ def shell_cmd(args):
|
||||
"""
|
||||
start = time.time()
|
||||
arg_str = ' '.join(args)
|
||||
result = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
bufsize = 0 if echo else -1
|
||||
result = subprocess.Popen(args, bufsize=bufsize, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
while time.time() - start < 5:
|
||||
while time.time() - start < timeout:
|
||||
if echo:
|
||||
s = result.stdout.read(80).decode('utf-8')
|
||||
if s != "":
|
||||
sys.stdout.write(s)
|
||||
if result.poll() is not None:
|
||||
break
|
||||
|
||||
@@ -128,8 +133,8 @@ def shell_cmd(args):
|
||||
|
||||
if result.returncode != 0:
|
||||
exit_error("%s failed: %d\n %s\n %s\n" %
|
||||
(arg_str, result.returncode, result.stdout.read(), result.stderr.read()))
|
||||
else:
|
||||
(arg_str, result.returncode, result.stdout.read().decode('utf-8'), result.stderr.read().decode('utf-8')))
|
||||
elif not echo:
|
||||
return result.stdout.read().decode('utf-8')
|
||||
|
||||
def get_latest_eeprom():
|
||||
@@ -170,8 +175,10 @@ def apply_update(config, eeprom=None, config_src=None):
|
||||
# with EEPROMs with configs delivered outside of APT.
|
||||
# The checksums are really just a safety check for automatic updates.
|
||||
args = ['rpi-eeprom-update', '-d', '-i', '-f', tmp_update]
|
||||
resp = shell_cmd(args)
|
||||
sys.stdout.write(resp)
|
||||
|
||||
# If flashrom is used then the command will not return until the EEPROM
|
||||
# has been updated so use a larger timeout.
|
||||
shell_cmd(args, timeout=20, echo=True)
|
||||
|
||||
def edit_config(eeprom=None):
|
||||
"""
|
||||
@@ -377,6 +384,15 @@ class BootloaderImage(object):
|
||||
% (src_filename, len(src_bytes), MAX_FILE_SIZE))
|
||||
self.update(src_bytes, dst_filename)
|
||||
|
||||
def set_timestamp(self, timestamp):
|
||||
"""
|
||||
Sets the self-update timestamp in an EEPROM image file. This is useful when
|
||||
using flashrom to write to SPI flash instead of using the bootloader self-update mode.
|
||||
"""
|
||||
ts = int(timestamp)
|
||||
struct.pack_into('<L', self._bytes, len(self._bytes) - 4, ts)
|
||||
struct.pack_into('<L', self._bytes, len(self._bytes) - 8, ~ts & 0xffffffff)
|
||||
|
||||
def write(self):
|
||||
"""
|
||||
Writes the updated EEPROM image to stdout or the specified output file.
|
||||
@@ -498,6 +514,7 @@ See 'rpi-eeprom-update -h' for more information about the available EEPROM image
|
||||
parser.add_argument('-d', '--digest', help='Signed boot only. The name of the .sig file generated by rpi-eeprom-dgst for config.txt ', required=False)
|
||||
parser.add_argument('-p', '--pubkey', help='Signed boot only. The name of the RSA public key file to store in the EEPROM', required=False)
|
||||
parser.add_argument('-x', '--extract', action='store_true', default=False, help='Extract the modifiable files (boot.conf, pubkey, signature)', required=False)
|
||||
parser.add_argument('-t', '--timestamp', help='Set the timestamp in the EEPROM image file', required=False)
|
||||
parser.add_argument('eeprom', nargs='?', help='Name of EEPROM file to use as input')
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -518,6 +535,8 @@ See 'rpi-eeprom-update -h' for more information about the available EEPROM image
|
||||
apply_update(args.apply, args.eeprom, args.apply)
|
||||
elif args.eeprom is not None:
|
||||
image = BootloaderImage(args.eeprom, args.out)
|
||||
if args.timestamp is not None:
|
||||
image.set_timestamp(args.timestamp)
|
||||
if args.config is not None:
|
||||
if not os.path.exists(args.config):
|
||||
exit_error("config file '%s' not found" % args.config)
|
||||
@@ -527,6 +546,8 @@ See 'rpi-eeprom-update -h' for more information about the available EEPROM image
|
||||
if args.pubkey is not None:
|
||||
image.update_key(args.pubkey, PUBKEY_BIN)
|
||||
image.write()
|
||||
elif args.config is None and args.timestamp is not None:
|
||||
image.write()
|
||||
else:
|
||||
image.read()
|
||||
elif args.config is None and args.eeprom is None:
|
||||
|
||||
@@ -89,6 +89,9 @@ cleanup() {
|
||||
if [ -f "${NEW_EEPROM_CONFIG}" ]; then
|
||||
rm -f "${NEW_EEPROM_CONFIG}"
|
||||
fi
|
||||
if [ -f "${FLASHROM_LOG}" ]; then
|
||||
rm -f "${FLASHROM_LOG}"
|
||||
fi
|
||||
if [ -d "${TMP_BOOTFS_MNT}" ]; then
|
||||
umount "${TMP_BOOTFS_MNT}"
|
||||
rmdir "${TMP_BOOTFS_MNT}"
|
||||
@@ -97,6 +100,7 @@ cleanup() {
|
||||
TMP_EEPROM_IMAGE=
|
||||
TMP_EEPROM_CONFIG=
|
||||
NEW_EEPROM_CONFIG=
|
||||
FLASHROM_LOG=
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
@@ -169,7 +173,14 @@ prepareImage()
|
||||
if [ "${OVERWRITE_CONFIG}" = 0 ]; then
|
||||
"${script_dir}/rpi-eeprom-config" \
|
||||
--out "${TMP_EEPROM_IMAGE}" \
|
||||
--config "${NEW_EEPROM_CONFIG}" "${BOOTLOADER_UPDATE_IMAGE}"
|
||||
--config "${NEW_EEPROM_CONFIG}" \
|
||||
--timestamp "$(date -u +%s)" \
|
||||
"${BOOTLOADER_UPDATE_IMAGE}"
|
||||
else
|
||||
"${script_dir}/rpi-eeprom-config" \
|
||||
--out "${TMP_EEPROM_IMAGE}" \
|
||||
--timestamp "$(date -u +%s)" \
|
||||
"${BOOTLOADER_UPDATE_IMAGE}"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -200,7 +211,7 @@ applyRecoveryUpdate()
|
||||
# and the current timestamp.
|
||||
rpi-eeprom-digest -i "${TMP_EEPROM_IMAGE}" -o "${BOOTFS}/pieeprom.sig"
|
||||
|
||||
cp -f "${TMP_EEPROM_IMAGE}" "${BOOTFS}/pieeprom.upd" \
|
||||
cp -fv "${TMP_EEPROM_IMAGE}" "${BOOTFS}/pieeprom.upd" \
|
||||
|| die "Failed to copy ${TMP_EEPROM_IMAGE} to ${BOOTFS}"
|
||||
|
||||
# For NFS mounts ensure that the files are readable to the TFTP user
|
||||
@@ -225,7 +236,7 @@ applyRecoveryUpdate()
|
||||
RPI_EEPROM_SELF_UPDATE=0
|
||||
fi
|
||||
|
||||
# Setting bootlaoder_update=0 was really intended for use with network-boot with shared
|
||||
# Setting bootloader_update=0 was really intended for use with network-boot with shared
|
||||
# config.txt files. However, if it looks as though self-update has been disabled then
|
||||
# assume recovery.bin is required.
|
||||
config_txt="${BOOTFS}/config.txt"
|
||||
@@ -237,8 +248,33 @@ 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"
|
||||
# For immediate updates via flash the recovery.bin update is created and then discarded if the
|
||||
# flashrom update was successful. For SD boot (most common) this provides a rollback in the event
|
||||
# of power loss.
|
||||
if [ "${RPI_EEPROM_USE_FLASHROM}" = 1 ]; then
|
||||
echo
|
||||
echo "UPDATING bootloader."
|
||||
echo
|
||||
echo "*** WARNING: Do not disconnect the power until the update is complete ***"
|
||||
echo "If a problem occurs then the Raspberry Pi Imager may be used to create"
|
||||
echo "a bootloader rescue SD card image which restores the default bootloader image."
|
||||
echo
|
||||
FLASHROM_LOG="$(mktemp)"
|
||||
echo "flashrom -p linux_spi:dev=${SPIDEV},spispeed=16000 -w ${BOOTFS}/pieeprom.upd"
|
||||
if flashrom -p linux_spi:dev=${SPIDEV},spispeed=16000 -w "${BOOTFS}/pieeprom.upd" > "${FLASHROM_LOG}"; then
|
||||
# Success - remove update files from the boot partition
|
||||
removePreviousUpdates
|
||||
echo "UPDATE SUCCESSFUL"
|
||||
else
|
||||
# Leave the recovery files in case the EEPROM has been partially updated
|
||||
cat "${FLASHROM_LOG}"
|
||||
die "UPDATE FAILED"
|
||||
fi
|
||||
return
|
||||
elif [ "${RPI_EEPROM_SELF_UPDATE}" = "1" ]; then
|
||||
echo "Using self-update"
|
||||
else
|
||||
echo "Copying recovery.bin to ${BOOTFS} for EEPROM update"
|
||||
cp -f "${RECOVERY_BIN}" "${BOOTFS}/recovery.bin" || die "Failed to copy ${RECOVERY_BIN} to ${BOOTFS}"
|
||||
fi
|
||||
|
||||
@@ -269,6 +305,25 @@ applyUpdate() {
|
||||
) || die "Unable to validate EEPROM image package checksums"
|
||||
fi
|
||||
|
||||
# Disable flashrom if the SPI device is not found
|
||||
if [ "${RPI_EEPROM_USE_FLASHROM}" = 1 ]; then
|
||||
flashrom_probe_ok=0
|
||||
if ! [ -e "${SPIDEV}" ]; then
|
||||
echo "WARNING: SPI device ${SPIDEV} not found. Setting RPI_EEPROM_USE_FLASHROM to 0"
|
||||
fi
|
||||
|
||||
if ! flashrom -p linux_spi:dev=${SPIDEV},spispeed=16000 > /dev/null 2>&1; then
|
||||
echo "WARNING: Flashrom probe of ${SPIDEV} failed"
|
||||
else
|
||||
flashrom_probe_ok=1
|
||||
fi
|
||||
if [ "${flashrom_probe_ok}" != 1 ]; then
|
||||
echo "Setting RPI_EEPROM_USE_FLASHROM to 0"
|
||||
echo
|
||||
export RPI_EEPROM_USE_FLASHROM=0
|
||||
fi
|
||||
fi
|
||||
|
||||
applyRecoveryUpdate
|
||||
}
|
||||
|
||||
@@ -334,14 +389,21 @@ checkDependencies() {
|
||||
BCM_CHIP=2711
|
||||
EEPROM_SIZE=524288
|
||||
BOOTLOADER_AUTO_UPDATE_MIN_VERSION="${BOOTLOADER_AUTO_UPDATE_MIN_VERSION:-1599135103}"
|
||||
|
||||
SPIDEV=/dev/spidev0.0
|
||||
elif [ $(((0x$BOARD_INFO >> 12) & 15)) = 4 ]; then
|
||||
BCM_CHIP=2712
|
||||
EEPROM_SIZE=2097152
|
||||
BOOTLOADER_AUTO_UPDATE_MIN_VERSION="${BOOTLOADER_AUTO_UPDATE_MIN_VERSION:-1697650217}"
|
||||
SPIDEV=/dev/spidev10.0
|
||||
else
|
||||
chipNotSupported
|
||||
fi
|
||||
|
||||
# Default to off - in the future Raspberry Pi 5 may default to using flashrom if
|
||||
# flashrom is available.
|
||||
[ -z "${RPI_EEPROM_USE_FLASHROM}" ] && RPI_EEPROM_USE_FLASHROM=0
|
||||
|
||||
FIRMWARE_IMAGE_DIR="${FIRMWARE_ROOT}-${BCM_CHIP}/${FIRMWARE_RELEASE_STATUS}"
|
||||
if ! [ -d "${FIRMWARE_IMAGE_DIR}" ]; then
|
||||
# Use unadorned name for backwards compatiblity
|
||||
@@ -358,6 +420,18 @@ checkDependencies() {
|
||||
echo "The recommended method for flashing the EEPROM is rpiboot."
|
||||
echo "See: https://github.com/raspberrypi/usbboot/blob/master/Readme.md"
|
||||
echo "Run with -h for more information."
|
||||
echo
|
||||
echo "To enable flashrom programming of the EEPROM"
|
||||
echo "Add these the following entries to /etc/default/rpi-eeprom-update"
|
||||
echo "RPI_EEPROM_USE_FLASHROM=1"
|
||||
echo "CM4_ENABLE_RPI_EEPROM_UPDATE=1"
|
||||
echo
|
||||
echo "and these entries to config.txt and reboot"
|
||||
echo "[cm4]"
|
||||
echo "dtparam=spi=on"
|
||||
echo "dtoverlay=audremap"
|
||||
echo "dtoverlay=spi-gpio40-45"
|
||||
echo
|
||||
exit ${EXIT_SUCCESS}
|
||||
fi
|
||||
|
||||
@@ -404,6 +478,10 @@ checkDependencies() {
|
||||
if [ "${BCM_CHIP}" = 2711 ] && [ ! -f "${RECOVERY_BIN}" ]; then
|
||||
die "${RECOVERY_BIN} not found."
|
||||
fi
|
||||
|
||||
if ! command -v flashrom > /dev/null; then
|
||||
RPI_EEPROM_USE_FLASHROM=0
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
@@ -542,6 +620,22 @@ N.B. If there is a power failure during SELF_UPDATE the EEPROM write may fail an
|
||||
usbboot must be used to flash the bootloader EEPROM. SELF_UPDATE is not recommended
|
||||
for updating the bootloader on remote systems.
|
||||
|
||||
FLASHROM:
|
||||
|
||||
If the RPI_EEPROM_USE_FLASHROM variable is set to 1 then flashrom is used to perform
|
||||
an immediate update to the SPI flash rather than installing the recovery.bin plus
|
||||
pieeprom.upd files. The power must not be disconnected during this update otherwise the
|
||||
EEPROM will need to be re-flashed using the Rasberry Pi Imager bootloader restore feature.
|
||||
|
||||
On Raspberry Pi 4, CM4, CM4-S and Pi400 flashrom updates are not enabled by default
|
||||
because the SPI GPIOs are shared with analog audio. To enable this add the following
|
||||
entries to config.txt. This moves analog audio to GPIO pins 12,13 and may not be
|
||||
compatible with some HATS / CM4 IO boards.
|
||||
|
||||
dtparam=spi=on
|
||||
dtoverlay=audremap
|
||||
dtoverlay=spi-gpio40-45
|
||||
|
||||
EOF
|
||||
exit ${EXIT_SUCCESS}
|
||||
}
|
||||
@@ -595,7 +689,9 @@ findBootFS()
|
||||
elif [ -z "$BOOTFS" ]; then
|
||||
if ! BOOTFS=$(/usr/lib/raspberrypi-sys-mods/get_fw_loc 2> /dev/null); then
|
||||
for BOOTFS in /boot/firmware /boot; do
|
||||
if findmnt --fstab "$BOOTFS" > /dev/null; then
|
||||
if [ -f "${BOOTFS}/config.txt" ]; then
|
||||
break
|
||||
elif findmnt --fstab "$BOOTFS" > /dev/null; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
@@ -714,7 +810,7 @@ checkAndApply()
|
||||
fi
|
||||
|
||||
if [ "${ACTION_UPDATE_BOOTLOADER}" = 1 ] || [ "${ACTION_UPDATE_VL805}" = 1 ]; then
|
||||
echo "*** INSTALLING EEPROM UPDATES ***"
|
||||
echo "*** PREPARING EEPROM UPDATES ***"
|
||||
echo ""
|
||||
|
||||
printVersions
|
||||
@@ -727,7 +823,7 @@ checkAndApply()
|
||||
fileUpdate()
|
||||
{
|
||||
removePreviousUpdates
|
||||
echo "*** INSTALLING ${BOOTLOADER_UPDATE_IMAGE} ${VL805_UPDATE_IMAGE} ***"
|
||||
echo "*** CREATED UPDATE ${BOOTLOADER_UPDATE_IMAGE} ${VL805_UPDATE_IMAGE} ***"
|
||||
echo
|
||||
|
||||
if [ -n "${BOOTLOADER_UPDATE_IMAGE}" ]; then
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
FIRMWARE_ROOT=/lib/firmware/raspberrypi/bootloader
|
||||
FIRMWARE_RELEASE_STATUS="default"
|
||||
FIRMWARE_BACKUP_DIR="/var/lib/raspberrypi/bootloader/backup"
|
||||
USE_FLASHROM=0
|
||||
EEPROM_CONFIG_HOOK=
|
||||
|
||||
# BOOTFS can be set here to override auto-detection in rpi-eeprom-update
|
||||
#BOOTFS=/boot
|
||||
|
||||
# Use flashrom if available to update the bootloader without rebooting - Raspberry Pi 5
|
||||
#RPI_EEPROM_USE_FLASHROM=1
|
||||
|
||||
Reference in New Issue
Block a user