mirror of
https://github.com/raspberrypi/rpi-eeprom.git
synced 2026-01-21 14:53:32 +08:00
Compare commits
53 Commits
v2023.12.0
...
v2024.02.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a1a01c24f | ||
|
|
f4580cd6f5 | ||
|
|
c0a207f452 | ||
|
|
76b990a894 | ||
|
|
afa5822e03 | ||
|
|
a2fb4ed28d | ||
|
|
ca7a39efe9 | ||
|
|
c94506e598 | ||
|
|
61023cbd32 | ||
|
|
d8abe8c67d | ||
|
|
14f05613b4 | ||
|
|
07bf72a919 | ||
|
|
b745226b41 | ||
|
|
c478689de0 | ||
|
|
8c67b27665 | ||
|
|
18620870d7 | ||
|
|
11c64e3721 | ||
|
|
36e58db5c2 | ||
|
|
b1a715b256 | ||
|
|
0e8ecbcf83 | ||
|
|
d4918d4d4c | ||
|
|
b5c7f1bee6 | ||
|
|
c987375f1d | ||
|
|
99cb0bdaa2 | ||
|
|
a8f2eb75b5 | ||
|
|
606c5d25e5 | ||
|
|
88b33ab030 | ||
|
|
a7f982962b | ||
|
|
9df346bc1c | ||
|
|
68fca2166b | ||
|
|
eca47c5f4c | ||
|
|
097e2d0573 | ||
|
|
4b8e875510 | ||
|
|
21a78a91de | ||
|
|
cc020609fb | ||
|
|
d5f1ab30fa | ||
|
|
8855da9889 | ||
|
|
a5b4f91caf | ||
|
|
7232154170 | ||
|
|
759460850c | ||
|
|
9e0bffb291 | ||
|
|
258d0114c0 | ||
|
|
0cd761bc84 | ||
|
|
72cedfe5ee | ||
|
|
14e934cee3 | ||
|
|
e407fb0030 | ||
|
|
b405ed7465 | ||
|
|
ef0cfffced | ||
|
|
a66e79ba99 | ||
|
|
745eabf90e | ||
|
|
043841636c | ||
|
|
3f325bd482 | ||
|
|
52c5d89d48 |
6
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
6
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -6,7 +6,7 @@ body:
|
|||||||
value: |
|
value: |
|
||||||
**Is this the right place for my bug report?**
|
**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 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/).
|
* 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.
|
* 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?
|
description: On which device you are facing the bug?
|
||||||
multiple: true
|
multiple: true
|
||||||
options:
|
options:
|
||||||
|
- Raspberry Pi 5
|
||||||
- Raspberry Pi 4 Mod. B
|
- Raspberry Pi 4 Mod. B
|
||||||
- Raspberry Pi 400
|
- Raspberry Pi 400
|
||||||
- Raspberry Pi CM4
|
- Raspberry Pi CM4
|
||||||
- Raspberry Pi CM4 Lite
|
- Raspberry Pi CM4 Lite
|
||||||
|
- Raspberry Pi CM4-S
|
||||||
- Other
|
- Other
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
@@ -52,7 +54,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Bootloader configuration.
|
label: Bootloader configuration.
|
||||||
description: |
|
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-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.
|
* `rpi-eeprom-config pieeprom.upd` can be used to read the contents of an EEPROM image.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ To reset the bootloader back to factory defaults use [Raspberry Pi Imager](https
|
|||||||
|
|
||||||
# Bootloader documentation
|
# Bootloader documentation
|
||||||
* [Config.txt boot options](https://www.raspberrypi.com/documentation/computers/config_txt.html#boot-options)
|
* [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 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-4-bootloader-configuration)
|
* [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)
|
* [Updating the Compute Module 4 bootloader](https://www.raspberrypi.com/documentation/computers/compute-module.html#cm4bootloader)
|
||||||
* [Releases and release notes](releases.md)
|
* [Releases and release notes](releases.md)
|
||||||
|
|||||||
BIN
firmware-2711/default/pieeprom-2024-04-15.bin
Normal file
BIN
firmware-2711/default/pieeprom-2024-04-15.bin
Normal file
Binary file not shown.
Binary file not shown.
BIN
firmware-2711/latest/pieeprom-2024-01-18.bin
Normal file
BIN
firmware-2711/latest/pieeprom-2024-01-18.bin
Normal file
Binary file not shown.
BIN
firmware-2711/latest/pieeprom-2024-01-22.bin
Normal file
BIN
firmware-2711/latest/pieeprom-2024-01-22.bin
Normal file
Binary file not shown.
BIN
firmware-2711/latest/pieeprom-2024-04-15.bin
Normal file
BIN
firmware-2711/latest/pieeprom-2024-04-15.bin
Normal file
Binary file not shown.
BIN
firmware-2711/latest/pieeprom-2024-04-17.bin
Normal file
BIN
firmware-2711/latest/pieeprom-2024-04-17.bin
Normal file
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,29 @@
|
|||||||
# Raspberry Pi4 bootloader EEPROM release notes
|
# 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
|
## 2023-08-01 - Remove beta release folder
|
||||||
* Remove the beta release folder and provide a symlink to stable
|
* Remove the beta release folder and provide a symlink to stable
|
||||||
for backwards compatibility for anyone who has beta in
|
for backwards compatibility for anyone who has beta in
|
||||||
|
|||||||
BIN
firmware-2712/default/pieeprom-2023-12-14.bin
Normal file
BIN
firmware-2712/default/pieeprom-2023-12-14.bin
Normal file
Binary file not shown.
BIN
firmware-2712/default/pieeprom-2024-01-05.bin
Normal file
BIN
firmware-2712/default/pieeprom-2024-01-05.bin
Normal file
Binary file not shown.
BIN
firmware-2712/default/pieeprom-2024-02-16.bin
Normal file
BIN
firmware-2712/default/pieeprom-2024-02-16.bin
Normal file
Binary file not shown.
BIN
firmware-2712/default/pieeprom-2024-04-17.bin
Normal file
BIN
firmware-2712/default/pieeprom-2024-04-17.bin
Normal file
Binary file not shown.
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2023-12-14.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2023-12-14.bin
Normal file
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2024-01-05.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2024-01-05.bin
Normal file
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2024-01-15.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2024-01-15.bin
Normal file
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2024-01-22.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2024-01-22.bin
Normal file
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2024-01-24.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2024-01-24.bin
Normal file
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2024-02-05.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2024-02-05.bin
Normal file
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2024-02-08.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2024-02-08.bin
Normal file
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2024-02-14.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2024-02-14.bin
Normal file
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2024-02-16.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2024-02-16.bin
Normal file
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2024-04-05.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2024-04-05.bin
Normal file
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2024-04-17.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2024-04-17.bin
Normal file
Binary file not shown.
BIN
firmware-2712/latest/pieeprom-2024-04-18.bin
Normal file
BIN
firmware-2712/latest/pieeprom-2024-04-18.bin
Normal file
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,97 @@
|
|||||||
# Raspberry Pi5 bootloader EEPROM release notes
|
# Raspberry Pi5 bootloader EEPROM release notes
|
||||||
|
|
||||||
|
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-12: Promote 2023-12-06 to default release.
|
||||||
|
|
||||||
2023-12-06: Initialise DWC PHY (latest)
|
2023-12-06: Initialise DWC PHY (latest)
|
||||||
|
|||||||
@@ -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
|
${script_dir}/make-release critical 2023-01-11 000138c0 "${script_dir}/2711-config" release-2711 rpi-boot-eeprom-recovery 2711
|
||||||
|
|
||||||
# Pi5
|
# 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-17 "" "${script_dir}/2712-config" release-2712 rpi-boot-eeprom-recovery 2712
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ VALID_IMAGE_SIZES = [512 * 1024, 2 * 1024 * 1024]
|
|||||||
BOOTCONF_TXT = 'bootconf.txt'
|
BOOTCONF_TXT = 'bootconf.txt'
|
||||||
BOOTCONF_SIG = 'bootconf.sig'
|
BOOTCONF_SIG = 'bootconf.sig'
|
||||||
PUBKEY_BIN = 'pubkey.bin'
|
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
|
# Each section starts with a magic number followed by a 32 bit offset to the
|
||||||
# next section (big-endian).
|
# next section (big-endian).
|
||||||
@@ -296,14 +298,22 @@ class BootloaderImage(object):
|
|||||||
length = -1
|
length = -1
|
||||||
is_last = False
|
is_last = False
|
||||||
|
|
||||||
next_offset = self._image_size - ERASE_ALIGN_SIZE # Don't create padding inside the bootloader scratch page
|
if filename == BOOTCODE_BIN:
|
||||||
for i in range(0, len(self._sections)):
|
next_offset = 0
|
||||||
|
dst_filename = filename
|
||||||
|
i = 0
|
||||||
s = self._sections[i]
|
s = self._sections[i]
|
||||||
if s.magic == FILE_MAGIC and s.filename == filename:
|
offset = s.offset
|
||||||
is_last = (i == len(self._sections) - 1)
|
length = s.length
|
||||||
offset = s.offset
|
else:
|
||||||
length = s.length
|
next_offset = self._image_size - ERASE_ALIGN_SIZE # Don't create padding inside the bootloader scratch page
|
||||||
break
|
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
|
# Find the start of the next non padding section
|
||||||
i += 1
|
i += 1
|
||||||
@@ -317,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]))
|
debug('%s offset %d length %d is-last %d next %d' % (filename, ret[0], ret[1], ret[2], ret[3]))
|
||||||
return ret
|
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.
|
Replaces a modifiable file with specified byte array.
|
||||||
"""
|
"""
|
||||||
hdr_offset, length, is_last, next_offset = self.find_file(dst_filename)
|
if bootcode:
|
||||||
update_len = len(src_bytes) + FILE_HDR_LEN
|
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:
|
else:
|
||||||
raise Exception('No space available - image past EOF.')
|
hdr_offset, length, is_last, next_offset = self.find_file(dst_filename)
|
||||||
|
update_len = len(src_bytes) + FILE_HDR_LEN
|
||||||
|
|
||||||
if hdr_offset < 0:
|
if hdr_offset + update_len > self._image_size - ERASE_ALIGN_SIZE:
|
||||||
raise Exception('Update target %s not found' % dst_filename)
|
raise Exception('No space available - image past EOF.')
|
||||||
|
|
||||||
if hdr_offset + update_len > next_offset:
|
if hdr_offset < 0:
|
||||||
raise Exception('Update %d bytes is larger than section size %d' % (update_len, next_offset - hdr_offset))
|
raise Exception('Update target %s not found' % dst_filename)
|
||||||
|
|
||||||
new_len = len(src_bytes) + FILENAME_LEN + 4
|
if hdr_offset + update_len > next_offset:
|
||||||
struct.pack_into('>L', self._bytes, hdr_offset + 4, new_len)
|
raise Exception('Update %d bytes is larger than section size %d' % (update_len, next_offset - hdr_offset))
|
||||||
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
|
new_len = len(src_bytes) + FILENAME_LEN + 4
|
||||||
# data which is now unused to all ones (erase value)
|
struct.pack_into('>L', self._bytes, hdr_offset + 4, new_len)
|
||||||
pad_start = hdr_offset + 4 + FILE_HDR_LEN + len(src_bytes)
|
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
|
# Add padding up to 8-byte boundary
|
||||||
while pad_start % 8 != 0:
|
while pad_start % 8 != 0:
|
||||||
@@ -379,10 +402,11 @@ class BootloaderImage(object):
|
|||||||
Replaces the contents of dst_filename in the EEPROM with the contents of src_file.
|
Replaces the contents of dst_filename in the EEPROM with the contents of src_file.
|
||||||
"""
|
"""
|
||||||
src_bytes = open(src_filename, 'rb').read()
|
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."
|
raise Exception("src file %s is too large (%d bytes). The maximum size is %d bytes."
|
||||||
% (src_filename, len(src_bytes), MAX_FILE_SIZE))
|
% (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):
|
def set_timestamp(self, timestamp):
|
||||||
"""
|
"""
|
||||||
@@ -408,14 +432,22 @@ class BootloaderImage(object):
|
|||||||
|
|
||||||
def get_file(self, filename):
|
def get_file(self, filename):
|
||||||
hdr_offset, length, is_last, next_offset = self.find_file(filename)
|
hdr_offset, length, is_last, next_offset = self.find_file(filename)
|
||||||
offset = hdr_offset + 4 + FILE_HDR_LEN
|
if filename == BOOTCODE_BIN:
|
||||||
file_bytes = self._bytes[offset:offset+length-FILENAME_LEN-4]
|
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
|
return file_bytes
|
||||||
|
|
||||||
def extract_files(self):
|
def extract_files(self):
|
||||||
for i in range(0, len(self._sections)):
|
for i in range(0, len(self._sections)):
|
||||||
s = self._sections[i]
|
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)
|
file_bytes = self.get_file(s.filename)
|
||||||
open(s.filename, 'wb').write(file_bytes)
|
open(s.filename, 'wb').write(file_bytes)
|
||||||
|
|
||||||
@@ -431,6 +463,7 @@ class BootloaderImage(object):
|
|||||||
sys.stdout.write(config_bytes)
|
sys.stdout.write(config_bytes)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
global DEBUG
|
||||||
"""
|
"""
|
||||||
Utility for reading and writing the configuration file in the
|
Utility for reading and writing the configuration file in the
|
||||||
Raspberry Pi bootloader EEPROM image.
|
Raspberry Pi bootloader EEPROM image.
|
||||||
@@ -478,7 +511,7 @@ Operating modes:
|
|||||||
The configuration file will be taken from:
|
The configuration file will be taken from:
|
||||||
* The blconfig reserved memory nvmem device
|
* The blconfig reserved memory nvmem device
|
||||||
* The cached bootloader configuration 'vcgencmd bootloader_config'
|
* 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]
|
sudo -E rpi-eeprom-config --edit [pieeprom.bin]
|
||||||
|
|
||||||
@@ -492,8 +525,7 @@ Operating modes:
|
|||||||
the corresponding RSA public key.
|
the corresponding RSA public key.
|
||||||
|
|
||||||
Requires Python Cryptodomex libraries and OpenSSL. To install on Raspberry Pi OS run:-
|
Requires Python Cryptodomex libraries and OpenSSL. To install on Raspberry Pi OS run:-
|
||||||
sudo apt install openssl python-pip
|
sudo apt install python3-pycryptodome
|
||||||
sudo python3 -m pip install cryptodomex
|
|
||||||
|
|
||||||
rpi-eeprom-digest -k private.pem -i bootconf.txt -o bootconf.sig
|
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
|
rpi-eeprom-config --config bootconf.txt --digest bootconf.sig --pubkey public.pem --out pieeprom-signed.bin pieeprom.bin
|
||||||
@@ -511,12 +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('-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('-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('-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('-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('-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('-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')
|
parser.add_argument('eeprom', nargs='?', help='Name of EEPROM file to use as input')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
DEBUG = args.debug
|
||||||
|
|
||||||
if (args.edit or args.apply is not None) and os.getuid() != 0:
|
if (args.edit or args.apply is not None) and os.getuid() != 0:
|
||||||
exit_error("--edit/--apply must be run as root")
|
exit_error("--edit/--apply must be run as root")
|
||||||
@@ -537,7 +573,15 @@ See 'rpi-eeprom-update -h' for more information about the available EEPROM image
|
|||||||
image = BootloaderImage(args.eeprom, args.out)
|
image = BootloaderImage(args.eeprom, args.out)
|
||||||
if args.timestamp is not None:
|
if args.timestamp is not None:
|
||||||
image.set_timestamp(args.timestamp)
|
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:
|
if args.config is not None:
|
||||||
|
# The public key, EEPROM config and signature should be set together
|
||||||
if not os.path.exists(args.config):
|
if not os.path.exists(args.config):
|
||||||
exit_error("config file '%s' not found" % args.config)
|
exit_error("config file '%s' not found" % args.config)
|
||||||
image.update_file(args.config, BOOTCONF_TXT)
|
image.update_file(args.config, BOOTCONF_TXT)
|
||||||
@@ -545,8 +589,9 @@ See 'rpi-eeprom-update -h' for more information about the available EEPROM image
|
|||||||
image.update_file(args.digest, BOOTCONF_SIG)
|
image.update_file(args.digest, BOOTCONF_SIG)
|
||||||
if args.pubkey is not None:
|
if args.pubkey is not None:
|
||||||
image.update_key(args.pubkey, PUBKEY_BIN)
|
image.update_key(args.pubkey, PUBKEY_BIN)
|
||||||
image.write()
|
|
||||||
elif args.config is None and args.timestamp is not None:
|
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()
|
image.write()
|
||||||
else:
|
else:
|
||||||
image.read()
|
image.read()
|
||||||
|
|||||||
@@ -41,11 +41,20 @@ usage() {
|
|||||||
cat <<EOF
|
cat <<EOF
|
||||||
rpi-eeprom-digest [-k RSA_KEY] -i IMAGE -o OUTPUT
|
rpi-eeprom-digest [-k RSA_KEY] -i IMAGE -o OUTPUT
|
||||||
|
|
||||||
Creates a .sig file containing the sha256 digest of the IMAGE and an optional
|
Tool to generate .sig files containing the SHA256 digest and optional
|
||||||
RSA signature of that hash.
|
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:
|
Options:
|
||||||
-i The source image.
|
-i The source image e.g. boot.img
|
||||||
-o The name of the digest/signature file.
|
-o The name of the digest/signature file.
|
||||||
-k Optional RSA private key.
|
-k Optional RSA private key.
|
||||||
|
|
||||||
@@ -58,16 +67,20 @@ The bootloader only verifies RSA signatures in signed boot mode
|
|||||||
|
|
||||||
Examples:
|
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
|
# Generate the normal sha256 hash to guard against file-system corruption
|
||||||
rpi-eeprom-digest -i pieeprom.bin -o pieeprom.sig
|
rpi-eeprom-digest -i pieeprom.bin -o pieeprom.sig
|
||||||
rpi-eeprom-digest -i vl805.bin -o vl805.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.
|
# 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.
|
# 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
|
EOF
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -110,6 +110,10 @@ die() {
|
|||||||
exit ${EXIT_FAILED}
|
exit ${EXIT_FAILED}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
echo "$@" >&2
|
||||||
|
}
|
||||||
|
|
||||||
getBootloaderConfig() {
|
getBootloaderConfig() {
|
||||||
# Prefer extracting bootloader's config from DT.
|
# Prefer extracting bootloader's config from DT.
|
||||||
#
|
#
|
||||||
@@ -192,9 +196,9 @@ applyRecoveryUpdate()
|
|||||||
getBootloaderCurrentVersion
|
getBootloaderCurrentVersion
|
||||||
BOOTLOADER_UPDATE_VERSION=$(strings "${BOOTLOADER_UPDATE_IMAGE}" | grep BUILD_TIMESTAMP | sed 's/.*=//g')
|
BOOTLOADER_UPDATE_VERSION=$(strings "${BOOTLOADER_UPDATE_IMAGE}" | grep BUILD_TIMESTAMP | sed 's/.*=//g')
|
||||||
if [ "${BOOTLOADER_CURRENT_VERSION}" -gt "${BOOTLOADER_UPDATE_VERSION}" ]; then
|
if [ "${BOOTLOADER_CURRENT_VERSION}" -gt "${BOOTLOADER_UPDATE_VERSION}" ]; then
|
||||||
echo " WARNING: Installing an older bootloader version."
|
warn " WARNING: Installing an older bootloader version."
|
||||||
echo " Update the rpi-eeprom package to fetch the latest bootloader images."
|
warn " Update the rpi-eeprom package to fetch the latest bootloader images."
|
||||||
echo
|
warn
|
||||||
fi
|
fi
|
||||||
echo " CURRENT: $(date -u "-d@${BOOTLOADER_CURRENT_VERSION}") (${BOOTLOADER_CURRENT_VERSION})"
|
echo " CURRENT: $(date -u "-d@${BOOTLOADER_CURRENT_VERSION}") (${BOOTLOADER_CURRENT_VERSION})"
|
||||||
echo " UPDATE: $(date -u "-d@${BOOTLOADER_UPDATE_VERSION}") (${BOOTLOADER_UPDATE_VERSION})"
|
echo " UPDATE: $(date -u "-d@${BOOTLOADER_UPDATE_VERSION}") (${BOOTLOADER_UPDATE_VERSION})"
|
||||||
@@ -254,9 +258,10 @@ applyRecoveryUpdate()
|
|||||||
# of power loss.
|
# of power loss.
|
||||||
if [ "${RPI_EEPROM_USE_FLASHROM}" = 1 ]; then
|
if [ "${RPI_EEPROM_USE_FLASHROM}" = 1 ]; then
|
||||||
echo
|
echo
|
||||||
echo "UPDATING bootloader."
|
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
|
||||||
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 "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 "a bootloader rescue SD card image which restores the default bootloader image."
|
||||||
echo
|
echo
|
||||||
@@ -310,11 +315,11 @@ applyUpdate() {
|
|||||||
if [ "${RPI_EEPROM_USE_FLASHROM}" = 1 ]; then
|
if [ "${RPI_EEPROM_USE_FLASHROM}" = 1 ]; then
|
||||||
flashrom_probe_ok=0
|
flashrom_probe_ok=0
|
||||||
if ! [ -e "${SPIDEV}" ]; then
|
if ! [ -e "${SPIDEV}" ]; then
|
||||||
echo "WARNING: SPI device ${SPIDEV} not found. Setting RPI_EEPROM_USE_FLASHROM to 0"
|
warn "WARNING: SPI device ${SPIDEV} not found. Setting RPI_EEPROM_USE_FLASHROM to 0"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! flashrom -p linux_spi:dev=${SPIDEV},spispeed=16000 > /dev/null 2>&1; then
|
if ! flashrom -p linux_spi:dev=${SPIDEV},spispeed=16000 > /dev/null 2>&1; then
|
||||||
echo "WARNING: Flashrom probe of ${SPIDEV} failed"
|
warn "WARNING: Flashrom probe of ${SPIDEV} failed"
|
||||||
else
|
else
|
||||||
flashrom_probe_ok=1
|
flashrom_probe_ok=1
|
||||||
fi
|
fi
|
||||||
@@ -365,7 +370,7 @@ getBootloaderUpdateVersion() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chipNotSupported() {
|
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}
|
exit ${EXIT_SUCCESS}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,15 +400,23 @@ checkDependencies() {
|
|||||||
elif [ $(((0x$BOARD_INFO >> 12) & 15)) = 4 ]; then
|
elif [ $(((0x$BOARD_INFO >> 12) & 15)) = 4 ]; then
|
||||||
BCM_CHIP=2712
|
BCM_CHIP=2712
|
||||||
EEPROM_SIZE=2097152
|
EEPROM_SIZE=2097152
|
||||||
BOOTLOADER_AUTO_UPDATE_MIN_VERSION="${BOOTLOADER_AUTO_UPDATE_MIN_VERSION:-1697650217}"
|
BOOTLOADER_AUTO_UPDATE_MIN_VERSION="${BOOTLOADER_AUTO_UPDATE_MIN_VERSION:-1713358463}"
|
||||||
SPIDEV=/dev/spidev10.0
|
SPIDEV=/dev/spidev10.0
|
||||||
|
# Default is to use flashrom if availableon BCM2712
|
||||||
|
RPI_EEPROM_USE_FLASHROM=${RPI_EEPROM_USE_FLASHROM:-1}
|
||||||
else
|
else
|
||||||
chipNotSupported
|
chipNotSupported
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Default to off - in the future Raspberry Pi 5 may default to using flashrom if
|
# Default to off - in the future Raspberry Pi 5 may default to using flashrom if
|
||||||
# flashrom is available.
|
# flashrom is available.
|
||||||
[ -z "${RPI_EEPROM_USE_FLASHROM}" ] && RPI_EEPROM_USE_FLASHROM=0
|
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}"
|
FIRMWARE_IMAGE_DIR="${FIRMWARE_ROOT}-${BCM_CHIP}/${FIRMWARE_RELEASE_STATUS}"
|
||||||
if ! [ -d "${FIRMWARE_IMAGE_DIR}" ]; then
|
if ! [ -d "${FIRMWARE_IMAGE_DIR}" ]; then
|
||||||
@@ -450,11 +463,15 @@ checkDependencies() {
|
|||||||
die "lspci not found. Try installing the pciutils package."
|
die "lspci not found. Try installing the pciutils package."
|
||||||
fi
|
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
|
# vcgencmd bootloader_version is deprecated. Use device-tree if available to
|
||||||
# reduce the number of dependencies on VCHI.
|
# reduce the number of dependencies on VCHI.
|
||||||
if ! [ -f "${DT_BOOTLOADER_TS}" ]; then
|
if ! [ -f "${DT_BOOTLOADER_TS}" ]; then
|
||||||
if ! command -v vcgencmd > /dev/null; 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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -473,16 +490,12 @@ checkDependencies() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v sha256sum > /dev/null; then
|
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
|
fi
|
||||||
|
|
||||||
if [ "${BCM_CHIP}" = 2711 ] && [ ! -f "${RECOVERY_BIN}" ]; then
|
if [ "${BCM_CHIP}" = 2711 ] && [ ! -f "${RECOVERY_BIN}" ]; then
|
||||||
die "${RECOVERY_BIN} not found."
|
die "${RECOVERY_BIN} not found."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v flashrom > /dev/null; then
|
|
||||||
RPI_EEPROM_USE_FLASHROM=0
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
@@ -704,11 +717,11 @@ findBootFS()
|
|||||||
|
|
||||||
if [ "${BCM_CHIP}" = 2712 ]; then
|
if [ "${BCM_CHIP}" = 2712 ]; then
|
||||||
if ! [ -e "${BOOTFS}/config.txt" ]; 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
|
fi
|
||||||
else
|
else
|
||||||
if [ "$(find "${BOOTFS}/" -name "*.elf" | wc -l)" = 0 ]; then
|
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
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ FORCE=0
|
|||||||
READ_KEY=""
|
READ_KEY=""
|
||||||
WRITE_KEY=""
|
WRITE_KEY=""
|
||||||
OUTPUT_BINARY=0
|
OUTPUT_BINARY=0
|
||||||
|
ROW_COUNT=8
|
||||||
|
ROW_OFFSET=0
|
||||||
|
|
||||||
die() {
|
die() {
|
||||||
echo "$@" >&2
|
echo "$@" >&2
|
||||||
@@ -25,10 +27,12 @@ usage() {
|
|||||||
N.B. OTP bits can never change from 1 to 0.
|
N.B. OTP bits can never change from 1 to 0.
|
||||||
-w Writes the new key to OTP memory.
|
-w Writes the new key to OTP memory.
|
||||||
-y Skip the confirmation prompt when writing to OTP.
|
-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
|
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.
|
storage if the OS has already been restricted using the signed boot functionality.
|
||||||
|
|
||||||
@@ -46,8 +50,8 @@ check_key_set() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
read_key() {
|
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"
|
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 '{for(i=8;i<16;i++) printf $i; print ""}')"
|
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() {
|
write_key() {
|
||||||
@@ -55,19 +59,19 @@ write_key() {
|
|||||||
# Normalize formatting and check the length
|
# Normalize formatting and check the length
|
||||||
key="$(echo "${key}" | tr 'A-Z' 'a-z')"
|
key="$(echo "${key}" | tr 'A-Z' 'a-z')"
|
||||||
key="$(echo "${key}" | sed 's/[^a-f0-9]//g')"
|
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
|
count=0
|
||||||
key_params=""
|
key_params=""
|
||||||
while [ ${count} -lt 8 ]; do
|
while [ ${count} -lt $ROW_COUNT ]; do
|
||||||
start=$(((count * 8) + 1))
|
start=$(((count * 8) + 1))
|
||||||
end=$((start + 7))
|
end=$((start + 7))
|
||||||
key_params="${key_params} 0x$(echo -n "${key}" | cut -c${start}-${end})"
|
key_params="${key_params} 0x$(echo -n "${key}" | cut -c${start}-${end})"
|
||||||
count=$((count + 1))
|
count=$((count + 1))
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "${YES}" = 0 ] && [ -t 0 ]; then
|
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
|
||||||
echo "WARNING: Updates to OTP registers are permanent and cannot be undone."
|
echo "WARNING: Updates to OTP registers are permanent and cannot be undone."
|
||||||
|
|
||||||
@@ -79,13 +83,13 @@ write_key() {
|
|||||||
fi
|
fi
|
||||||
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
|
||||||
[ "${READ_KEY}" = "${key}" ] || die "Key readback check failed. ${out}"
|
[ "${READ_KEY}" = "${key}" ] || die "Key readback check failed. ${out}"
|
||||||
}
|
}
|
||||||
|
|
||||||
YES=0
|
YES=0
|
||||||
while getopts bcfhw:y option; do
|
while getopts bcfhw:yl:o: option; do
|
||||||
case "${option}" in
|
case "${option}" in
|
||||||
b) OUTPUT_BINARY=1
|
b) OUTPUT_BINARY=1
|
||||||
;;
|
;;
|
||||||
@@ -102,13 +106,61 @@ while getopts bcfhw:y option; do
|
|||||||
w) WRITE_KEY="${OPTARG}"
|
w) WRITE_KEY="${OPTARG}"
|
||||||
;;
|
;;
|
||||||
y) YES=1
|
y) YES=1
|
||||||
;;
|
;;
|
||||||
|
l) ROW_COUNT="${OPTARG}"
|
||||||
|
;;
|
||||||
|
o) ROW_OFFSET="${OPTARG}"
|
||||||
|
;;
|
||||||
*) echo "Unknown argument \"${option}\""
|
*) echo "Unknown argument \"${option}\""
|
||||||
usage
|
usage
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
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 [ -n "${WRITE_KEY}" ]; then
|
||||||
if [ "${FORCE}" = 0 ] && check_key_set; then
|
if [ "${FORCE}" = 0 ] && check_key_set; then
|
||||||
die "Current key is non-zero. Specify -f to write anyway"
|
die "Current key is non-zero. Specify -f to write anyway"
|
||||||
|
|||||||
229
tools/rpi-sign-bootcode
Executable file
229
tools/rpi-sign-bootcode
Executable 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()
|
||||||
Reference in New Issue
Block a user