Compare commits

...

72 Commits

Author SHA1 Message Date
Tim Gover
9a5a522ee8 pieeprom-2024-04-20: 2712: Fix SDRAM default refresh timings 2024-04-20 12:14:16 +01:00
Tim Gover
7a1a01c24f pieeprom-2024-04-17: 2712: Promote to default release (automatic update)
Interesting changes since the last automatic update:
* Enable network install
* Enable over-clocking frequencies > 3GHz
  See: ttps://github.com/raspberrypi/firmware/issues/1876
* Adjust SDRAM refresh rate according to temperature and address a performance
  gap between 4GB and 8GB parts in benchmarks.
  See: https://github.com/raspberrypi/firmware/issues/1854
* Support custom CA certs with HTTPS boot
* Move non Kernel ARM stages back to 512KB
  https://github.com/raspberrypi/firmware/issues/1868
* Assorted HAT+ and NVMe interop improvements.
* Fix TRYBOOT if secure-boot is enabled.
* Preliminary support for D0 and CM5.
2024-04-18 10:39:16 +01:00
Tim Gover
f4580cd6f5 pieeprom-2024-04-18: 2712: Update RP1 firmware to extend PCIe L1 entry timeout to 32 us (latest)
* Extend PCIe L1 entry timeout to 32us
  Fix xhci soft reset on link-down
  Set useful xhci compatibility bits in GUCTL
  See https://github.com/raspberrypi/firmware/issues/1877
2024-04-18 10:20:14 +01:00
Tim Gover
c0a207f452 pieeprom-2024-04-17: 2712: 2711: Build Pi4 and Pi5 firmware from the same branch
* Switch to building the Pi4 firmware from the common Pi4/Pi5
  mainline release. This doesn't change the Pi4 features
  but should make it quicker to release bug fixes in common code.
* Fix issue that caused the TRYBOOT flag to be lost in secure-boot mode.
* dtoverlay: Use %u when converting u32s to strings
   See: https://github.com/raspberrypi/linux/issues/6039
* Improved debug messages for secure-boot.
* Generate the bootloader diagnostics qrcode at run time.
2024-04-17 14:20:36 +01:00
Andrew Scheller
76b990a894 rpi-eeprom-config: fix rpi-eeprom-dgst typo in usage-text 2024-04-17 10:47:18 +01:00
Tim Gover
afa5822e03 rpi-eeprom-config: Add --debug flag to args 2024-04-17 10:46:10 +01:00
Tim Gover
a2fb4ed28d rpi-eeprom-config: Process bootcode arg with other file replacements
It should be possible to change the config, public key, signature
and signed bootcode in a single operation.
2024-04-17 10:46:10 +01:00
Tim Gover
ca7a39efe9 pieeprom-2024-04-15: 2711: Promote stable release to DEFAULT 2024-04-16 09:55:05 +01:00
Tim Gover
c94506e598 pieeprom-2024-04-15: 2711: Fix tryboot mode in secure-boot - STABLE
Fix an issue where the tryboot flag was being reset and lost during
the secure-boot initialization.
2024-04-15 16:52:48 +01:00
Cody Scott
61023cbd32 Remove variable expansion in arithmetic
https://www.shellcheck.net/wiki/SC2004
2024-04-05 16:55:43 +01:00
Tim Gover
d8abe8c67d 2024-04-05: 2712: HAT+ fixes for max-current, custom CA cert for net install and enable over-clocking to > 3GHz (latest)
* bootloader: clock_2712: Remove restriction on arm_freq <= 3000
  See: https://github.com/raspberrypi/firmware/issues/1876
* arm_dt: Update max_current to match HAT value
* arm_dt: Remove unused legacy parameters (core_freq, arm_freq, uart0_clkrate and cache_line_size)
* Add support for custom CA cert for network install
    You need to specify
    HTTP_HOST=myhost.com
    HTTP_PATH=/path/to/files
    HTTP_CACERT_HASH=<hash>

    where <hash> is a sha256 hash of the der encoded ca certificate.
    CA cert is added using rpi-eeprom-config.
* Optimise Vbat current draw with charging disabled
* Display OTP boot status in UART log messages.
* Preliminary support for secure-boot OTP provisioning.
* Update PCIE DET_WAKE pinmux for D0 products
2024-04-05 12:39:42 +01:00
Tim Gover
14f05613b4 tools: rpi-eeprom-digest: Improve docs for secure-boot
Make it clearer that rpi-eeprom-digest is used create optionally
signed hashes for binary files.

For secure-boot the update-pieeprom.sh wrapper must be used
because only the boot configuration is signed by the customer
key rather than the entire SPI flash image.
2024-03-27 14:45:28 +00:00
Tim Gover
07bf72a919 tools: Preliminary tool support for signed-boot on 2712
Update rpi-eeprom-config to support replacement of bootcode.bin
with a customer counter-signed version.

Add a new rpi-sign-bootcode script which enables bootcode.bin
to be counter-signed with the customer key.

N.B. Signed boot on 2712 requires newer firmware which is currently
under development and has not been released.
2024-03-27 14:45:28 +00:00
Tim Gover
b745226b41 tools: rpi-otp-private-key: Update to same version as usbboot 2024-03-01 17:05:33 +00:00
Peter Harper
c478689de0 Add new cacertder option
Allows you to add a custom ca cert to an image.

Note: This option is only relevant for newer (as yet unreleased)
bootloader images that support custom CA certs and reserve a space for
this in the flash image.
2024-03-01 13:26:06 +00:00
Tim Gover
8c67b27665 rpi-eeprom-update: Only check for flashrom during an update
There's no need to check for flashrom when querying the current
version, removing pending updates etc.

See: https://github.com/raspberrypi/rpi-eeprom/issues/548
2024-03-01 10:28:58 +00:00
Tim Gover
18620870d7 rpi-eeprom-update: Output warnings to stderr
Output non-fatal warnings to stderr in order to avoid breaking
programs like rpi-eeeprom-config which parse the output of
rpi-eeprom-update.

Fixes: https://github.com/raspberrypi/rpi-eeprom/issues/548
2024-03-01 10:28:58 +00:00
Tim Gover
11c64e3721 rpi-eeprom-update: Use flashrom by default on Pi5
Use flashrom by default on Pi5 unless the the RPI_EEPROM_USE_FLASHROM
environment variable has been set to zero OR flashrom is not available.
2024-02-21 18:02:37 +00:00
Tim Gover
36e58db5c2 imager-release: 2712: Bump to 2024-02-16 2024-02-18 22:23:26 +00:00
Tim Gover
b1a715b256 2024-02-16: 2712: u-boot loading and thermal throttling fixes (latest) (default)
* arm_loader: Move non-kernels back to 512KB
  See: https://github.com/raspberrypi/firmware/issues/1868

* Limit throttled frequency to OS requested frequency rather than config.txt frequency.
   See: https://github.com/raspberrypi/rpi-eeprom/issues/518
2024-02-16 15:45:05 +00:00
Tim Gover
0e8ecbcf83 2024-02-14: 2712: Adjust SDRAM refresh based on temperature (latest)
* Adjust the SDRAM refresh interval based on the temperature. This
  addresses the gap in performance between the 8GB and 4GB variants.
  See https://github.com/raspberrypi/firmware/issues/1864
* Preliminary support for signed boot.
2024-02-14 08:58:47 +00:00
timg236
d4918d4d4c Merge pull request #539 from timg236/pieeprom-2024-02-08-2712
pieeprom-2024-02-08: 2712: Adjust SDRAM refresh based on temperature (latest)
2024-02-08 12:25:09 +00:00
Tim Gover
b5c7f1bee6 pieeprom-2024-02-08: 2712: Adjust SDRAM refresh based on temperature (latest)
* Adjust the SDRAM refresh interval based on the temperature. This
  addresses the gap in performance between the 8GB and 4GB variants.
  See https://github.com/raspberrypi/firmware/issues/1854
