🛠 Bootloader EEPROM du CM4 : maîtriser BOOT_ORDER via usbboot
Objectives
The CM4 is the first Compute Module with a bootloader in an SPI EEPROM embedded on the module. Concrete consequences: recovery.bin is never executed from eMMC/SD, the rpi-eeprom-update service is disabled by default, and any modification of the boot order goes through usbboot/rpiboot. This tutorial: read the bootloader version, change BOOT_ORDER (0xf1 SD/eMMC, 0xf2 network, 0xf15 USB→eMMC, 0xf6 NVMe) via the recovery flow, then lock the EEPROM against writing.
Hardware
- 1 × CM4 (eMMC preferred) on a CM4 IO Board
- Jumper on J2 (nRPI_BOOT), micro-USB cable between J11 and the host
- 1 Linux host PC (a Pi 4 running RPiOS 64-bit works); note: the rpiboot package in Ubuntu ≤ 24.04 is known to be broken — compile it from sources
- Avoid USB hubs between the module and the host (enumeration is sometimes impossible)
Complete code
#!/usr/bin/env bash
# bootorder-cm4.sh — reprogrammer BOOT_ORDER de l'EEPROM d'un CM4 (flux officiel).
set -euo pipefail
git clone --depth 1 https://github.com/raspberrypi/usbboot && cd usbboot
cd recovery
cat > boot.conf <<'EOF'
[All]
BOOT_ORDER=0xf15
EOF
./update-pieeprom.sh # régénère pieeprom.bin depuis boot.conf
cd .. && sudo ./rpiboot -d recovery # écrit l'EEPROM (J2 posé, EEPROM_nWP non maintenu bas)
Then, once the module has restarted normally (J2 removed):
vcgencmd bootloader_version | head -1 # la date doit correspondre au build fraîchement écrit
grep -i boot /var/log/bootstrap.log 2>/dev/null || true
# Durcissement production : protection en écriture
echo 'eeprom_write_protect=1' | sudo tee -a /boot/firmware/config.txt
Expected verification
vcgencmd bootloader_version displays the date of the regenerated build; with BOOT_ORDER=0xf15, plugging in a bootable USB drive makes the module boot from it with eMMC fallback. The boot log (uart or journalctl -b) traces the boot order used.
Common errors
- Relying on
rpi-eeprom-update: disabled by default on Compute Modules (eMMC is not removable); theself-updatemode exists but is not atomic — a power cut during the update can corrupt the EEPROM. - Forgetting the J2 jumper during writing, or leaving it in place: in the first case rpiboot sees nothing, in the second the module does not restart normally.
- EEPROM_nWP held low (hardware protection active): writing fails silently or is refused.
- Broken distribution rpiboot: on Ubuntu ≤ 24.04, compile usbboot from sources, and connect directly (no hub).
Other tutorials for this board
- Premier démarrage d'un CM4 Lite depuis la microSD de l'IO Board
- GPIO du CM4 : comprendre les banks 1,8 V / 3,3 V avant de câbler
- Basculer le Wi-Fi du CM4 sur l'antenne externe U.FL (dtparam=ant2)
- Ajouter une RTC au CM4 (PCF8523 sur I2C1 via dt-blob)
- Son sur CM4 : DAC I2S/PCM (PCM5102) sans prise jack
- Horodatage industriel : PTP IEEE 1588 sur le PHY Ethernet du CM4
Code examples for this board
clignotante.pyPythonbouton-gpio.pyPythoncapteur-i2c.shBashsurveillance-temperature.shBashcapteur-dht11.pyPythonservo-pwm-sysfs.shBash