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:
152
emmc-provisioning/network-boot-initramfs/rescue-eeprom.sh
Normal file → Executable file
152
emmc-provisioning/network-boot-initramfs/rescue-eeprom.sh
Normal file → Executable 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"
|
||||
|
||||
Reference in New Issue
Block a user