diff --git a/chromium-setup/emmc-provisioning/cloud-init/first-boot.md b/chromium-setup/emmc-provisioning/cloud-init/first-boot.md index 969098b..176024a 100644 --- a/chromium-setup/emmc-provisioning/cloud-init/first-boot.md +++ b/chromium-setup/emmc-provisioning/cloud-init/first-boot.md @@ -16,9 +16,11 @@ This script runs once on first boot via cloud-init (see `user-data-remote-gnss.e 8. **Maliit** — Download `maliit-keyboard.desktop` from file server to pi’s autostart. 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`. -11. **Boot order** — If `rpi-eeprom-config` is available, set `BOOT_ORDER=0x21` (network first, then eMMC/SD) for future network boot / re-provisioning. -12. **One-shots** — Download `set-rotation-once.sh` + `.desktop` from file server (wlr-randr for labwc). Wallpaper is set once by creating `~/.config/labwc/autostart` during first-boot. -13. **Reboot.** +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`; adding a `[cm4]` block to `config.txt` with `dtparam=spi=on`, `dtoverlay=audremap`, `dtoverlay=spi-gpio40-45`. After reboot, `rpi-eeprom-update -l` works and boot order can be set. +13. **Boot order** — If `rpi-eeprom-config` is available, set `BOOT_ORDER=0x21` (network first, then eMMC/SD). 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. +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.** --- @@ -126,9 +128,17 @@ The reTerminal DM default is portrait. Rotation is set using **wlr-randr** (labw --- +## Dark theme + +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: (1) **`/etc/default/rpi-eeprom-update`**: **`RPI_EEPROM_USE_FLASHROM=1`**, **`CM4_ENABLE_RPI_EEPROM_UPDATE=1`**; (2) **config.txt** **`[cm4]`** block: **`dtparam=spi=on`**, **`dtoverlay=audremap`**, **`dtoverlay=spi-gpio40-45`**. After reboot, **`rpi-eeprom-update -l`** works. See: [usbboot](https://github.com/raspberrypi/usbboot/blob/master/Readme.md). + ## Boot order (network first, then eMMC/SD) -If **`rpi-eeprom-config`** and **`rpi-eeprom-update`** are present (Pi 4/CM4), the script sets the EEPROM **`BOOT_ORDER=0x21`**: try **network** first (0x2), then **SD/eMMC** (0x1). This allows future network boot or re-provisioning (e.g. PXE or USB gadget) before falling back to local storage. The EEPROM update is scheduled for the next reboot; no second reboot is required. 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. +If **`rpi-eeprom-config`** and **`rpi-eeprom-update`** are present (Pi 4/CM4), the script sets the EEPROM **`BOOT_ORDER=0x21`**: try **network** first (0x2), then **SD/eMMC** (0x1). **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 BOOT_ORDER=0x21, then removes itself (two reboots for network-first). 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 diff --git a/chromium-setup/emmc-provisioning/cloud-init/first-boot.sh b/chromium-setup/emmc-provisioning/cloud-init/first-boot.sh index c44e703..8ab75d1 100644 --- a/chromium-setup/emmc-provisioning/cloud-init/first-boot.sh +++ b/chromium-setup/emmc-provisioning/cloud-init/first-boot.sh @@ -131,6 +131,19 @@ fi log "--- Maliit ---" mkdir -p "$AUTOSTART" "$PI_HOME/.config" curl -fsSL "${FILE_SERVER}/maliit-keyboard.desktop" -o "$AUTOSTART/maliit-keyboard.desktop" 2>/dev/null && log "maliit-keyboard.desktop installed" || log "WARNING: Could not download maliit-keyboard.desktop" + +# --- 5b. Dark theme (GTK + prefer dark for apps) --- +log "--- Dark theme ---" +GTK_SETTINGS="$PI_HOME/.config/gtk-3.0/settings.ini" +mkdir -p "$(dirname "$GTK_SETTINGS")" +if [[ ! -f "$GTK_SETTINGS" ]]; then + printf '%s\n' '[Settings]' 'gtk-application-prefer-dark-theme=1' 'gtk-theme-name=PiXnoir' > "$GTK_SETTINGS" +else + grep -q '^gtk-application-prefer-dark-theme=' "$GTK_SETTINGS" && sed -i 's/^gtk-application-prefer-dark-theme=.*/gtk-application-prefer-dark-theme=1/' "$GTK_SETTINGS" || echo 'gtk-application-prefer-dark-theme=1' >> "$GTK_SETTINGS" + grep -q '^gtk-theme-name=' "$GTK_SETTINGS" && sed -i 's/^gtk-theme-name=.*/gtk-theme-name=PiXnoir/' "$GTK_SETTINGS" || echo 'gtk-theme-name=PiXnoir' >> "$GTK_SETTINGS" +fi +# Fallback if PiXnoir not installed (e.g. older image): Adwaita-dark +log "Set dark theme (PiXnoir) in gtk-3.0/settings.ini" chown -R "$PI_USER:$PI_USER" "$PI_HOME/.config" # --- 6. reTerminal DM drivers (Seeed) --- @@ -177,11 +190,38 @@ if [[ -f "$CMDLINE_PATH" ]] && ! grep -q 'swiotlb=' "$CMDLINE_PATH"; then log "Added swiotlb=65536 to kernel cmdline (vc4-drm / DSI)" fi -# --- 6c. Boot order: network first, then eMMC/SD (for future network boot / re-provisioning) --- +# --- 6c. CM4: enable rpi-eeprom-update (flashrom + config.txt [cm4] block) so boot order can be set --- +# On CM4, rpi-eeprom-update is disabled by default. Enable it so we can set BOOT_ORDER=0x21 (network first). +# 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" +# config.txt: [cm4] section with SPI for EEPROM (only applied when booting a CM4) +if [[ -f "$CFG_PATH" ]]; then + if ! grep -q '^\[cm4\]' "$CFG_PATH"; then + printf '%s\n' '' '[cm4]' 'dtparam=spi=on' 'dtoverlay=audremap' 'dtoverlay=spi-gpio40-45' >> "$CFG_PATH" + log "Added [cm4] block (spi, audremap, spi-gpio40-45) to config.txt for EEPROM" + else + for ENTRY in 'dtparam=spi=on' 'dtoverlay=audremap' 'dtoverlay=spi-gpio40-45'; do + grep -q "^$ENTRY" "$CFG_PATH" || echo "$ENTRY" >> "$CFG_PATH" + done + log "Ensured [cm4] EEPROM entries in config.txt" + fi +fi + +# --- 6d. Boot order: network first, then eMMC/SD (for future network boot / re-provisioning) --- # BOOT_ORDER: 0x2 = network, 0x1 = SD/eMMC. 0x21 = try network first, then local storage. +# 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 (network first, then eMMC/SD) ---" +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 - BOOTCONF="/tmp/first-boot-eeprom-conf.txt" if PEE="$(rpi-eeprom-update -l 2>/dev/null)" && [[ -n "$PEE" ]] && [[ -f "$PEE" ]]; then rpi-eeprom-config "$PEE" > "$BOOTCONF" 2>/dev/null || true fi @@ -190,17 +230,58 @@ if command -v rpi-eeprom-config >/dev/null 2>&1 && command -v rpi-eeprom-update grep -q '^BOOT_ORDER=' "$BOOTCONF" || echo 'BOOT_ORDER=0x21' >> "$BOOTCONF" if rpi-eeprom-config --apply "$BOOTCONF" 2>/dev/null; then log "Boot order set to 0x21 (network first, then eMMC/SD); EEPROM update scheduled for next reboot" + BOOT_ORDER_SET=1 else log "WARNING: rpi-eeprom-config --apply failed; boot order unchanged" fi else - log "WARNING: Could not read current EEPROM config; skipping boot order change (run 'rpi-eeprom-update -l' as root to check)" + 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=0x21 (network first) 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=0x21/' "$BOOTCONF" + grep -q '^BOOT_ORDER=' "$BOOTCONF" || echo 'BOOT_ORDER=0x21' >> "$BOOTCONF" + if rpi-eeprom-config --apply "$BOOTCONF" 2>/dev/null; then + echo "Boot order set to 0x21 (network first, then eMMC/SD)" + 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 (network first) +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 (rotation at first login; wallpaper already set in pcmanfm config above) --- log "--- One-shot scripts (run at pi first login) ---" install_oneshot set-rotation-once || true