Update boot order configuration for eMMC first, then network

Modify the first-boot script and documentation to set the EEPROM boot order to 0xf21, prioritizing eMMC boot followed by network boot. Adjust network boot settings for faster failure on DHCP timeouts and update related scripts and documentation to reflect these changes. Enhance the rescue script to directly modify EEPROM settings without requiring a chroot into eMMC, streamlining the recovery process for devices stuck in network-only boot. Update relevant documentation to ensure clarity on the new boot order and its implications.
This commit is contained in:
nearxos
2026-02-21 15:05:17 +02:00
parent ff6258c2af
commit 5238d457e8
13 changed files with 348 additions and 247 deletions

152
emmc-provisioning/network-boot-initramfs/rescue-eeprom.sh Normal file → Executable file
View File

@@ -1,36 +1,138 @@
#!/bin/sh
# Rescue script: mount eMMC root and chroot to run rpi-eeprom-config.
# Use this when stuck in network-only boot (BOOT_ORDER=0x2) to set BOOT_ORDER=0x1 or 0x21.
# Rescue script: set EEPROM boot order directly from the initramfs (no chroot needed).
# Uses rpi-eeprom-config + pieeprom.bin bundled in the Alpine-based initramfs.
# Sets BOOT_ORDER=0xf21 (eMMC first, then network, restart) with fast network timeouts.
# Run from the initramfs rescue shell (after booting with provisioning_rescue=1 in cmdline).
# Pass --edit to open the editor manually instead of applying automatically.
set -e
ROOT="/mnt/emmc"
BOOT="$ROOT/boot/firmware"
[ -d "$ROOT/boot" ] && [ ! -d "$BOOT" ] && BOOT="$ROOT/boot"
EEPROM_FW="/lib/firmware/raspberrypi/bootloader/default/pieeprom.bin"
BOOT_MNT="/mnt/boot"
MANUAL=0
[ "$1" = "--edit" ] && MANUAL=1
echo "=== Mounting eMMC for EEPROM config ==="
# CM4 / reTerminal: eMMC is usually mmcblk0, p1=boot (FAT), p2=root (ext4)
if [ ! -b /dev/mmcblk0p2 ]; then
echo "No /dev/mmcblk0p2 found. Try: ls /dev/mmcblk*"
# Clean up any previous mounts
umount "$BOOT_MNT" 2>/dev/null || true
umount /mnt/emmc 2>/dev/null || true
# --- Read current EEPROM config ---
echo "=== EEPROM rescue (Alpine initramfs) ==="
if ! command -v rpi-eeprom-config >/dev/null 2>&1; then
echo "ERROR: rpi-eeprom-config not found in initramfs."
echo "This initramfs was not built with the Alpine build script."
exit 1
fi
mkdir -p "$ROOT"
mount /dev/mmcblk0p2 "$ROOT" || { echo "Mount root failed"; exit 1; }
if [ -b /dev/mmcblk0p1 ]; then
mkdir -p "$BOOT"
mount /dev/mmcblk0p1 "$BOOT" 2>/dev/null || true
if [ ! -f "$EEPROM_FW" ]; then
echo "ERROR: EEPROM firmware not found at $EEPROM_FW"
echo "Rebuild the initramfs with build.sh to include it."
exit 1
fi
mount -t proc none "$ROOT/proc"
mount -t sysfs none "$ROOT/sys"
mount --bind /dev "$ROOT/dev"
mount --bind /dev/pts "$ROOT/dev/pts" 2>/dev/null || true
if [ -x "$ROOT/usr/bin/rpi-eeprom-config" ]; then
echo "Chroot to eMMC and run: rpi-eeprom-config --edit"
echo "Set BOOT_ORDER=0x1 (eMMC only) or 0x21 (network first, then eMMC), save, then exit and run: reboot"
chroot "$ROOT" /usr/bin/rpi-eeprom-config --edit
else
echo "rpi-eeprom-config not found in eMMC. Chrooting anyway; run: apt install rpi-eeprom && rpi-eeprom-config --edit"
chroot "$ROOT" /bin/sh -i
echo "Reading current EEPROM config from running bootloader..."
CURRENT_CONF="/tmp/eeprom-current.conf"
rpi-eeprom-config 2>/dev/null > "$CURRENT_CONF" || true
if [ ! -s "$CURRENT_CONF" ]; then
echo "Could not read current EEPROM config via vcgencmd."
echo "Extracting config from firmware image instead..."
rpi-eeprom-config "$EEPROM_FW" > "$CURRENT_CONF" 2>/dev/null || true
fi
if [ ! -s "$CURRENT_CONF" ]; then
echo "ERROR: Could not read EEPROM config from either source."
exit 1
fi
echo "Current config:"
cat "$CURRENT_CONF"
echo ""
# --- Manual mode: mount eMMC boot, chroot, edit ---
if [ "$MANUAL" -eq 1 ]; then
echo "Manual mode: mounting eMMC for interactive editing..."
mkdir -p /mnt/emmc
mount /dev/mmcblk0p2 /mnt/emmc 2>/dev/null || true
BOOT="/mnt/emmc/boot/firmware"
[ ! -d "$BOOT" ] && BOOT="/mnt/emmc/boot"
if [ -b /dev/mmcblk0p1 ]; then
mkdir -p "$BOOT"
mount /dev/mmcblk0p1 "$BOOT" 2>/dev/null || true
fi
mount -t proc none /mnt/emmc/proc 2>/dev/null || true
mount -t sysfs none /mnt/emmc/sys 2>/dev/null || true
mount --bind /dev /mnt/emmc/dev 2>/dev/null || true
if [ -x /mnt/emmc/usr/bin/rpi-eeprom-config ]; then
chroot /mnt/emmc /usr/bin/rpi-eeprom-config --edit
else
echo "rpi-eeprom-config not found on eMMC. Dropping to shell."
chroot /mnt/emmc /bin/sh -i
fi
exit 0
fi
# --- Automatic mode: build new config and apply ---
NEW_CONF="/tmp/eeprom-new.conf"
# Keep settings we don't modify, strip the ones we replace
grep -v '^BOOT_ORDER=' "$CURRENT_CONF" \
| grep -v '^NET_BOOT_MAX_RETRIES=' \
| grep -v '^DHCP_TIMEOUT=' \
| grep -v '^DHCP_REQ_TIMEOUT=' \
| grep -v '^TFTP_IP=' \
| grep -v '^NET_INSTALL_AT_POWER_ON=' \
> "$NEW_CONF" || true
echo 'BOOT_ORDER=0xf21' >> "$NEW_CONF"
echo 'NET_BOOT_MAX_RETRIES=3' >> "$NEW_CONF"
echo 'DHCP_TIMEOUT=1500' >> "$NEW_CONF"
echo 'DHCP_REQ_TIMEOUT=500' >> "$NEW_CONF"
echo 'NET_INSTALL_AT_POWER_ON=0' >> "$NEW_CONF"
echo "New config to apply:"
cat "$NEW_CONF"
echo ""
# Create the modified EEPROM image with the new config embedded
EEPROM_OUT="/tmp/pieeprom.upd"
echo "Embedding config into EEPROM firmware image..."
rpi-eeprom-config --config "$NEW_CONF" --out "$EEPROM_OUT" "$EEPROM_FW"
if [ ! -f "$EEPROM_OUT" ] || [ ! -s "$EEPROM_OUT" ]; then
echo "ERROR: Failed to create modified EEPROM image."
exit 1
fi
# Generate the signature file (sha256 of the .upd, named .sig)
EEPROM_SIG="/tmp/pieeprom.sig"
sha256sum "$EEPROM_OUT" | awk '{print $1}' > "$EEPROM_SIG"
# Mount eMMC boot partition and copy the update files
echo "Mounting eMMC boot partition..."
if [ ! -b /dev/mmcblk0p1 ]; then
echo "ERROR: /dev/mmcblk0p1 not found. Is eMMC present?"
exit 1
fi
mkdir -p "$BOOT_MNT"
mount /dev/mmcblk0p1 "$BOOT_MNT" || { echo "ERROR: Could not mount boot partition"; exit 1; }
cp "$EEPROM_OUT" "$BOOT_MNT/pieeprom.upd"
cp "$EEPROM_SIG" "$BOOT_MNT/pieeprom.sig"
sync
echo ""
echo "=== EEPROM update written to eMMC boot partition ==="
echo " BOOT_ORDER=0xf21 (eMMC first, then network, restart)"
echo " NET_BOOT_MAX_RETRIES=3, DHCP_TIMEOUT=1500ms"
echo " Files: pieeprom.upd + pieeprom.sig on /dev/mmcblk0p1"
echo ""
echo "The bootloader will apply this update on next boot from eMMC."
echo ""
echo "Next steps:"
echo " 1. Disable network boot on the LXC (so next boot falls through to eMMC)"
echo " 2. Reboot: reboot -f (or: echo b > /proc/sysrq-trigger)"
umount "$BOOT_MNT" 2>/dev/null || true
rm -f "$CURRENT_CONF" "$NEW_CONF" "$EEPROM_OUT" "$EEPROM_SIG"