How to update the Raspberry Pi Compute Module 4 Bootloader / EEPROM

The Raspberry Pi 4 and Pi 400 share the same Broadcom BCM2711 SoC with the Compute Module 4. All three devices also share an SPI EEPROM flash chip, which stores the Raspberry Pi's bootloader.

SPI EEPROM Flash bootloader chip on Raspberry Pi 4 model B

But the Compute Module 4 differs in how you update the bootloader. With the Pi 4 or Pi 400, you can use Raspberry Pi imager to write a utility image to a microSD card to update the bootloader. You put in the card, power on the Pi, and the bootloader is updated.

On the Compute Module 4, because it may be used in remote or embedded environments, its bootloader can actually be hardware write-protected!

And to update it (when not write-protected), you have to use Raspberry Pi's usbboot/rpiboot utility.

Note: While it uses the same base project, this process is slightly different than the one used to flash eMMC Compute Modules.

First, make sure you have libusb installed. On my Mac, I ran brew install libusb, but on a Debian system or Raspberry Pi, you can install it with sudo apt install libusb-1.0-0-dev.

Then, clone Raspberry Pi's usbboot project to your computer:

git clone --depth=1 https://github.com/raspberrypi/usbboot

Change into the usbboot directory and build the rpiboot binary:

$ cd usbboot
$ make

Now, change into the recovery directory, and modify the boot.conf file to your liking. Check out the CM4 Bootloader documentation for some examples, in addition to the Raspberry Pi 4 bootloader configuration options documentation.

In my case, I wanted to try out the new Network Install feature, so I added the line NET_INSTALL_ENABLED=1 to my boot.conf, and I replaced the pieeprom.original.bin file in the recovery directory with the beta network install bootloader file pieeprom-2022-02-04.bin.

Now, run ./update-pieeprom.sh to update the pieeprom.bin image file.

With the Compute Module 4 plugged into your computer, with the 'disable eMMC boot' jumper set (so it will not boot up normally), run rpiboot and it should load in the new pieeprom.bin:

$ ../rpiboot -d .
RPIBOOT: build-date Feb  4 2022 version 20220131~101805 693d5beb
Loading: ./bootcode4.bin
Waiting for BCM2835/6/7/2711...
Loading: ./bootcode4.bin
Sending bootcode.bin
Successful read 4 bytes 
Waiting for BCM2835/6/7/2711...
Loading: ./bootcode4.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
Second stage boot server done

Once it's complete, your terminal session should drop you back to your prompt, the green ACT LED on the CM4 IO Board should start flashing green, and if you have an HDMI display plugged in, it should show a green screen to indicate success.

Now, power off the CM4, pull the 'disable eMMC boot' jumper, and power it back on, and it should be running the latest bootloader.

You can verify with:

$ sudo rpi-eeprom-update
BOOTLOADER: up to date
   CURRENT: Thu 29 Apr 16:11:25 UTC 2021 (1619712685)
    LATEST: Thu 29 Apr 16:11:25 UTC 2021 (1619712685)
   RELEASE: default (/lib/firmware/raspberrypi/bootloader/default)
            Use raspi-config to change the release.

You can also use rpi-eeprom-config to check on the current bootloader configuration, e.g.:

[email protected]:~ $ rpi-eeprom-config
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
ENABLE_SELF_UPDATE=1
BOOT_ORDER=0xf51

And you can edit the configuration with sudo rpi-eeprom-config --edit, or if you just want to change the boot order, use sudo raspi-config, and change that inside the Advanced Options.

Comments

It should be noted that a CM4 without eMMC and with SD or SSD attached also requires:

  1. a "Fit jumper to disable eMMC boot' jumper attached, even though there's no eMMC or no bootable eMMC
  2. one of these boot-media to be inserted, while running ../rpiboot -d .
  3. first and foremost the RPi Compute Module IO Board - because not all IO boards support this flash method

I'd like to add:
The Waveshare CM4-IO-BASE-A module also allows this flash method.
The DIP switch close to the HDMI header needs to be turned ON for the
flash procedure.
And a bootable media (eMMC/SD/NVME/USB) needs to be attached
during the process.
After the firmware is successfully written, the module needs to be powered off and
the DIP switch needs to be turned OFF again.