* Preliminary support for signed boot
2024-02-08 11:55:52 +00:00
timg236
c987375f1d Merge pull request #538 from timg236/pieeprom-2024-02-05
pieeprom-2024-02-05: 2712: Add support for HAT+ POE HATs (latest)
2024-02-05 16:53:46 +00:00
Tim Gover
99cb0bdaa2 pieeprom-2024-02-05: 2712: Add support for HAT+ POE HATs (latest)
* Add support for probing HAT+ POE HATs
* Implement DWC3 specific XHCI quirks
2024-02-05 15:18:32 +00:00
timg236
a8f2eb75b5 Merge pull request #537 from mocknen/warn-flashrom-not-found
Print warning when flashrom is not found, instead of silently ignorin…
2024-02-05 09:22:05 +00:00
Shogo Yamazaki
606c5d25e5 Print warning when flashrom is not found, instead of silently ignoring it 2024-02-04 11:50:06 +09:00
Peter Harper
88b33ab030 Merge pull request #528 from peterharperuk/nvme_boot_wd_fix
2024-01-24: NVMe boot fix for WD NVMe (latest)
2024-01-24 14:25:50 +00:00
Peter Harper
a7f982962b 2024-01-24: NVMe boot fix for WD NVMe (latest)
* Add a workaround for an issue seen when booting with WD Blue SN550 NVMe SSD
2024-01-24 12:48:26 +00:00
timg236
9df346bc1c Merge pull request #525 from timg236/pieeprom-2024-01-22-2712
2024-01-22: 2712: Fixes for small boot.img files + SD CD indicator (latest)
2024-01-22 15:57:58 +00:00
Tim Gover
68fca2166b 2024-01-22: 2712: Fixes for small boot.img files + SD CD indicator (latest)
* Fix issue boot.img end sector check - STABLE
  See:  https://github.com/raspberrypi/rpi-eeprom/issues/521
* Fix handling of files that use the last cluster in the partition
  See: https://github.com/raspberrypi/rpi-eeprom/issues/521
* Fix SD card detection
  See: https://github.com/raspberrypi/rpi-eeprom/issues/523
2024-01-22 15:54:03 +00:00
timg236
eca47c5f4c Merge pull request #524 from timg236/pieeprom-2024-01-22-2711
pieeprom-2024-01-22: 2711: Fix issue boot.img end sector check - STABLE
2024-01-22 10:58:02 +00:00
Tim Gover
097e2d0573 pieeprom-2024-01-22: 2711: Fix issue boot.img end sector check - STABLE
See https://github.com/raspberrypi/rpi-eeprom/issues/521
2024-01-22 10:51:22 +00:00
timg236
4b8e875510 Merge pull request #522 from timg236/pieeprom-2024-01-18-2711
2024-01-18: 2711: Fix issue with minimal sized FAT partition - STABLE
2024-01-18 20:10:04 +00:00
Tim Gover
21a78a91de 2024-01-18: 2711: Fix issue with minimal sized FAT partition - STABLE
* Fix handling of files that use the last cluster in the partition
  https://github.com/raspberrypi/rpi-eeprom/issues/521
2024-01-18 20:08:20 +00:00
timg236
cc020609fb Merge pull request #520 from timg236/pieeprom-2024-01-15-2712
pieeprom-2024-01-15: 2712: Add support for network-install (latest)
2024-01-16 16:03:48 +00:00
Tim Gover
d5f1ab30fa pieeprom-2024-01-15: 2712: Add support for network-install (latest)
* Add support for Network Install
* Preliminary D0 firmware support
2024-01-15 19:35:12 +00:00
timg236
8855da9889 Merge pull request #517 from timg236/pieeprom-2024-01-05-2712-default
Update default release to 2024-01-05 and mark as an automatic update
2024-01-08 11:43:57 +00:00
Tim Gover
a5b4f91caf Update RPi Imager release to 2024-01-05 2024-01-08 10:30:01 +00:00
Tim Gover
7232154170 pieeprom-2024-01-05: 2712: Promote to default (automatic update) 2024-01-08 10:24:11 +00:00
TrevorM
759460850c Updated documentation links
Documentation anchor IDs had been changed as they aren't Pi 4 specific now.
2024-01-08 09:29:00 +00:00
timg236
9e0bffb291 Merge pull request #515 from timg236/pieeprom-2024-05-01-2712
pieeprom-2024-01-05: 2712: Fix handling of FAT files without LFNs.
2024-01-06 08:35:44 +00:00
Tim Gover
258d0114c0 pieeprom-2024-01-05: 2712: Fix handling of FAT files without LFNs.
* Fix issues with SFN entries sometimes being treated as LFNs
  see https://github.com/raspberrypi/rpi-eeprom/issues/514
* Add a dedicated message for "M.2 HAT" not being found instead of
  the generic 'unsupported boot order' message when NVMe boot is
  skipped.
2024-01-06 08:33:36 +00:00
timg236
0cd761bc84 Update bug_report.yml 2024-01-05 15:58:49 +00:00
timg236
72cedfe5ee Merge pull request #512 from timg236/pieeprom-2023-12-14-default
pieeprom-2023-12-14: 2712: Promote pieeprom-2023-12-14 to default
2023-12-18 17:27:17 +00:00
Tim Gover
14e934cee3 pieeprom-2023-12-14: 2712: Promote pieeprom-2023-12-14 to default 2023-12-18 17:24:57 +00:00
Tim Gover
e407fb0030 rpi-eeprom-update: Tweak chipNotSupported message
Tweak the message to look like like an error.
2023-12-18 17:18:52 +00:00
timg236
b405ed7465 Merge pull request #511 from lurch/patch-1
rpi-eeprom-update: Fix package-names in error messages
2023-12-18 17:11:57 +00:00
Pavel Djundik
ef0cfffced Check that strings exists, suggest installing binutils 2023-12-18 17:11:09 +00:00
Andrew Scheller
a66e79ba99 rpi-eeprom-update: Fix package-names in error messages
Looks like some things have moved around in Bookworm.
2023-12-18 16:22:09 +00:00
Andrew Scheller
745eabf90e Fix typo in warning message 2023-12-18 11:55:29 +00:00
timg236
043841636c Merge pull request #507 from timg236/pieeprom-2023-12-14-2712
pieeprom-2023-12-14: 2712 + update imager release
2023-12-14 17:07:47 +00:00
Tim Gover
3f325bd482 pieeprom-2023-12-14: 2712: Fix boot partition parameter (latest)
* Fix an issue where the boot partition parameter in PM_RSTS was cleared
  before being checked.
  https://github.com/raspberrypi/firmware/issues/1853
* Add a specific fatal error pattern for RP1 not found - 4 long - 3 short
2023-12-14 17:04:22 +00:00
Tim Gover
52c5d89d48 imager: Update imager release to 2023-12-06 2023-12-12 10:27:19 +00:00
timg236
77402b6527 Merge pull request #506 from timg236/pieeprom-2023-12-06-default
pieeprom-2023-12-12: 2712: Promote 2023-12-06 to default release.
2023-12-12 09:54:53 +00:00
Tim Gover
9c8d97d6a2 pieeprom-2023-12-12: 2712: Promote 2023-12-06 to default release.
Promote this bootloader to the default release and remove the
executable bit from the file.
2023-12-12 09:16:32 +00:00
Tim Gover
f20bb90a67 imager: 2712: Add NVMe into default boot configurations
Add NVMe into the SD/USB/DEFAULT boot modes with a higher
priority than USB. The detection of NVMe HATs is quick so
there is no disadvantage in trying NVMe first.
2023-12-12 09:08:03 +00:00
timg236
7e22b8ff47 Merge pull request #503 from raspberrypi/pieeprom-2023-12-06-2712
pieeprom-2023-12-06: 2712: Initialise DWC PHY (latest)
2023-12-06 18:58:47 +00:00
Tim Gover
8f19146862 pieeprom-2023-12-06: 2712: Initialise DWC PHY (latest)
* Initialise the DWC PHY to enable DWC host+peripheral support under Linux.
  Requires 82069a7a02
* Force PWM on 3V3 supply if cameras or HATs are connected or if
   power_force_3v3_pwm=1 in config.txt
   Resolves an image quality issue with the GS camera.
