Compare commits

...

40 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
32 changed files with 523 additions and 72 deletions

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.

View File

@@ -1,5 +1,84 @@
# Raspberry Pi5 bootloader EEPROM release notes
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
@@ -56,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

@@ -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-12-06 "" "${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).
@@ -296,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
@@ -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]))
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:
@@ -379,10 +402,11 @@ 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):
"""
@@ -408,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)
@@ -431,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.
@@ -478,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]
@@ -492,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
@@ -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('-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")
@@ -537,7 +573,15 @@ See 'rpi-eeprom-update -h' for more information about the available EEPROM image
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)
@@ -545,8 +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)
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()
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

@@ -110,6 +110,10 @@ die() {
exit ${EXIT_FAILED}
}
warn() {
echo "$@" >&2
}
getBootloaderConfig() {
# Prefer extracting bootloader's config from DT.
#
@@ -192,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})"
@@ -254,9 +258,10 @@ applyRecoveryUpdate()
# of power loss.
if [ "${RPI_EEPROM_USE_FLASHROM}" = 1 ]; then
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 "*** WARNING: Do not disconnect the power until the update is complete ***"
echo "If a problem occurs then the Raspberry Pi Imager may be used to create"
echo "a bootloader rescue SD card image which restores the default bootloader image."
echo
@@ -310,11 +315,11 @@ applyUpdate() {
if [ "${RPI_EEPROM_USE_FLASHROM}" = 1 ]; then
flashrom_probe_ok=0
if ! [ -e "${SPIDEV}" ]; then
echo "WARNING: SPI device ${SPIDEV} not found. Setting RPI_EEPROM_USE_FLASHROM to 0"
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
echo "WARNING: Flashrom probe of ${SPIDEV} failed"
warn "WARNING: Flashrom probe of ${SPIDEV} failed"
else
flashrom_probe_ok=1
fi
@@ -395,15 +400,23 @@ checkDependencies() {
elif [ $(((0x$BOARD_INFO >> 12) & 15)) = 4 ]; then
BCM_CHIP=2712
EEPROM_SIZE=2097152
BOOTLOADER_AUTO_UPDATE_MIN_VERSION="${BOOTLOADER_AUTO_UPDATE_MIN_VERSION:-1697650217}"
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.
[ -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}"
if ! [ -d "${FIRMWARE_IMAGE_DIR}" ]; then
@@ -483,10 +496,6 @@ checkDependencies() {
if [ "${BCM_CHIP}" = 2711 ] && [ ! -f "${RECOVERY_BIN}" ]; then
die "${RECOVERY_BIN} not found."
fi
if ! command -v flashrom > /dev/null; then
RPI_EEPROM_USE_FLASHROM=0
fi
}
usage() {
@@ -708,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
}

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()