Using RPIBOOT on the HackerGadgets CM4/5 adapter

This is a guide to upgrading the firmware on a non-bootable CM5 using the HackerGadgets CM4/5 adapter board for the uConsole. I am a human and I wrote the entirety of this post without external help or tools; I am just like this and the heavy use of citations is meant to aid referencing. This post continues my quest to boot from my NVME drive. I purchased a CM5 16GB RAM Lite (CM5116000) to install in my uConsole, in the hopes that it would work without complaint with PCIe.

However, the CM5 wouldn’t boot from any device. I expected that as there is an existing thread discussing the challenges with new CM5s’ EEPROMs. Unfortunately, as the known-good SD card went from $12 at the time of posting to $60 now(!!!) it’s a little out of budget for me and I’d have to wait two weeks for it to ship. Other SD cards I tried also failed to boot. But I had forgotten that I had the HackerGadgets NVMe upgrade kit, which has a USB-C port on-board for accessing the Compute Module’s EEPROM or eMMC. There is an existing thread discussing using that port to flash the EEPROM but I didn’t find the guide that was hyperlinked to be satisfactory and many of the questions are unanswered, so this thread aims to fill in the gaps in the knowledge. @vileer - you know more than I do about this, so please let me know if I got anything wrong. :slight_smile:

On the HackerGadgets CM4 adapter, DIP switch 1 (labeled 1:nRPIBOOT on the silkscreen) disables regular booting and enables a boot mode in the Raspberry Pi Compute Modules that uses the RPIBOOT protocol to allow access to the EEPROM, eMMC, and GPU firmware. DIP 2 (labeled 2:EEPROM_nWP) write-protects the EEPROM, preventing accidental (or malicious) writes to the configuration. These switches are analogous to putting a jumper between pins 1-2 and 3-4 respectively on the CM4 IO board’s J2 section (located in the middle on the top edge of the board, to the right of the three ribbon connectors and to the left of the CM slot itself), and in the CM4 IO board’s datasheet (page 11, row D, column 2) those signals are labeled with the same names as are on the HackerGadgets silkscreen. At the electrical level, toggling the switches 1 and 2 grounds out CM pins 93 and 20 respectively.

The Raspberry Pi team developed the companion tool usbboot which uses libusb1 to implement an RPIBOOT protocol client, and performs some file validation and lower-level USB tasks that are a bit beyond the amount of research I’m willing to do today. It’s very portable - though “support for other platforms is provided on a best-effort and/or community-maintained basis”, it is a mostly-POSIX C program and has additional code to support older BSDs and OS X versions. It lists its own dependencies and compiles without much fuss; if its own README is too dense Jeff Geerling wrote a blog post about using usbboot that walks through the more basic steps. usbboot comes with the extension recovery5 which can be used directly to upgrade the CM5 EEPROM, and that’s what this guide will be using.

In terms of physical setup, I used a pin to switch DIP 1 on, removed the batteries from the uConsole (though this might be necessary, I just didn’t wanna take any chances), and used a USB-C right-angle adapter to plug the CM4 adapter into a spare USB-A port on this Thinkpad X200T I’m borrowing for this purpose, as the uConsole is the only computer I own that I could use here (D’oh!).

# dmesg reports:

[ 7210.121088] usb 4-2: new high-speed USB device number 5 using ehci-pci
[ 7210.246928] usb 4-2: New USB device found, idVendor=0a5c, idProduct=2712, bcdDevice= 0.00
[ 7210.246939] usb 4-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 7210.246943] usb 4-2: Product: BCM2712D0 Boot
[ 7210.246946] usb 4-2: Manufacturer: Broadcom
[ 7210.246949] usb 4-2: SerialNumber: a55b00b5

So I went ahead (with usbboot built prior to my setup) and:

$ cd usbboot/recovery5
$ cat boot.conf
# I'M JUST USING REX'S RECOMMENDED EEPROM CONFIG
[all]
BOOT_UART=1

# Switch off PMIC outputs on HALT
POWER_OFF_ON_HALT=1

# Default BOOT_ORDER for provisioning
# SD -> NVMe -> USB -> Network
BOOT_ORDER=0xf461

# Try boot on SDCard repeatly
SD_BOOT_MAX_RETRIES=2

# Slow down SDCard SDR Mode on bootloader
SD_QUIRKS=1
$ ./update-pieeprom.sh
+ rpi-eeprom-config --config boot.conf --out pieeprom.bin pieeprom.original.bin
+ set +x
new-image: pieeprom.bin
source-image: pieeprom.original.bin
config: boot.conf
$ ../rpiboot -d .
RPIBOOT: build-date 2026/03/06 pkg-version local 101f2d00

Please fit the EMMC_DISABLE / nRPIBOOT jumper before connecting the power and USB cables to the target device.
If the device fails to connect then please see https://rpltd.co/rpiboot for debugging tips.

Loading: ./bootcode5.bin
Waiting for BCM2835/6/7/2711/2712...

Loading: ./bootcode5.bin
Permission to access USB device denied. Make sure you are a member of the plugdev group.
$ su
# ../rpiboot -d .
RPIBOOT: build-date 2026/03/06 pkg-version local 101f2d00

Please fit the EMMC_DISABLE / nRPIBOOT jumper before connecting the power and USB cables to the target device.
If the device fails to connect then please see https://rpltd.co/rpiboot for debugging tips.

Loading: ./bootcode5.bin
Waiting for BCM2835/6/7/2711/2712...

Loading: ./bootcode5.bin
Sending bootcode.bin
Successful read 4 bytes 
Waiting for BCM2835/6/7/2711/2712...

Loading: ./bootcode5.bin
Second stage boot server
Loading: ./config.txt
File read: config.txt
Loading: ./pieeprom.bin
Loading: ./pieeprom.bin
Loading: ./pieeprom.sig
File read: pieeprom.sig
Loading: ./pieeprom.bin
File read: pieeprom.bin
{
	"USER_SERIAL_NUM": "identifiable information",
	"MAC_ADDR": "identifiable information",
	"EEPROM_UPDATE": "success",
	"EEPROM_HASH": "994d4925f61b18e0aad88d045db3ec58aeeecca935a49c8f28ba179b386caa9d",
	"CUSTOMER_KEY_HASH": "0000000000000000000000000000000000000000000000000000000000000000",
	"BOOT_ROM": "0000000a",
	"BOARD_ATTR": "80000000",
	"USER_BOARDREV": "e041a0",
	"JTAG_LOCKED": "0",
	"SIGNATURE_MODE": "0",
	"MAC_WIFI_ADDR": "identifiable information",
	"MAC_BT_ADDR": "identifiable information",
	"FACTORY_UUID": "identifiable information"
}
Second stage boot server done

Don’t forget to toggle the RPIBOOT switch when done.

I’ve been writing this as I did it, and now it’s done. My CM5 is useable in the uConsole! I owe a very dear thank you to HackerGadgets for having the foresight to add a USB-C port to the adapter for RPIBOOT. And thank you for your time.

  1. Just switch both pins when flashing
  2. don’t need to disconnect battery. but after flashing you might want to remove the module or battery to hard reset the device
  3. remember to use the newest rpiboot / usbboot software, older versions maybe not working with cm5
1 Like

Won’t switching both pins while flashing enable RPIBOOT but disable EEPROM writing, preventing the EEPROM update?

Just switch the nRPIBOOT.

1 Like