* Add support for C(arm_min_freq) < 1500 MHz (must be at >= 200 MHz)
* Manufacturing test updates for DVFS.
2023-12-06 18:47:05 +00:00
timg236
e4724b4783 Merge pull request #500 from timg236/rpi-eeprom-update-ignore-dpkg-checksums
rpi-eeprom: Disable the dpkg checksum validation by default
2023-11-30 12:56:35 +00:00
Tim Gover
1e5594c51b rpi-eeprom: Disable the dpkg checksum validation by default
Enforcing package checksum validation makes it difficult to install
new EEPROM binaries via rpi-update causing extra churn of APT releases.

Drop this check by default because random corruption of these files
either via software or users never actually happens.
2023-11-30 12:55:31 +00:00
timg236
b57586ead2 Merge pull request #498 from timg236/pieeprom-2023-11-20-2712
pieeprom-2023-11-20: 2712: Auto-detect support for PCIe expansion HAT… (default + latest)
2023-11-21 11:29:19 +00:00
Tim Gover
46c89bee09 pieeprom-2023-11-20: 2712: 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-11-21 09:45:11 +00:00
timg236
6b14e84a2f Merge pull request #492 from timg236/raspberrypi5-use-flashrom
rpi-eeprom-update: Add the option to use flashrom for updates on Raspberry Pi 5
2023-11-09 12:09:42 +00:00
Tim Gover
db154d4710 rpi-eeprom-update: Add the option to use flashrom for updates on Raspberry Pi 5
On Raspberry Pi 5 there are dedicated pins for the bootloader SPI
EEPROM. This makes it possible to do immediate updates via flashrom.

The "current" EEPROM config is the EEPROM config at boot rather
than what has just been written to the SPI flash because this is
consistent with current behaviour.

To use flashrom instead of recovery.bin for bootloader updates
set RPI_EEPROM_USE_FLASHROM=1 in /etc/defaults/rpi-eeprom-update

BCM2711
On CM4, Pi4, CM4-S, Pi400 config.txt must be modified to disable
the analog audio driver which shares the GPIO pins used by the
bootloader EEPROM.

dtparam=spi=on
dtoverlay=audremap
dtoverlay=spi-gpio40-45
2023-11-02 16:54:34 +00:00
timg236
aded0825e3 Merge pull request #494 from timg236/pieeprom-2023-10-30-2712
pieeprom-2023-10-30: 2712: UPG watchdog support + SD reset fixes
2023-10-30 17:47:06 +00:00
Tim Gover
d53db79009 pieeprom-2023-10-30: 2712: UPG watchdog support + SD reset fixes (default + latest)
* Fix SDIO / WiFi clock-setup for BOOT_ORDER=0xf14
* Fix SD power-on-reset
* Firmware support for improved watchdog driver
* Update DHCP Option97 to be R,P,i,5 on Pi5
2023-10-30 16:54:48 +00:00
Tim Gover
5ec5c003ba rpi-eeprom-update: Switch back to recovery.bin on Pi5
The Pi5 EEPROM is larger and can take longer to update which
slightly increases the change of failure if the board power is
disconnected across an update. Re-enable recovery.bin for SD
updates for now.
2023-10-22 14:28:32 +01:00
timg236
b066f89a40 Merge pull request #491 from lurch/patch-1
rpi-eeprom-update: Fix typos in usage text
2023-10-22 14:06:34 +01:00
Andrew Scheller
ff81e998c5 rpi-eeprom-update: Fix typos in usage text 2023-10-21 15:05:18 +01:00
timg236
fdff8e81f0 Merge pull request #490 from timg236/tim/pieeprom-2023-10-18-2712-automatic-update
rpi-eeprom-update: 2712: Bump the min version to pieeprom-2023-10-18
2023-10-20 11:35:50 +01:00
Tim Gover
645c2a1201 rpi-eeprom-update: 2712: Bump the min version to pieeprom-2023-10-18 2023-10-20 10:51:21 +01:00
47 changed files with 719 additions and 98 deletions

View File

