Refactor first-boot script and documentation to remove rpi-eeprom handling

Eliminate the rpi-eeprom configuration steps from the first-boot script, simplifying the installation process. Update the documentation to clarify that the EEPROM boot order is now set via the dashboard or manually, rather than during first boot. Adjust package installation logs to reflect the removal of rpi-eeprom and ensure clarity in the installation process. Enhance overall documentation to guide users on the new EEPROM update methods.
This commit is contained in:
nearxos
2026-02-21 17:04:37 +02:00
parent a915e5a405
commit 595ae0dd35
5 changed files with 11 additions and 122 deletions

View File

@@ -9,7 +9,7 @@ This script runs once on first boot via cloud-init (see `user-data-remote-gnss.e
1. **Constants**`FILE_SERVER`, `PI_USER`, paths, log file. 1. **Constants**`FILE_SERVER`, `PI_USER`, paths, log file.
2. **Logging** — All output teed to `/var/log/first-boot.log`. 2. **Logging** — All output teed to `/var/log/first-boot.log`.
3. **Helpers**`install_oneshot(name)` downloads `${name}.sh` from the file server and installs it as a one-shot autostart (runs once at pis first login, then deletes itself). 3. **Helpers**`install_oneshot(name)` downloads `${name}.sh` from the file server and installs it as a one-shot autostart (runs once at pis first login, then deletes itself).
4. **Packages** — git, Chromium, wmctrl, SSH, swaybg, wlr-randr, maliit, xinput-calibrator, rpi-eeprom. 4. **Packages** — git, Chromium, wmctrl, SSH, swaybg, wlr-randr, maliit, xinput-calibrator.
5. **Kiosk files** — Download `start-chromium.sh` and `chromium-kiosk.desktop`; create autostart dir. 5. **Kiosk files** — Download `start-chromium.sh` and `chromium-kiosk.desktop`; create autostart dir.
6. **Boot splash and wallpaper** — Download `splash.png`; install Plymouth custom theme; copy image for LightDM and desktop. 6. **Boot splash and wallpaper** — Download `splash.png`; install Plymouth custom theme; copy image for LightDM and desktop.
7. **LightDM** — Download `99-default-session.conf` (rpd-labwc) and `99-wallpaper.conf` to `/etc/lightdm/lightdm.conf.d/`. 7. **LightDM** — Download `99-default-session.conf` (rpd-labwc) and `99-wallpaper.conf` to `/etc/lightdm/lightdm.conf.d/`.
@@ -17,10 +17,8 @@ This script runs once on first boot via cloud-init (see `user-data-remote-gnss.e
9. **reTerminal DM drivers** — Seeed repo clone and `reTerminal.sh`. 9. **reTerminal DM drivers** — Seeed repo clone and `reTerminal.sh`.
10. **Re-apply splash** — Set `disable_splash=0`, Plymouth theme to `custom` only, `update-initramfs`. 10. **Re-apply splash** — Set `disable_splash=0`, Plymouth theme to `custom` only, `update-initramfs`.
11. **Dark theme** — Set GTK dark theme for user `pi`: `~/.config/gtk-3.0/settings.ini` with `gtk-application-prefer-dark-theme=1` and `gtk-theme-name=PiXnoir` (Raspberry Pi OS dark theme). 11. **Dark theme** — Set GTK dark theme for user `pi`: `~/.config/gtk-3.0/settings.ini` with `gtk-application-prefer-dark-theme=1` and `gtk-theme-name=PiXnoir` (Raspberry Pi OS dark theme).
12. **CM4 EEPROM enable** — On CM4, `rpi-eeprom-update` is disabled by default. First-boot enables it by adding `RPI_EEPROM_USE_FLASHROM=1` and `CM4_ENABLE_RPI_EEPROM_UPDATE=1` to `/etc/default/rpi-eeprom-update`. **No config.txt changes are needed**`dtoverlay=audremap`/`dtoverlay=spi-gpio40-45` are for the flashrom method only and **must not be added** as they conflict with the reTerminal DM display backlight (GPIO13 PWM). The bootloader method (`pieeprom.upd`) is used instead. 12. **One-shots** — Download `set-rotation-once.sh` + `.desktop` from file server (wlr-randr for labwc). Wallpaper is set once via pcmanfm config during first-boot.
13. **Boot order** — If `rpi-eeprom-config` is available, set `BOOT_ORDER=0xf21` (eMMC first, then network, then restart). Also sets `NET_BOOT_MAX_RETRIES=3`, `DHCP_TIMEOUT=1500`, `DHCP_REQ_TIMEOUT=500`, `NET_INSTALL_AT_POWER_ON=0` so network boot fails fast when no TFTP server is available. On CM4 first boot this may be skipped (EEPROM not yet enabled); a one-shot systemd service runs after reboot to set boot order once. 13. **Reboot.**
14. **One-shots** — Download `set-rotation-once.sh` + `.desktop` from file server (wlr-randr for labwc). Wallpaper is set once via pcmanfm config during first-boot.
15. **Reboot.**
--- ---
@@ -55,7 +53,6 @@ Installs the software needed for the rest of the script and for the kiosk:
| **wlr-randr** | Display rotation for wlroots/labwc; one-shot sets “Left” (transform 270). | | **wlr-randr** | Display rotation for wlroots/labwc; one-shot sets “Left” (transform 270). |
| **maliit-keyboard** | On-screen keyboard for touch input. | | **maliit-keyboard** | On-screen keyboard for touch input. |
| **xinput-calibrator** | Touchscreen calibration (optional; run manually if needed). | | **xinput-calibrator** | Touchscreen calibration (optional; run manually if needed). |
| **rpi-eeprom** | EEPROM tools (`rpi-eeprom-update`, `rpi-eeprom-config`) for Pi 4/CM4 boot order (e.g. network first). |
--- ---
@@ -133,13 +130,7 @@ The reTerminal DM default is portrait. Rotation is set **persistently** via the
First-boot sets a dark GTK theme for user **pi** via **`~/.config/gtk-3.0/settings.ini`** with **`gtk-application-prefer-dark-theme=1`** and **`gtk-theme-name=PiXnoir`**. On older images use **Adwaita-dark** if PiXnoir is missing. First-boot sets a dark GTK theme for user **pi** via **`~/.config/gtk-3.0/settings.ini`** with **`gtk-application-prefer-dark-theme=1`** and **`gtk-theme-name=PiXnoir`**. On older images use **Adwaita-dark** if PiXnoir is missing.
## CM4: enable rpi-eeprom-update (for boot order)
On **CM4**, first-boot enables `rpi-eeprom-update` by setting **`RPI_EEPROM_USE_FLASHROM=1`** and **`CM4_ENABLE_RPI_EEPROM_UPDATE=1`** in **`/etc/default/rpi-eeprom-update`**. **No dtparams are added to config.txt.** `dtoverlay=audremap` and `dtoverlay=spi-gpio40-45` are only needed for the *flashrom* (direct SPI) update method — they **must not** be added because `audremap` remaps audio to GPIO12/13, which conflicts with the reTerminal DM display backlight PWM on GPIO13, causing a blank screen. The bootloader file method (`pieeprom.upd`) works without these overlays. See: [usbboot](https://github.com/raspberrypi/usbboot/blob/master/Readme.md).
## Boot order (eMMC first, then network)
If **`rpi-eeprom-config`** and **`rpi-eeprom-update`** are present (Pi 4/CM4), the script sets the EEPROM **`BOOT_ORDER=0xf21`**: try **SD/eMMC** first (0x1), then **network** (0x2), then **restart** (0xf). Network boot settings are tuned for fast fallback: `NET_BOOT_MAX_RETRIES=3`, `DHCP_TIMEOUT=1500` (1.5s), `DHCP_REQ_TIMEOUT=500` (0.5s), `NET_INSTALL_AT_POWER_ON=0`. The device boots from eMMC normally; if eMMC is blank it tries network boot for re-provisioning but gives up quickly when no TFTP server is available. **Pi 4:** applied on first-boot; EEPROM update scheduled for next reboot. **CM4:** a one-shot service (**`set-cm4-boot-order-once.service`**) runs after the next boot and sets the boot order, then removes itself. If “Could not read current EEPROM config” appears, run `sudo rpi-eeprom-update -l` on the device to see if a firmware file is listed; you can set boot order manually with `rpi-eeprom-config` if needed. If the tools are not available, the step is skipped.
## Reboot ## Reboot

View File

@@ -57,9 +57,9 @@ install_oneshot() {
log "--- Installing packages ---" log "--- Installing packages ---"
log "Running apt-get update ..." log "Running apt-get update ..."
apt-get update -qq apt-get update -qq
log "Installing: git chromium wmctrl openssh-server swaybg wlr-randr maliit-keyboard xinput-calibrator rpi-eeprom" log "Installing: git chromium wmctrl openssh-server swaybg wlr-randr maliit-keyboard xinput-calibrator"
apt-get install -y -qq git chromium wmctrl openssh-server \ apt-get install -y -qq git chromium wmctrl openssh-server \
swaybg wlr-randr maliit-keyboard xinput-calibrator rpi-eeprom swaybg wlr-randr maliit-keyboard xinput-calibrator
log "Packages installed successfully" log "Packages installed successfully"
# --- 2. Dirs and kiosk files from file server --- # --- 2. Dirs and kiosk files from file server ---
@@ -197,101 +197,6 @@ if [[ -f "$CMDLINE_PATH" ]]; then
fi fi
fi fi
# --- 6c. CM4: enable rpi-eeprom-update so boot order can be set ---
# On CM4, rpi-eeprom-update is disabled by default. Enable it by setting flags in /etc/default/rpi-eeprom-update.
# We use the bootloader method (pieeprom.upd file placed in /boot/firmware), NOT flashrom.
# NOTE: Do NOT add dtoverlay=audremap or dtoverlay=spi-gpio40-45 to config.txt.
# Those are only needed for the flashrom (direct SPI) method, and audremap CONFLICTS with
# the reTerminal DM display backlight (both use GPIO13 PWM).
# See: https://github.com/raspberrypi/usbboot , /etc/default/rpi-eeprom-update
log "--- CM4 EEPROM update enable (for boot order) ---"
EEPROM_DEFAULT="/etc/default/rpi-eeprom-update"
if [[ ! -f "$EEPROM_DEFAULT" ]]; then
touch "$EEPROM_DEFAULT"
log "Created $EEPROM_DEFAULT"
fi
grep -q '^RPI_EEPROM_USE_FLASHROM=' "$EEPROM_DEFAULT" && sed -i 's/^RPI_EEPROM_USE_FLASHROM=.*/RPI_EEPROM_USE_FLASHROM=1/' "$EEPROM_DEFAULT" || echo 'RPI_EEPROM_USE_FLASHROM=1' >> "$EEPROM_DEFAULT"
grep -q '^CM4_ENABLE_RPI_EEPROM_UPDATE=' "$EEPROM_DEFAULT" && sed -i 's/^CM4_ENABLE_RPI_EEPROM_UPDATE=.*/CM4_ENABLE_RPI_EEPROM_UPDATE=1/' "$EEPROM_DEFAULT" || echo 'CM4_ENABLE_RPI_EEPROM_UPDATE=1' >> "$EEPROM_DEFAULT"
log "Set RPI_EEPROM_USE_FLASHROM=1 and CM4_ENABLE_RPI_EEPROM_UPDATE=1 in $EEPROM_DEFAULT"
# --- 6d. Boot order: eMMC/SD first, then network, then restart (0xf21) ---
# BOOT_ORDER nibbles (right-to-left): 1=SD/eMMC, 2=network (TFTP), f=restart loop.
# On CM4, rpi-eeprom-update -l only works after reboot (once 6c is applied). So we try now; if it fails, a one-shot runs after next boot.
log "--- Boot order (0xf21: eMMC/SD first, then network, restart) ---"
BOOTCONF="/tmp/first-boot-eeprom-conf.txt"
BOOT_ORDER_SET=0
if command -v rpi-eeprom-config >/dev/null 2>&1 && command -v rpi-eeprom-update >/dev/null 2>&1; then
if PEE="$(rpi-eeprom-update -l 2>/dev/null)" && [[ -n "$PEE" ]] && [[ -f "$PEE" ]]; then
rpi-eeprom-config "$PEE" > "$BOOTCONF" 2>/dev/null || true
fi
if [[ -s "$BOOTCONF" ]]; then
sed -i 's/^BOOT_ORDER=.*/BOOT_ORDER=0xf21/' "$BOOTCONF"
grep -q '^BOOT_ORDER=' "$BOOTCONF" || echo 'BOOT_ORDER=0xf21' >> "$BOOTCONF"
# Limit network boot: 3 retries, 1500ms DHCP timeout (fail fast to eMMC)
sed -i '/^NET_BOOT_MAX_RETRIES=/d; /^DHCP_TIMEOUT=/d; /^DHCP_REQ_TIMEOUT=/d; /^TFTP_IP=/d; /^NET_INSTALL_AT_POWER_ON=/d' "$BOOTCONF"
echo 'NET_BOOT_MAX_RETRIES=3' >> "$BOOTCONF"
echo 'DHCP_TIMEOUT=1500' >> "$BOOTCONF"
echo 'DHCP_REQ_TIMEOUT=500' >> "$BOOTCONF"
echo 'NET_INSTALL_AT_POWER_ON=0' >> "$BOOTCONF"
if rpi-eeprom-config --apply "$BOOTCONF" 2>/dev/null; then
log "Boot order set to 0xf21 (eMMC first, then network, restart); EEPROM update scheduled for next reboot"
@ BOOT_ORDER_SET=1
else
log "WARNING: rpi-eeprom-config --apply failed; boot order unchanged"
fi
else
log "rpi-eeprom-update -l did not return a config (on CM4 this is normal until after reboot with 6c applied); scheduling one-shot to set boot order after next boot"
fi
rm -f "$BOOTCONF"
else
log "rpi-eeprom-config/rpi-eeprom-update not found; skipping boot order (not a Pi4/CM4 or package missing)"
fi
# If boot order was not set (e.g. CM4 first boot), install a one-shot systemd service to set it after reboot
if [[ "$BOOT_ORDER_SET" -eq 0 ]] && command -v rpi-eeprom-config >/dev/null 2>&1 && command -v rpi-eeprom-update >/dev/null 2>&1; then
ONCE_SCRIPT="/usr/local/bin/set-cm4-boot-order-once.sh"
ONCE_SVC="/etc/systemd/system/set-cm4-boot-order-once.service"
cat > "$ONCE_SCRIPT" << 'SETBOOTEOF'
#!/bin/bash
# One-shot: set BOOT_ORDER=0xf21 (eMMC first, then network) when rpi-eeprom-update becomes available (e.g. after CM4 enable and reboot).
BOOTCONF="/tmp/eeprom-boot-order-once.txt"
if PEE="$(rpi-eeprom-update -l 2>/dev/null)" && [[ -n "$PEE" ]] && [[ -f "$PEE" ]]; then
rpi-eeprom-config "$PEE" > "$BOOTCONF" 2>/dev/null
if [[ -s "$BOOTCONF" ]]; then
sed -i 's/^BOOT_ORDER=.*/BOOT_ORDER=0xf21/' "$BOOTCONF"
grep -q '^BOOT_ORDER=' "$BOOTCONF" || echo 'BOOT_ORDER=0xf21' >> "$BOOTCONF"
sed -i '/^NET_BOOT_MAX_RETRIES=/d; /^DHCP_TIMEOUT=/d; /^DHCP_REQ_TIMEOUT=/d; /^TFTP_IP=/d; /^NET_INSTALL_AT_POWER_ON=/d' "$BOOTCONF"
echo 'NET_BOOT_MAX_RETRIES=3' >> "$BOOTCONF"
echo 'DHCP_TIMEOUT=1500' >> "$BOOTCONF"
echo 'DHCP_REQ_TIMEOUT=500' >> "$BOOTCONF"
echo 'NET_INSTALL_AT_POWER_ON=0' >> "$BOOTCONF"
if rpi-eeprom-config --apply "$BOOTCONF" 2>/dev/null; then
echo "Boot order set to 0xf21 (eMMC first, then network)"
fi
fi
rm -f "$BOOTCONF"
fi
systemctl disable set-cm4-boot-order-once.service 2>/dev/null || true
rm -f /etc/systemd/system/set-cm4-boot-order-once.service
rm -f "$0"
SETBOOTEOF
chmod 755 "$ONCE_SCRIPT"
cat > "$ONCE_SVC" << 'SVCEOF'
[Unit]
Description=Set CM4 boot order once (eMMC first, then network)
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/set-cm4-boot-order-once.sh
RemainAfterExit=no
[Install]
WantedBy=multi-user.target
SVCEOF
systemctl enable set-cm4-boot-order-once.service 2>/dev/null && log "Enabled set-cm4-boot-order-once.service to set boot order after next boot"
fi
# --- 7. One-shots (wallpaper already set in pcmanfm config above; rotation is via cmdline.txt) --- # --- 7. One-shots (wallpaper already set in pcmanfm config above; rotation is via cmdline.txt) ---
log "--- One-shot scripts (if any) ---" log "--- One-shot scripts (if any) ---"
# Rotation is set persistently in cmdline.txt (video=DSI-1:rotate=90), not via one-shot script. # Rotation is set persistently in cmdline.txt (video=DSI-1:rotate=90), not via one-shot script.

View File

@@ -6,7 +6,7 @@ This describes the full flow from power-on to eMMC deploy/backup when using **ne
## Overview ## Overview
1. **reTerminal** is set to try **eMMC first, then network** (EEPROM `BOOT_ORDER=0xf21`). 1. **reTerminal** is set to try **eMMC first, then network** (EEPROM `BOOT_ORDER=0xf21`) via the dashboard **Update EEPROM** when the device is connected over USB boot, or set manually.
2. It is connected to the **same LAN as the LXCs eth1** (e.g. 10.20.50.0/24). 2. It is connected to the **same LAN as the LXCs eth1** (e.g. 10.20.50.0/24).
3. On power-on it gets an IP via **DHCP** and loads **boot files via TFTP** from the LXC. 3. On power-on it gets an IP via **DHCP** and loads **boot files via TFTP** from the LXC.
4. The **netboot environment** (kernel + rootfs) runs **provisioning-client.sh**, which registers with the **dashboard** and polls for an action. 4. The **netboot environment** (kernel + rootfs) runs **provisioning-client.sh**, which registers with the **dashboard** and polls for an action.
@@ -29,7 +29,7 @@ The **dashboard** (Flask) runs in the LXC and is reachable at e.g. `http://10.20
### 2. reTerminal (device) ### 2. reTerminal (device)
- **EEPROM**: `BOOT_ORDER=0xf21` (eMMC first, then network). Can be set by cloud-init first-boot on an already-flashed device. - **EEPROM**: `BOOT_ORDER=0xf21` (eMMC first, then network). Set via dashboard **Update EEPROM** (USB boot) or manually (usbboot recovery / `rpi-eeprom-config` on device). Not set by first-boot.
- **Network**: Ethernet connected to the same segment as the LXCs **eth1** (e.g. same switch/VLAN as 10.20.50.0/24). - **Network**: Ethernet connected to the same segment as the LXCs **eth1** (e.g. same switch/VLAN as 10.20.50.0/24).
- On **power-on**: - On **power-on**:
1. Pi 4/CM4 firmware does **DHCP** on the wired interface. 1. Pi 4/CM4 firmware does **DHCP** on the wired interface.

View File

@@ -67,7 +67,7 @@ Your current LXC already has eth0 (10.130.60.141) and eth1 (10.20.50.1); the set
## After setup: reTerminal network boot ## After setup: reTerminal network boot
1. Set the reTerminal **boot order** to try eMMC first, then network (e.g. `BOOT_ORDER=0xf21`; see cloud-init/first-boot). 1. Set the reTerminal **boot order** to try eMMC first, then network (e.g. `BOOT_ORDER=0xf21`): use the dashboard **Update EEPROM** when the device is connected via USB boot, or set manually (usbboot recovery / `rpi-eeprom-config` on device). Not set by first-boot.
2. Connect the reTerminal to the **same network as the LXCs eth1** (e.g. 10.20.50.0/24). 2. Connect the reTerminal to the **same network as the LXCs eth1** (e.g. 10.20.50.0/24).
3. Power on; it will get an IP via DHCP and load boot files via TFTP from the LXC. 3. Power on; it will get an IP via DHCP and load boot files via TFTP from the LXC.
4. For **provisioning** (Backup/Deploy), the netboot environment must run **network-client/provisioning-client.sh** with `PROVISIONING_SERVER=http://10.20.50.1:5000` so it talks to the dashboard on the LXC. 4. For **provisioning** (Backup/Deploy), the netboot environment must run **network-client/provisioning-client.sh** with `PROVISIONING_SERVER=http://10.20.50.1:5000` so it talks to the dashboard on the LXC.

View File

@@ -27,25 +27,19 @@ else
fi fi
mkdir -p "$EEPROM_DIR" mkdir -p "$EEPROM_DIR"
cd "$EEPROM_DIR"
echo "Downloading rpi-eeprom-config..." echo "Downloading rpi-eeprom-config..."
$GET_O "$EEPROM_DIR/rpi-eeprom-config" "$RPI_EEPROM_RAW/rpi-eeprom-config" $GET_O "$EEPROM_DIR/rpi-eeprom-config" "$RPI_EEPROM_RAW/rpi-eeprom-config"
$GET_O "$EEPROM_DIR/rpi-eeprom-digest" "$RPI_EEPROM_RAW/rpi-eeprom-digest" $GET_O "$EEPROM_DIR/rpi-eeprom-digest" "$RPI_EEPROM_RAW/rpi-eeprom-digest"
chmod +x "$EEPROM_DIR/rpi-eeprom-config" "$EEPROM_DIR/rpi-eeprom-digest" chmod +x "$EEPROM_DIR/rpi-eeprom-config" "$EEPROM_DIR/rpi-eeprom-digest"
echo "Finding latest BCM2711 EEPROM firmware..."
LATEST_FW=$($GET "https://api.github.com/repos/raspberrypi/rpi-eeprom/contents/firmware-2711/default" \ LATEST_FW=$($GET "https://api.github.com/repos/raspberrypi/rpi-eeprom/contents/firmware-2711/default" \
| grep -o '"name" *: *"pieeprom-[^"]*\.bin"' | sed 's/"name" *: *"//;s/"//' | sort | tail -1) | grep -o '"name" *: *"pieeprom-[^"]*\.bin"' | sed 's/"name" *: *"//;s/"//' | sort | tail -1)
if [ -z "$LATEST_FW" ]; then if [ -z "$LATEST_FW" ]; then
echo "WARNING: Could not determine latest firmware from GitHub API. Try again or download pieeprom.bin manually." echo "WARNING: Could not determine latest firmware from GitHub API. Try again or download pieeprom.bin manually."
exit 1 else
$GET_O "$EEPROM_DIR/pieeprom.bin" "$RPI_EEPROM_RAW/firmware-2711/default/$LATEST_FW"
fi fi
echo "Downloading $LATEST_FW..."
$GET_O "$EEPROM_DIR/pieeprom.bin" "$RPI_EEPROM_RAW/firmware-2711/default/$LATEST_FW"
if [ ! -s "$EEPROM_DIR/pieeprom.bin" ]; then if [ ! -s "$EEPROM_DIR/pieeprom.bin" ]; then
echo "ERROR: pieeprom.bin is missing or empty" echo "ERROR: pieeprom.bin is missing or empty"
exit 1 exit 1
@@ -56,5 +50,4 @@ if ! python3 "$EEPROM_DIR/rpi-eeprom-config" "$EEPROM_DIR/pieeprom.bin" >/dev/nu
echo "WARNING: rpi-eeprom-config could not read pieeprom.bin (non-fatal)" echo "WARNING: rpi-eeprom-config could not read pieeprom.bin (non-fatal)"
fi fi
echo "Done. EEPROM tools installed:" echo "Done. EEPROM tools installed to $EEPROM_DIR"
ls -la "$EEPROM_DIR"