followed the instructions and get the following error, thoughts?

$ ./update-pieeprom.sh
+ /home/arau/usbboot/tools/rpi-eeprom-config --config boot.conf --out pieeprom.bin pieeprom.original.bin
ERROR: pieeprom.original.bin: Expected size 524288 bytes actual size 124906 bytes
+ die Failed to update EEPROM image
+ echo Failed to update EEPROM image
Failed to update EEPROM image
+ exit
+ cleanup
+ [ -f ]

Not sure what the issue was but the file that threw the error was retrieved with wget as mentioned in the how to. When downloading to another host and scp'ing the file over it worked.

Thanks

Alex

Thanks Jeff this was a big help in getting my CM4 to update to the new bootloader. I was able to install a new OS on my eMMC.
Now my boot times are very slow. Is there a timer we can play with or can I tell the bootloader to ignore unless shift? (think macbook with option key held).

If not, I assume I can edit my boot.conf to boot SD, USB, mvne (my carrier has this but haven't figure out how to boot from it yet) and then Net Install if no one is home :^)

Hey Jeff,

Wondering if you have ever managed to boot a compute module from a USB? With the newer bootloaders on RPI4 there is a default to USB boot when the SD card is missing, if a compute board in on a carrier board with USB ports, can the same be achieved (either out of the box or with some config)?

This is great news. I am going to try and create a flash system using it, i.e a usb drive that contains an os and on boot contains all the logic to flash some provided content to the emmc. Hopefully take some friction out of using emmc. Let me know if you have come across anyone who has beat me to it.

Hi Jeff,
Can the CM4 lite boot loader / EEPROM be updated over USB from PC (without the help of uSD card)?
My doubt comes from a question whether it is possible to have only NVME & completely ditch the uSD card. Typically, it is possible to update EEPROM attached to a processor through the USB interface/COM port from a PC interfaced with the processor by any of the above means.

PS: I'm new to Pi & CM4 and is trying to understand it better.

Thanks for any help

Thanks for all the great videos and info, Jeff. I followed it with the CM4 I'm trying to set up and for whatever reason, I can't get the boot.config file to save. Every time I power cycle the CM4, it ends up with the eMMC as the top option. I've tried editing it directly on the CM4 using Raspberry Pi OS as well as through rpiboot/usbboot both with the same changes to the boot.conf file taking place. Any advice for how to get the edits to stick now that NVMe support is out of beta?

Hi Jeff,
Thanks a lot for the help on this. I have a cm4 (non-lite) and added a backup nvme drive. I could use this method to change the default boot order by changing the order in the boot.conf file. It works as it should now i.e boots from nvme (if available) and from emmc (when i remove it). I can even see the emmc boot & root partitions in "media" folder when i boot from nvme.

However, my raspi-config did not change (still shows B1, B2, B3 i.e. sd card boot, usb boot, network boot) and any effort to select any of those options returns an error "no eeprom Bin file found for version 2022-080-02"). Any idea why that could be? I was hoping to see the boot-order change option available in raspi-config so that i can switch the options, if required, from there instead of going through the whole process every time i need to change the boot order.

Hello, great article but I cannot get beyond a fatal error when I get to the first make step, I am using Ubuntu 22.04 on an intel cpu and getting

main.c:1:10: fatal error: libusb.h No such file or directory. 

I already installed git, build essential, etc. no dice and I have searched the web for an answer but cannot resolve the problem, any thoughts?

I tried the method described here and here: https://blog.j2i.net/2022/04/12/booting-a-pi-cm4-on-nvme/
On by CM4 lite on a Waveshare Mini Base Board (B). Without success.

If finally worked when I followed the instriction in this PDF, section 2.18. (https://download.kamami.pl/p581814-3160854.pdf)
With just a minor correction on last command: replace "cm4" with "." (i.e. sudo ./rpiboot -l -v -d ./recovery)

So the steps were (on the Pi4B used to program through USB):

$ rpi-eeprom-config pieeprom.bin > bootconf.txt

Edit bootconf.txt to change boot order

$ rpi-eeprom-config --out pieeprom-new.bin --config bootconf.txt pieeprom.bin

set boot switch to ON on CM4 board, connected usb cable between Pi4B and CM4 board

$ sudo ./rpiboot -l -v -d ./recovery