@@ -6,7 +6,7 @@ body:
value: |
**Is this the right place for my bug report?**
* This repository contains the Raspberry Pi 4, Pi400 and CM4 bootloader EEPROM images and installation scripts.
* This repository contains the Raspberry Pi 5, Raspberry Pi 4, Pi400, CM4 and CM4-S bootloader EEPROM images and installation scripts.
* Please report boot issues for the earlier models at the GPU firmware repo [github.com/raspberrypi/firmware](https://github.com/raspberrypi/firmware).
* Please report USB issues which occur after the OS has started at the Linux repo [github.com/raspberrypi/linux/](https://github.com/raspberrypi/linux/).
* If you simply have a question, then [the Raspberry Pi forums](https://www.raspberrypi.org/forums) are the best place to ask it.
@@ -39,10 +39,12 @@ body:
description: On which device you are facing the bug?
multiple: true
options:
- Raspberry Pi 5
- Raspberry Pi 4 Mod. B
- Raspberry Pi 400
- Raspberry Pi CM4
- Raspberry Pi CM4 Lite
- Raspberry Pi CM4-S
- Other
validations:
required: true
@@ -52,7 +54,7 @@ body:
attributes:
label: Bootloader configuration.
description: |
Copy and paste the results of `vcgencmd bootloader_config` or describe the failing configuration.
Copy and paste the results of `rpi-eeprom-config` or describe the failing configuration.
* `rpi-eeprom-update` saves a backup of the previous bootloader configuration to `/var/lib/raspberrypi/bootloader/backup` before it schedules the update.
* `rpi-eeprom-config pieeprom.upd` can be used to read the contents of an EEPROM image.

View File

@@ -9,7 +9,7 @@ To reset the bootloader back to factory defaults use [Raspberry Pi Imager](https
# Bootloader documentation
* [Config.txt boot options](https://www.raspberrypi.com/documentation/computers/config_txt.html#boot-options)
* [Bootloader EEPROM](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-4-boot-eeprom)
* [Bootloader configuration](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-4-bootloader-configuration)
* [Bootloader EEPROM](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-boot-eeprom)
* [Bootloader configuration](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-bootloader-configuration)
* [Updating the Compute Module 4 bootloader](https://www.raspberrypi.com/documentation/computers/compute-module.html#cm4bootloader)
* [Releases and release notes](releases.md)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,29 @@
# Raspberry Pi4 bootloader EEPROM release notes
## 2024-04-17 - Build Pi4 firmware from the mainline branch - STABLE
* Switch to building the Pi4 firmware from the common Pi4/Pi5
mainline release. This doesn't change the Pi4 features
but should make it quicker to release bug fixes in common code.
* Fix issue that caused the TRYBOOT flag to be lost in secure-boot mode.
* dtoverlay: Use %u when converting u32s to strings
See: https://github.com/raspberrypi/linux/issues/6039
* Improved debug messages for secure-boot.
* Generate the bootloader diagnostics qrcode at run time.
## 2024-04-15 - Fix tryboot mode in secure-boot - DEFAULT
* Promote the secure-boot fix to the DEFAULT release.
## 2024-04-15 - Fix tryboot mode in secure-boot - STABLE
* Fix an issue where the tryboot flag was being reset and lost during
the secure-boot initialization.
## 2024-01-22 - Fix issue boot.img end sector check - STABLE
* See https://github.com/raspberrypi/rpi-eeprom/issues/521
## 2024-01-18 - Fix issue with minimal sized FAT partition - STABLE
* Fix handling of files that use the last cluster in the partition
https://github.com/raspberrypi/rpi-eeprom/issues/521
## 2023-08-01 - Remove beta release folder
* Remove the beta release folder and provide a symlink to stable
for backwards compatibility for anyone who has beta in

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,130 @@
# Raspberry Pi5 bootloader EEPROM release notes
2023-10-18: Display autodetect + HAT gpiomap (default + latest)
2024-04-20: Fix SDRAM refesh timing (default) (automatic update)
* Fix a possible performance regression on Pi5.
2024-04-18: Promote the 2024-04-17 release to the default release (default) (automatic update)
* Select pieeprom-2024-04-17.bin to be the new default release and bump the
automatic update minimum version to this.
2024-04-18: Update RP1 firmware to extend PCIe L1 entry timeout to 32 us (latest)
* Extend PCIe L1 entry timeout to 32us
Fix xhci soft reset on link-down
Set useful xhci compatibility bits in GUCTL
See https://github.com/raspberrypi/firmware/issues/1877
2024-04-17: Fix TRYBOOT flag in secure-boot mode (latest)
* Fix issue that caused the TRYBOOT flag to be lost in secure-boot mode.
* dtoverlay: Use %u when converting u32s to strings
See: https://github.com/raspberrypi/linux/issues/6039
* Improved debug messages for secure-boot.
* Generate the bootloader diagnostics qrcode at run time.
2024-04-05: HAT+ fixes for max-current, custom CA cert for net install and enable over-clocking to > 3GHz (latest)
* bootloader: clock_2712: Remove restriction on arm_freq <= 3000
See: https://github.com/raspberrypi/firmware/issues/1876
* arm_dt: Update max_current to match HAT value
* arm_dt: Remove unused legacy parameters (core_freq, arm_freq, uart0_clkrate and cache_line_size)
* Add support for custom CA cert for network install
You need to specify
HTTP_HOST=myhost.com
HTTP_PATH=/path/to/files
HTTP_CACERT_HASH=<hash>
where <hash> is a sha256 hash of the der encoded ca certificate.
CA cert is added using rpi-eeprom-config.
* Optimise Vbat current draw with charging disabled
* Display OTP boot status in UART log messages.
* Preliminary support for secure-boot OTP provisioning.
* Update PCIE DET_WAKE pinmux for D0 products
2024-02-16: u-boot loading and thermal throttling fixes (latest) (default)
* arm_loader: Move non-kernels back to 512KB
See: https://github.com/raspberrypi/firmware/issues/1868
* Limit throttled frequency to OS requested frequency rather than
config.txt frequency.
See: https://github.com/raspberrypi/rpi-eeprom/issues/518
2024-02-14: Fix vcgencmd otp_dump and implement C(initial_turbo) (latest)
* Fix a regression that caused vcgencmd otp_dump to fail.
* Implement C(initial_turbo) on Pi5
See: https://github.com/raspberrypi/firmware/issues/1864
2024-02-08: Adjust SDRAM refresh based on temperature (latest)
* Adjust the SDRAM refresh interval based on the temperature. This
addresses the gap in performance between the 8GB and 4GB variants.
See https://github.com/raspberrypi/firmware/issues/1854
* Preliminary support for signed boot.
2024-02-05: Add support for HAT+ POE HATs (latest)
* Add support for probing HAT+ POE HATs
* Implement DWC3 specific XHCI quirks
2024-01-24: NVMe boot fix for WD NVMe (latest)
* Add a workaround for an issue seen when booting with WD Blue SN550 NVMe SSD
2024-01-22: Add support for network-install (latest)
* Fix issue boot.img end sector check - STABLE
See: https://github.com/raspberrypi/rpi-eeprom/issues/521
* Fix handling of files that use the last cluster in the partition
See: https://github.com/raspberrypi/rpi-eeprom/issues/521
* Fix SD card detection
See: https://github.com/raspberrypi/rpi-eeprom/issues/523
2024-01-15: Add support for network-install (latest)
* Add support for Network Install
* Preliminary D0 firmware support
2024-01-08: Promote 2024-01-05 to default (automatic update)
2024-01-05: Fix handling of FAT files without LFNs.
* Fix issues with SFN entries sometimes being treated as LFNs
see https://github.com/raspberrypi/rpi-eeprom/issues/514
* Add a dedicated message for "M.2 HAT" not being found instead of
the generic 'unsupported boot order' message when NVMe boot is
skipped.
2023-12-17: Promote 2023-12-14 to default release
* Bump to the default release now that the partition number fix is confirmed.
2023-12-14: Fix boot partition parameter (latest)
* Fix an issue where the boot partition parameter in PM_RSTS was cleared
before being checked.
https://github.com/raspberrypi/firmware/issues/1853
* Add a specific fatal error pattern for RP1 not found - 4 long - 3 short
2023-12-12: Promote 2023-12-06 to default release.
2023-12-06: Initialise DWC PHY (latest)
* Initialise the DWC PHY to enable DWC host+peripheral support under Linux.
Requires https://github.com/raspberrypi/linux/commit/82069a7a02632aa60fa5c69415bf891ede7d6fd4
* Force PWM on 3V3 supply if cameras or HATs are connected or if power_force_3v3_pwm=1 in config.txt
Resolves an image quality issue with the GS camera.
* Add support for C(arm_min_freq) < 1500 MHz (must be at >= 200 MHz)
* Manufacturing test updates for DVFS.
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
* Fix SD power-on-reset
* Firmware support for improved watchdog driver
* Update DHCP Option97 to be R,P,i,5 on Pi5
2023-10-18: Display autodetect + HAT gpiomap (default + latest) (automatic update)
* Add support for HAT gpiomap for improved HAT compatibility.
* Add I2C probe for DSI display auto detect
@@ -11,7 +135,7 @@
* Update board-name - "Raspberry Pi 5"
2023-09-28: vcgencmd pmic_read_adcs fixes (automatic update)
* Fix the LDO names and current scaling codes
* Manufacturing test updates

View File

@@ -1,4 +1,4 @@
[all]
BOOT_UART=1
BOOT_ORDER=0xf41
BOOT_ORDER=0xf461
POWER_OFF_ON_HALT=0

View File

@@ -1,4 +1,4 @@
[all]
BOOT_UART=1
BOOT_ORDER=0xf41
BOOT_ORDER=0xf461
POWER_OFF_ON_HALT=0

View File

@@ -1,5 +1,5 @@
[all]
BOOT_UART=1
BOOT_ORDER=0xf14
BOOT_ORDER=0xf146
POWER_OFF_ON_HALT=0

View File

@@ -8,4 +8,4 @@ script_dir=$(cd "$(dirname "$0")" && pwd)
${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-10-18 "" "${script_dir}/2712-config" release-2712 rpi-boot-eeprom-recovery 2712
${script_dir}/make-release critical 2024-04-20 "" "${script_dir}/2712-config" release-2712 rpi-boot-eeprom-recovery 2712

View File

@@ -19,6 +19,8 @@ VALID_IMAGE_SIZES = [512 * 1024, 2 * 1024 * 1024]
BOOTCONF_TXT = 'bootconf.txt'
BOOTCONF_SIG = 'bootconf.sig'
PUBKEY_BIN = 'pubkey.bin'
CACERT_DER = 'cacert.der'
BOOTCODE_BIN = 'bootcode.bin'
# Each section starts with a magic number followed by a 32 bit offset to the
# next section (big-endian).
@@ -109,7 +111,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 +119,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 +135,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 +177,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):
"""
@@ -289,14 +298,22 @@ class BootloaderImage(object):
length = -1
is_last = False
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)):
if filename == BOOTCODE_BIN:
next_offset = 0
dst_filename = filename
i = 0
s = self._sections[i]
if s.magic == FILE_MAGIC and s.filename == filename:
is_last = (i == len(self._sections) - 1)
offset = s.offset
length = s.length
break
offset = s.offset
length = s.length
else:
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:
is_last = (i == len(self._sections) - 1)
offset = s.offset
length = s.length
break
# Find the start of the next non padding section
i += 1
@@ -310,30 +327,43 @@ class BootloaderImage(object):
debug('%s offset %d length %d is-last %d next %d' % (filename, ret[0], ret[1], ret[2], ret[3]))
return ret
def update(self, src_bytes, dst_filename):
def update(self, src_bytes, dst_filename, bootcode = False):
"""
Replaces a modifiable file with specified byte array.
"""
hdr_offset, length, is_last, next_offset = self.find_file(dst_filename)
update_len = len(src_bytes) + FILE_HDR_LEN
if bootcode:
hdr_offset, length, is_last, next_offset = self.find_file(dst_filename)
struct.pack_into('>L', self._bytes, hdr_offset + 4, len(src_bytes))
struct.pack_into(("%ds" % len(src_bytes)), self._bytes, hdr_offset + 8, src_bytes)
pad_start = hdr_offset + len(src_bytes) + 8
is_last = False
debug("bootcode padded to %d" % next_offset);
if next_offset < 128 * 1024:
raise Exception("update-bootcode: Can't update image - 128K must be reserved for bootcode")
if next_offset < 0:
raise Exception("update-bootcode: Failed to find next section")
if hdr_offset + update_len > self._image_size - ERASE_ALIGN_SIZE:
raise Exception('No space available - image past EOF.')
else:
hdr_offset, length, is_last, next_offset = self.find_file(dst_filename)
update_len = len(src_bytes) + FILE_HDR_LEN
if hdr_offset < 0:
raise Exception('Update target %s not found' % dst_filename)
if hdr_offset + update_len > self._image_size - ERASE_ALIGN_SIZE:
raise Exception('No space available - image past EOF.')
if hdr_offset + update_len > next_offset:
raise Exception('Update %d bytes is larger than section size %d' % (update_len, next_offset - hdr_offset))
if hdr_offset < 0:
raise Exception('Update target %s not found' % dst_filename)
new_len = len(src_bytes) + FILENAME_LEN + 4
struct.pack_into('>L', self._bytes, hdr_offset + 4, new_len)
struct.pack_into(("%ds" % len(src_bytes)), self._bytes,
hdr_offset + 4 + FILE_HDR_LEN, src_bytes)
if hdr_offset + update_len > next_offset:
raise Exception('Update %d bytes is larger than section size %d' % (update_len, next_offset - hdr_offset))
# If the new file is smaller than the old file then set any old
# data which is now unused to all ones (erase value)
pad_start = hdr_offset + 4 + FILE_HDR_LEN + len(src_bytes)
new_len = len(src_bytes) + FILENAME_LEN + 4
struct.pack_into('>L', self._bytes, hdr_offset + 4, new_len)
struct.pack_into(("%ds" % len(src_bytes)), self._bytes,
hdr_offset + 4 + FILE_HDR_LEN, src_bytes)
# If the new file is smaller than the old file then set any old
# data which is now unused to all ones (erase value)
pad_start = hdr_offset + 4 + FILE_HDR_LEN + len(src_bytes)
# Add padding up to 8-byte boundary
while pad_start % 8 != 0:
@@ -372,10 +402,20 @@ class BootloaderImage(object):
Replaces the contents of dst_filename in the EEPROM with the contents of src_file.
"""
src_bytes = open(src_filename, 'rb').read()
if len(src_bytes) > MAX_FILE_SIZE:
bootcode = dst_filename == BOOTCODE_BIN
if not bootcode and len(src_bytes) > MAX_FILE_SIZE:
raise Exception("src file %s is too large (%d bytes). The maximum size is %d bytes."
% (src_filename, len(src_bytes), MAX_FILE_SIZE))
self.update(src_bytes, dst_filename)
self.update(src_bytes, dst_filename, bootcode)
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):
"""
@@ -392,14 +432,22 @@ class BootloaderImage(object):
def get_file(self, filename):
hdr_offset, length, is_last, next_offset = self.find_file(filename)
offset = hdr_offset + 4 + FILE_HDR_LEN
file_bytes = self._bytes[offset:offset+length-FILENAME_LEN-4]
if filename == BOOTCODE_BIN:
offset = hdr_offset + 8
file_bytes = self._bytes[offset:offset+length]
else:
offset = hdr_offset + 4 + FILE_HDR_LEN
file_bytes = self._bytes[offset:offset+length-FILENAME_LEN-4]
return file_bytes
def extract_files(self):
for i in range(0, len(self._sections)):
s = self._sections[i]
if s.magic == FILE_MAGIC:
if s.magic == MAGIC and s.offset == 0:
file_bytes = self.get_file(BOOTCODE_BIN)
open(BOOTCODE_BIN, 'wb').write(file_bytes)
elif s.magic == FILE_MAGIC:
file_bytes = self.get_file(s.filename)
open(s.filename, 'wb').write(file_bytes)
@@ -415,6 +463,7 @@ class BootloaderImage(object):
sys.stdout.write(config_bytes)
def main():
global DEBUG
"""
Utility for reading and writing the configuration file in the
Raspberry Pi bootloader EEPROM image.
@@ -462,7 +511,7 @@ Operating modes:
The configuration file will be taken from:
* The blconfig reserved memory nvmem device
* The cached bootloader configuration 'vcgencmd bootloader_config'
* The current pending update - typically /boot/pieeprom.upd
* The current pending update - typically /boot/firmware/pieeprom.upd
sudo -E rpi-eeprom-config --edit [pieeprom.bin]
@@ -476,8 +525,7 @@ Operating modes:
the corresponding RSA public key.
Requires Python Cryptodomex libraries and OpenSSL. To install on Raspberry Pi OS run:-
sudo apt install openssl python-pip
sudo python3 -m pip install cryptodomex
sudo apt install python3-pycryptodome
rpi-eeprom-digest -k private.pem -i bootconf.txt -o bootconf.sig
rpi-eeprom-config --config bootconf.txt --digest bootconf.sig --pubkey public.pem --out pieeprom-signed.bin pieeprom.bin
@@ -495,11 +543,16 @@ See 'rpi-eeprom-update -h' for more information about the available EEPROM image
parser.add_argument('-c', '--config', help='Name of bootloader configuration file', required=False)
parser.add_argument('-e', '--edit', action='store_true', default=False, help='Edit the current EEPROM config')
parser.add_argument('-o', '--out', help='Name of output file', required=False)
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('-d', '--digest', help='Signed boot only. The name of the .sig file generated by rpi-eeprom-digest 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('-b', '--bootcode', help='Signed boot 2712 only. The name of the customer signed bootcode.bin file to store in the EEPROM', required=False)
parser.add_argument('-t', '--timestamp', help='Set the timestamp in the EEPROM image file', required=False)
parser.add_argument('--cacertder', help='The name of a CA Certificate DER encoded file to store in the EEPROM', required=False)
parser.add_argument('--debug', help='Debug logging for this tool', action='store_true', required=False)
parser.add_argument('eeprom', nargs='?', help='Name of EEPROM file to use as input')
args = parser.parse_args()
DEBUG = args.debug
if (args.edit or args.apply is not None) and os.getuid() != 0:
exit_error("--edit/--apply must be run as root")
@@ -518,7 +571,17 @@ 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.bootcode is not None:
image.update_file(args.bootcode, BOOTCODE_BIN)
if args.cacertder is not None:
image.update_file(args.cacertder, CACERT_DER)
if args.config is not None:
# The public key, EEPROM config and signature should be set together
if not os.path.exists(args.config):
exit_error("config file '%s' not found" % args.config)
image.update_file(args.config, BOOTCONF_TXT)
@@ -526,6 +589,9 @@ See 'rpi-eeprom-update -h' for more information about the available EEPROM image
image.update_file(args.digest, BOOTCONF_SIG)
if args.pubkey is not None:
image.update_key(args.pubkey, PUBKEY_BIN)
if args.config is not None or args.timestamp is not None or args.bootcode is not None or args.cacertder is not None:
debug("Writing image")
image.write()
else:
image.read()

View File

@@ -34,18 +34,27 @@ checkDependencies() {
if ! command -v xxd > /dev/null; then
die "xxd not found. Try installing the xxd package."
fi
fi
fi
}
usage() {
cat <<EOF
rpi-eeprom-digest [-k RSA_KEY] -i IMAGE -o OUTPUT
Creates a .sig file containing the sha256 digest of the IMAGE and an optional
RSA signature of that hash.
Tool to generate .sig files containing the SHA256 digest and optional
RSA signature. Typically this tool is used by rpi-eeprom-update to
generate a hash to guard against file-system corruption for EEPROM updates
OR for signing OS images (boot.img) for secure-boot.
This tool CANNOT be used directly to sign an bootloader EEPROM image
for secure-boot because the signed data is bootloader configuration file
rather than the entire flash image.
To create signed bootloader images please see
https://github.com/raspberrypi/usbboot/tree/master/secure-boot-recovery/README.md
Options:
-i The source image.
-i The source image e.g. boot.img
-o The name of the digest/signature file.
-k Optional RSA private key.
@@ -58,16 +67,20 @@ The bootloader only verifies RSA signatures in signed boot mode
Examples:
# Generate RSA signature for the EEPROM config file.
rpi-eeprom-digest -k private.pem -i bootconf.txt -o bootconf.sig
# Generate the normal sha256 hash to guard against file-system corruption
rpi-eeprom-digest -i pieeprom.bin -o pieeprom.sig
rpi-eeprom-digest -i vl805.bin -o vl805.sig
# Generate a signed OS ramdisk image for secure-boot
rpi-eeprom-digest -k private.pem -i boot.img -o boot.sig
# Generate RSA signature for the EEPROM config file
# As used by update-pieeprom.sh in usbboot/secure-boot-recovery
rpi-eeprom-digest -k private.pem -i bootconf.txt -o bootconf.sig
# To verify the signature of an existing .sig file using the public key.
# N.B The key file must be the PUBLIC key in PEM format.
rpi-eeprom-digest -k public.pem -i pieeprom.bin -v pieeprom.sig
rpi-eeprom-digest -k public.pem -i boot.bin -v boot.sig
EOF
exit 0

View File

@@ -19,6 +19,7 @@ elif [ -d /lib/firmware/raspberrypi/bootloader ] || [ -d /lib/firmware/raspberry
else
# Work from local git checkout
LOCAL_MODE=1
IGNORE_DPKG_CHECKSUMS=1
FIRMWARE_ROOT="${script_dir}/firmware"
fi
@@ -89,6 +90,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 +101,7 @@ cleanup() {
TMP_EEPROM_IMAGE=
TMP_EEPROM_CONFIG=
NEW_EEPROM_CONFIG=
FLASHROM_LOG=
}
trap cleanup EXIT
@@ -105,6 +110,10 @@ die() {
exit ${EXIT_FAILED}
}
warn() {
echo "$@" >&2
}
getBootloaderConfig() {
# Prefer extracting bootloader's config from DT.
#
@@ -169,7 +178,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
}
@@ -180,9 +196,9 @@ applyRecoveryUpdate()
getBootloaderCurrentVersion
BOOTLOADER_UPDATE_VERSION=$(strings "${BOOTLOADER_UPDATE_IMAGE}" | grep BUILD_TIMESTAMP | sed 's/.*=//g')
if [ "${BOOTLOADER_CURRENT_VERSION}" -gt "${BOOTLOADER_UPDATE_VERSION}" ]; then
echo " WARNING: Installing an older bootloader version."
echo " Update the rpi-eeprom package to fetch the latest bootloader images."
echo
warn " WARNING: Installing an older bootloader version."
warn " Update the rpi-eeprom package to fetch the latest bootloader images."
warn
fi
echo " CURRENT: $(date -u "-d@${BOOTLOADER_CURRENT_VERSION}") (${BOOTLOADER_CURRENT_VERSION})"
echo " UPDATE: $(date -u "-d@${BOOTLOADER_UPDATE_VERSION}") (${BOOTLOADER_UPDATE_VERSION})"
@@ -200,7 +216,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 +241,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 +253,34 @@ 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. This could take up to a minute. Please wait"
echo
echo "*** Do not disconnect the power until the update is complete ***"
echo
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 +311,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
warn "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
warn "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
}
@@ -309,7 +370,7 @@ getBootloaderUpdateVersion() {
}
chipNotSupported() {
echo "This tool only works with Raspberry Pi4 and Rapberry Pi5"
echo "Device does not a have a Raspberry Pi bootloader EEPROM (e.g. Pi 4 or Pi 5). Skipping bootloader update."
exit ${EXIT_SUCCESS}
}
@@ -334,17 +395,29 @@ 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
# 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:-1695896697}"
BOOTLOADER_AUTO_UPDATE_MIN_VERSION="${BOOTLOADER_AUTO_UPDATE_MIN_VERSION:-1713610410}"
SPIDEV=/dev/spidev10.0
# Default is to use flashrom if availableon BCM2712
RPI_EEPROM_USE_FLASHROM=${RPI_EEPROM_USE_FLASHROM:-1}
else
chipNotSupported
fi
# Default to off - in the future Raspberry Pi 5 may default to using flashrom if
# flashrom is available.
if [ "${AUTO_UPDATE_BOOTLOADER}" = 1 ] || [ -n "${BOOTLOADER_UPDATE_IMAGE}" ]; then
[ -z "${RPI_EEPROM_USE_FLASHROM}" ] && RPI_EEPROM_USE_FLASHROM=0
if [ "${RPI_EEPROM_USE_FLASHROM}" -eq 1 ] && ! command -v flashrom > /dev/null; then
warn "WARNING: flashrom not found. Setting RPI_EEPROM_USE_FLASHROM to 0"
RPI_EEPROM_USE_FLASHROM=0
fi
fi
FIRMWARE_IMAGE_DIR="${FIRMWARE_ROOT}-${BCM_CHIP}/${FIRMWARE_RELEASE_STATUS}"
if ! [ -d "${FIRMWARE_IMAGE_DIR}" ]; then
# Use unadorned name for backwards compatiblity
@@ -361,6 +434,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
@@ -378,11 +463,15 @@ checkDependencies() {
die "lspci not found. Try installing the pciutils package."
fi
if ! command -v strings > /dev/null; then
die "strings not found. Try installing the binutils package."
fi
# vcgencmd bootloader_version is deprecated. Use device-tree if available to
# reduce the number of dependencies on VCHI.
if ! [ -f "${DT_BOOTLOADER_TS}" ]; then
if ! command -v vcgencmd > /dev/null; then
die "vcgencmd not found. Try installing the libraspberrypi-bin package."
die "vcgencmd not found. Try installing the raspi-utils package."
fi
fi
@@ -401,7 +490,7 @@ checkDependencies() {
fi
if ! command -v sha256sum > /dev/null; then
die "sha256sum not found. Try installing the coreutilities package."
die "sha256sum not found. Try installing the coreutils package."
fi
if [ "${BCM_CHIP}" = 2711 ] && [ ! -f "${RECOVERY_BIN}" ]; then
@@ -454,7 +543,6 @@ Options:
Ignores the FREEZE_VERSION flag in bootloader and is intended for manual
firmware updates.
-h Display help text and exit
-i Ignore package checksums - for rpi-eeprom developers.
-j Write status information using JSON notation (requires -m option)
-l Returns the full path to the latest available EEPROM image file according
to the FIRMWARE_RELEASE_STATUS and FIRMWARE_IMAGE_DIR settings.
@@ -492,10 +580,10 @@ to be stable.
default:
The default bootloader image which supports all current models and hardware
revisions.
If a critical bug fix is required then the minimum default version number
(BOOTLOADER_AUTO_UPDATE_MIN_VERSION) in the rpi-eeprom package is updated
causing the bootloader to be automatically updated.
revisions. If there is an important bug fix or hardware change that could
affect most users then the BOOTLOADER_AUTO_UPDATE_MIN_VERSION is updated
causing the update to be applied the next time the rpi-eeprom APT package is
updated.
latest:
Contains new features, bug fixes and performance improvements.
@@ -545,6 +633,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}
}
@@ -598,7 +702,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
@@ -611,11 +717,11 @@ findBootFS()
if [ "${BCM_CHIP}" = 2712 ]; then
if ! [ -e "${BOOTFS}/config.txt" ]; then
echo "WARNING: BOOTFS: \"${BOOTFS}/config.txt\" not found. Please check boot directory"
warn "WARNING: BOOTFS: \"${BOOTFS}/config.txt\" not found. Please check boot directory"
fi
else
if [ "$(find "${BOOTFS}/" -name "*.elf" | wc -l)" = 0 ]; then
echo "WARNING: BOOTFS: \"${BOOTFS}\" contains no .elf files. Please check boot directory"
warn "WARNING: BOOTFS: \"${BOOTFS}\" contains no .elf files. Please check boot directory"
fi
fi
}
@@ -717,7 +823,7 @@ checkAndApply()
fi
if [ "${ACTION_UPDATE_BOOTLOADER}" = 1 ] || [ "${ACTION_UPDATE_VL805}" = 1 ]; then
echo "*** INSTALLING EEPROM UPDATES ***"
echo "*** PREPARING EEPROM UPDATES ***"
echo ""
printVersions
@@ -730,7 +836,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
@@ -822,7 +928,8 @@ AUTO_UPDATE_VL805=0
SILENT_UPDATE=0
MACHINE_OUTPUT=""
JSON_OUTPUT="no"
IGNORE_DPKG_CHECKSUMS=${LOCAL_MODE}
# Ignore dpkg checksums by default so that rpi-update can install new binaries into /lib/firmware
IGNORE_DPKG_CHECKSUMS=${IGNORE_DPKG_CHECKSUMS:-1}
PACKAGE_INFO_DIR="/var/lib/dpkg/info/"
if [ ! -d "${PACKAGE_INFO_DIR}" ]; then
IGNORE_DPKG_CHECKSUMS=1
@@ -852,7 +959,9 @@ while getopts A:abdhilf:m:ju:rs option; do
;;
f) BOOTLOADER_UPDATE_IMAGE="${OPTARG}"
;;
i) IGNORE_DPKG_CHECKSUMS=1
i)
# Script default is 1 but this could have been set to zero in the defaults file
IGNORE_DPKG_CHECKSUMS=1
;;
j) JSON_OUTPUT="yes"
;;

View File

@@ -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

View File

@@ -6,6 +6,8 @@ FORCE=0
READ_KEY=""
WRITE_KEY=""
OUTPUT_BINARY=0
ROW_COUNT=8
ROW_OFFSET=0
die() {
echo "$@" >&2
@@ -25,10 +27,12 @@ usage() {
N.B. OTP bits can never change from 1 to 0.
-w Writes the new key to OTP memory.
-y Skip the confirmation prompt when writing to OTP.
-l Specify key length in words. Defaults to 8 words (32 bytes). Pi 5 supports up to 16 words (64 bytes).
-o word Offset into the keystore to use, e.g. 0-7 for Pi 4, 0-15 for Pi 5. Defaults to zero.
<key> is a 64 digit hex number (256 bit) e.g. to generate a 256 random number run 'openssl rand -hex 32'
<key> is usually a 64 digit hex number (256 bit) e.g. to generate a 256 random number run 'openssl rand -hex 32'
IMPORTANT: Raspberry Pi 4 and earlier revisions do not have a hardware secure key store. These OTP rows are visible
IMPORTANT: Raspberry Pi 5 and earlier revisions do not have a hardware secure key store. These OTP rows are visible
to any user in the 'video' group via vcmailbox. Therefore this functionality is only suitable for key
storage if the OS has already been restricted using the signed boot functionality.
@@ -46,8 +50,8 @@ check_key_set() {
}
read_key() {
out=READ_KEY="$(vcmailbox 0x00030081 40 40 0 8 0 0 0 0 0 0 0 0)" || die "Failed to read the current key from OTP"
READ_KEY="$(echo "${out}" | sed 's/0x//g' | awk '{for(i=8;i<16;i++) printf $i; print ""}')"
out=READ_KEY="$(vcmailbox 0x00030081 $((8 + ROW_COUNT * 4)) $((8 + ROW_COUNT * 4)) $ROW_OFFSET $ROW_COUNT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)" || die "Failed to read the current key from OTP"
READ_KEY="$(echo "${out}" | sed 's/0x//g' | awk -v last=$((8 + ROW_COUNT)) '{for(i=8;i<last;i++) printf $i; print ""}')"
}
write_key() {
@@ -55,19 +59,19 @@ write_key() {
# Normalize formatting and check the length
key="$(echo "${key}" | tr 'A-Z' 'a-z')"
key="$(echo "${key}" | sed 's/[^a-f0-9]//g')"
[ "$(echo -n "${key}" | wc -c)" = 64 ] || die "Invalid key parameter"
[ "$(echo -n "${key}" | wc -c)" = $((ROW_COUNT * 4 * 2)) ] || die "Invalid key parameter"
count=0
key_params=""
while [ ${count} -lt 8 ]; do
while [ ${count} -lt $ROW_COUNT ]; do
start=$(((count * 8) + 1))
end=$((start + 7))
key_params="${key_params} 0x$(echo -n "${key}" | cut -c${start}-${end})"
count=$((count + 1))
end=$((start + 7))
key_params="${key_params} 0x$(echo -n "${key}" | cut -c${start}-${end})"
count=$((count + 1))
done
if [ "${YES}" = 0 ] && [ -t 0 ]; then
echo "Write ${key} to OTP?"
echo "Write ${key} of $ROW_COUNT words to OTP starting at word offset $ROW_OFFSET?"
echo
echo "WARNING: Updates to OTP registers are permanent and cannot be undone."
@@ -79,13 +83,13 @@ write_key() {
fi
fi
vcmailbox 0x38081 40 40 0 8 ${key_params} || die "Failed to write key"
vcmailbox 0x38081 $((8 + ROW_COUNT * 4)) $((8 + ROW_COUNT * 4)) $ROW_OFFSET $ROW_COUNT ${key_params} || die "Failed to write key"
read_key
[ "${READ_KEY}" = "${key}" ] || die "Key readback check failed. ${out}"
}
YES=0
while getopts bcfhw:y option; do
while getopts bcfhw:yl:o: option; do
case "${option}" in
b) OUTPUT_BINARY=1
;;
@@ -102,13 +106,61 @@ while getopts bcfhw:y option; do
w) WRITE_KEY="${OPTARG}"
;;
y) YES=1
;;
;;
l) ROW_COUNT="${OPTARG}"
;;
o) ROW_OFFSET="${OPTARG}"
;;
*) echo "Unknown argument \"${option}\""
usage
;;
esac
done
if [ -f "/sys/firmware/devicetree/base/system/linux,revision" ]; then
BOARD_INFO="$(od -v -An -t x1 /sys/firmware/devicetree/base/system/linux,revision | tr -d ' \n')"
elif grep -q Revision /proc/cpuinfo; then
BOARD_INFO="$(sed -n '/^Revision/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo)"
elif command -v vcgencmd > /dev/null; then
BOARD_INFO="$(vcgencmd otp_dump | grep '30:' | sed 's/.*://')"
else
die "No Raspberry Pi board info found"
fi
if [ $(((0x$BOARD_INFO >> 23) & 1)) = 0 ]; then
die "Chip not supported"
fi
if [ $(((0x$BOARD_INFO >> 12) & 15)) = 3 ]; then
MAX_ROW_COUNT=8
elif [ $(((0x$BOARD_INFO >> 12) & 15)) = 4 ]; then
MAX_ROW_COUNT=16
else
die "Chip not supported"
fi
if [ -z "$ROW_COUNT" ] || [ "$ROW_COUNT" -ne "$ROW_COUNT" ] 2>/dev/null; then
die "Key length not a number"
fi
if [ $ROW_COUNT -lt 1 ]; then
die "Length too small"
fi
if [ $ROW_COUNT -gt $MAX_ROW_COUNT ]; then
die "Length too big"
fi
if [ -z "$ROW_OFFSET" ] || [ "$ROW_OFFSET" -ne "$ROW_OFFSET" ] 2>/dev/null; then
die "Offset is not a number"
fi
if [ $ROW_OFFSET -lt 0 ]; then
die "Offset too small"
fi
if [ ${ROW_OFFSET} -gt $((MAX_ROW_COUNT - ROW_COUNT)) ]; then
die "Offset too big"
fi
if [ -z $(which vcmailbox) ]; then
die "vcmailbox command missing"
fi
if [ -z $(which xxd) ] && [ "$OUTPUT_BINARY" -eq "1" ]; then
die "xxd command missing"
fi
if [ -n "${WRITE_KEY}" ]; then
if [ "${FORCE}" = 0 ] && check_key_set; then
die "Current key is non-zero. Specify -f to write anyway"

