Files
reterminal-dm4/emmc-provisioning/network-boot-initramfs/rescue-eeprom.sh
nearxos 5238d457e8 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.
2026-02-21 15:05:17 +02:00

139 lines
4.5 KiB
Bash
Executable File

#!/bin/sh
# 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
EEPROM_FW="/lib/firmware/raspberrypi/bootloader/default/pieeprom.bin"
BOOT_MNT="/mnt/boot"
MANUAL=0
[ "$1" = "--edit" ] && MANUAL=1
# 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
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
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"