229
tools/rpi-sign-bootcode Executable file
View File

@@ -0,0 +1,229 @@
#!/usr/bin/env python3
import argparse
import base64
import struct
import sys
# python3 -m pip install pycryptodomex
from Cryptodome.Hash import HMAC, SHA1, SHA256
from Cryptodome.PublicKey import RSA
from Cryptodome.Signature import pkcs1_15
_CONFIG = {'DEBUG': False}
MAX_BIN_SIZE = 110 * 1024
def debug(msg):
"""
Outputs the msg string to stdout if DEBUG is enabled (via -d)
"""
if _CONFIG['DEBUG']:
sys.stderr.write(str(msg) + '\n')
class ImageFile:
"""
Signed binary image
"""
def __init__(self, filename, max_size_kb):
self._filename = filename
self._bytes_written = 0
if self._filename is None:
self._of = sys.stdout
else:
self._of = open(self._filename, "wb")
self._max_size_kb = max_size_kb
self._bytes = bytearray()
debug("%8s %20s: [%6s] %s" % ('OFFSET', 'TYPE', 'SIZE', 'DESCRIPTION'))
debug("")
def append(self, data):
"""
Appends a blob of binary data to the image
"""
self._bytes.extend(data)
def append_file(self, source_file):
"""
Appends the binary contents of source_file to the current image. If
source_file is None then a base64 encoded blob is read from stdin.
"""
if source_file is None:
b64 = ""
for l in sys.stdin.readlines():
b64 += l
file_bytes = base64.b64decode(b64)
else:
file_bytes = bytearray(open(source_file, 'rb').read())
size = len(file_bytes)
debug("%08x %20s: [%6d] %s" % (self.pos(), 'FILE', size, source_file))
self.append(file_bytes)
def append_keynum(self, keynum):
"""
Appends a given key number as a 32-bit LE integer.
"""
if (keynum < 0 or keynum > 4) and keynum != 16:
raise Exception("Bad key number %d" % keynum)
debug("%08x %20s: [%6d] %d" % (self.pos(), "KEYNUM", 4, keynum))
self.append(struct.pack('<i', keynum))
def append_version(self, version):
"""
Appends a version number, 0-32 to avoid firmware rollback, a Raspberry Pi
with OTP bit n set will not execute a firmware without bit n set.
"""
if version < 0 or version > 32:
raise Exception("Bad version number %d must be between 0-32" % version)
debug("%08x %20s: [%6d] %d" % (self.pos(), "VERSION", 4, version))
self.append(struct.pack('<i', version))
def append_length(self):
"""
Appends the current length to the image as a 32-bit LE integer
"""
length = len(self._bytes)
debug("%08x %20s: [%6d] %d" % (self.pos(), "LEN", 4, length))
self.append(struct.pack('<i', length))
def append_public_key(self, pem_file):
"""
Converts an RSA public key into the format expected by the ROM
and appends it to the image.
If a private key is passed then only the public key part is extracted.
"""
arr = bytearray()
key = RSA.importKey(open(pem_file, 'r').read())
if key.size_in_bits() != 2048:
raise Exception("RSA key size must be 2048")
# Export N and E in little endian format
arr.extend(key.n.to_bytes(256, byteorder='little'))
arr.extend(key.e.to_bytes(8, byteorder='little'))
debug("%08x %20s: [%6d] %s" % (self.pos(), 'RSA', len(arr), pem_file))
self.append(arr)
def append_rsa_signature(self, digest_alg, private_pem):
"""
Append a RSA 2048 signature of the SHA256 of the data so far
"""
key = RSA.importKey(open(private_pem, 'r').read())
if key.size_in_bits() != 2048:
raise Exception("RSA key size must be 2048")
if digest_alg == 'sha256':
digest = SHA256.new(self._bytes)
elif digest_alg == 'sha1':
digest = SHA1.new(self._bytes)
signature = pkcs1_15.new(key).sign(digest)
self.append(signature)
debug("%08x %20s: [%6d] digest %s signature %s" % (self.pos(), 'RSA2048 - SHA256', len(signature), digest.hexdigest(), signature.hex()))
def append_digest(self, digest_alg, hmac_keyfile):
"""
Appends the hash/digest to the image
"""
if hmac_keyfile is not None:
hmac_key = str(open(hmac_keyfile, 'r').read()).strip()
expected_keylen = 40
if len(hmac_key) != expected_keylen:
raise Exception("Bad key length %d expected %d" % (len(hmac_key), expected_keylen))
if digest_alg == 'hmac-sha256':
digest = HMAC.new(base64.b16decode(hmac_key, True), self._bytes, digestmod=SHA256)
elif digest_alg == 'hmac-sha1':
digest = HMAC.new(base64.b16decode(hmac_key, True), self._bytes, digestmod=SHA1)
elif digest_alg == 'sha256':
digest = SHA256.new(self._bytes)
elif digest_alg == 'sha1':
digest = SHA1.new(self._bytes)
else:
raise Exception("Digest not supported %s" % (digest_alg))
debug("%08x %20s: [%6d] %s" % (self.pos(), digest_alg, len(digest.digest()), digest.hexdigest()))
self.append(digest.digest())
def pos(self):
return len(self._bytes)
def write(self):
if len(self._bytes) > self._max_size_kb:
raise Exception("Signed binary size %d is too large. Max size %d" % (len(self._bytes), MAX_BIN_SIZE))
debug("Image size %d" % len(self._bytes))
if self._filename is None:
self._of.buffer.write(base64.b64encode(self._bytes))
else:
self._of.write(self._bytes)
def close(self):
self._of.close()
def create_2711_image(output, bootcode, private_key, private_keynum, hmac):
"""
Create a 2711 C0 secure-boot compatible seconds stage signed binary.
"""
image = ImageFile(output, MAX_BIN_SIZE)
image.append_file(bootcode)
image.append_length()
image.append_keynum(private_keynum)
image.append_rsa_signature('sha1', private_key)
image.append_digest('hmac-sha1', hmac)
image.write()
image.close()
def create_2712_image(output, bootcode, private_key, private_keynum, private_version):
"""
Create 2712 signed bootloader. The HMAC is removed and the full public key is appended.
"""
image = ImageFile(output, MAX_BIN_SIZE)
image.append_file(bootcode)
image.append_length()
image.append_keynum(private_keynum)
image.append_version(private_version)
image.append_rsa_signature('sha256', private_key)
image.append_public_key(private_key)
image.write()
image.close()
def main():
help_text = """
Signs a second stage bootloader image.
Examples:
2711 mode:
rpi-sign-bootcode --debug -c 2711 -i bootcode.bin.clr -o bootcode.bin -k 2711_rsa_priv_0.pem -n 0 -m bootcode-production.key
2712 C1 and D0 mode:
* HMAC not included on 2712
* RSA public key included - ROM just contains the hashes of the RPi public keys.
Customer counter-signed signed:
* Exactly the same as Raspberry Pi signing but the input is the Raspberry Pi signed bootcode.bin
* The key number will probably always be 16 to indicate a customer signing
rpi-sign-bootcode --debug -c 2712 -i bootcode.bin.sign2 -o bootcode.bin -k customer.pem
"""
parser = argparse.ArgumentParser(help_text)
parser.add_argument('-o', '--output', required=False, help='Output filename . If not specified the signed images is written to stdout in base64 format')
parser.add_argument('-c', '--chip', required=True, type=int, help='Chip number')
parser.add_argument('-i', '--input', required=False, help='Path of the unsigned bootcode.bin file OR RPi signed bootcode file sign with the customer key. If NULLL the binary is read from stdin in base64 format')
parser.add_argument('-m', '--hmac', required=False, help='Path of the HMAC key file')
parser.add_argument('-k', '--private-key', dest='private_key', required=True, help='Path of RSA private key (PEM format)')
parser.add_argument('-n', '--private-keynum', dest='private_keynum', required=False, default=0, type=int, help='ROM key index for RPi signing stage')
parser.add_argument('-d', '--debug', action='store_true')
parser.add_argument('-v', '--private-version', dest='private_version', required=True, type=int, help='Version of firmware, stops firmware rollback, only valid 0-31')
args = parser.parse_args()
_CONFIG['DEBUG'] = args.debug
if args.chip == 2711:
if args.hmac is None:
raise Exception("HMAC key requried for 2711")
create_2711_image(args.output, args.input, args.private_key, args.private_keynum, args.hmac)
elif args.chip == 2712:
create_2712_image(args.output, args.input, args.private_key, args.private_keynum, args.private_version)
if __name__ == '__main__':
main()