Files
reterminal-dm4/emmc-provisioning/cloud-init/first-boot.md
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

13 KiB
Raw Blame History

first-boot.sh — Documentation

This script runs once on first boot via cloud-init (see user-data-remote-gnss.example). It installs packages, configures a Chromium kiosk with rpd-labwc (Raspberry Pi Desktop + labwc) and touch support, and installs the reTerminal DM display/touch drivers. It must run as root.


Structure (sections)

  1. ConstantsFILE_SERVER, PI_USER, paths, log file.
  2. Logging — All output teed to /var/log/first-boot.log.
  3. Helpersinstall_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.
  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.
  7. LightDM — Download 99-default-session.conf (rpd-labwc) and 99-wallpaper.conf to /etc/lightdm/lightdm.conf.d/.
  8. Maliit — Download maliit-keyboard.desktop from file server to pis 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. 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 neededdtoverlay=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.
  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.
  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.

Script header and environment

  • set -e — Exit immediately if any command fails.
  • DEBIAN_FRONTEND=noninteractive — Prevents apt from asking questions (assumes default or automatic answers).

Logging

All script output (stdout and stderr) is appended to /var/log/first-boot.log so you can review what ran after first boot (e.g. over SSH: cat /var/log/first-boot.log).

  • LOGFILE — Path of the log file (/var/log/first-boot.log).
  • log "..." — Prints a timestamped line (ISO format); used for section headers.
  • exec > >(tee -a "$LOGFILE") 2>&1 — Sends all subsequent stdout and stderr to both the console and the log file.

Packages

Installs the software needed for the rest of the script and for the kiosk:

Package Purpose
git Clone the Seeed Linux DTOverlays repo for reTerminal DM drivers.
chromium-browser Full-screen kiosk browser.
wmctrl Window control; used to force Chromium into fullscreen.
openssh-server SSH access (often also enabled in user-data).
swaybg Wallpaper for labwc (Wayland); used by one-shot and labwc autostart.
wlr-randr Display rotation for wlroots/labwc; one-shot sets “Left” (transform 270).
maliit-keyboard On-screen keyboard for touch input.
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).

Autostart directory

Creates /home/pi/.config/autostart so that .desktop files placed there are started when user pi logs into the graphical session.


Chromium kiosk files (from file server)

Downloads from FILE_SERVER (no local creation):

  • FILE_SERVER — Base URL for first-boot assets (default: http://10.130.60.141:5000/files/first-boot). All first-boot files are served from a first-boot subfolder on the file server. Change this if your server or path is different.
  • start-chromium.sh — Downloaded to /home/pi/start-chromium.sh, made executable (755), owned by pi. Waits for the desktop, then starts Chromium in fullscreen. When the session is Wayland (rpd-labwc), Chromium runs with --ozone-platform=wayland so touch long-press produces right-click (context menu) like the rest of the desktop; on X11 it falls back to --ozone-platform=x11 and uses wmctrl to force fullscreen.
  • chromium-kiosk.desktop — Downloaded to /home/pi/.config/autostart/chromium-kiosk.desktop, mode 644, owned by pi. This autostart entry runs start-chromium.sh when pi logs in.

Ensure the .desktop file on the server has Exec=/home/pi/start-chromium.sh (or the path you use on the device).

Touch in Chromium: Long-press on the touchscreen to open the context menu (right-click). This works when Chromium runs as a Wayland client (default under rpd-labwc). If you ever run under pure X11, long-press may not trigger the context menu; in that case you can use evdev-right-click-emulation (see e.g. evdev-right-click-emulation) to inject right-click on long-press at the input layer.


Boot splash and wallpaper (single image from file server)

A single image (splash.png) is used for the boot splash, login screen, and desktop wallpaper. Host it at ${FILE_SERVER}/splash.png (e.g. http://10.130.60.141:5000/files/splash.png).

  • Plymouth (boot splash): Downloads splash.png, custom.plymouth, and custom.script from the file server → installs to /usr/share/plymouth/themes/custom/ → sets Theme=custom in /etc/plymouth/plymouthd.conf (single [Daemon] section) → runs update-initramfs -u. If any download fails, logs a warning and continues. Note: On reTerminal DM the DSI panel can initialize a few seconds into boot, so the Plymouth splash may appear briefly or after a short black screen; this is normal for DSI displays.
  • LightDM (login screen): Copies the same image to /usr/share/rpd-wallpaper/splash.png and writes /etc/lightdm/lightdm.conf.d/99-wallpaper.conf with wallpaper=... and wallpaper_mode=crop.
  • Desktop wallpaper: First-boot sets the wallpaper once by writing pcmanfm config: ~/.config/pcmanfm/LXDE-pi/desktop-items-0.conf and default/desktop-items-0.conf with wallpaper=/usr/share/rpd-wallpaper/splash.png and wallpaper_mode=crop. pcmanfm-pi (rpd-labwc desktop) reads this and shows the wallpaper; no autostart script. To set or change wallpaper manually: pcmanfm --set-wallpaper /path/to/image.png --wallpaper-mode=crop (modes: crop, stretch, fit, center, tile, screen, color).

LightDM: default session (rpd-labwc)

Writes /etc/lightdm/lightdm.conf.d/99-default-session.conf so the display manager (LightDM) uses the rpd-labwc session (Raspberry Pi Desktop with labwc Wayland compositor). The script also patches /etc/lightdm/lightdm.conf so user-session and autologin-session are rpd-labwc.


On-screen keyboard (Maliit)

Creates /home/pi/.config/autostart/maliit-keyboard.desktop so that Maliit (maliit-keyboard -r) starts when pi logs in. This gives an on-screen keyboard for touch-only use.


Ownership for pis config

Runs chown -R pi:pi /home/pi/.config so all files under pis config directory are owned by pi. Ensures the desktop session runs as pi without permission issues.


reTerminal DM: Seeed display/touch drivers

Installs the official Seeed drivers for the reTerminal DM so the display and touch work:

  1. Clones https://github.com/Seeed-Studio/seeed-linux-dtoverlays into /tmp/seeed-linux-dtoverlays (--depth 1 for a shallow clone).
  2. Runs scripts/reTerminal.sh --device reTerminal-DM to install device-tree overlays and any required firmware/config for the reTerminal DM.
  3. Removes the clone from /tmp.

These changes take effect after a reboot.


Screen rotation (portrait → landscape, 90° clockwise)

The reTerminal DM default is portrait. Rotation is set persistently via the kernel command line (KMS driver), so it survives reboots and does not depend on the desktop session.

  • Kernel cmdline — First-boot appends video=DSI-1:rotate=90 to /boot/firmware/cmdline.txt (or /boot/cmdline.txt). The file must remain one single line with no line breaks.
  • 90° clockwise — The value 90 gives 90° clockwise rotation. Other valid values: 180, 270 (90° counter-clockwise).
  • Effect — Rotation is applied by the kernel at boot; no one-shot script or wlr-randr needed.

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 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.

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

Runs reboot so the kernel and display stack load the new Seeed drivers and the cmdline rotation. After reboot, the screen and touch work with rotation applied (video=DSI-1:rotate=90), and the Chromium kiosk and Maliit start via autostart on pi's login.


Customisation

  • File server — Edit FILE_SERVER if your assets are served from another host/port. Host all files listed in files-from-guard/README.md and config-files/README.md (kiosk, splash, Plymouth, LightDM, Maliit, one-shots and their .desktop files).
  • Kiosk URL — The URL Chromium opens is defined in start-chromium.sh on your file server (e.g. --app=http://127.0.0.1:8080); change it there.
  • User — If you use a user other than pi, replace pi in this script and in the files on the file server (paths and ownership).
  • Screen rotation — Set in /boot/firmware/cmdline.txt: video=DSI-1:rotate=90 (90° clockwise). Use 180 or 270 for other orientations. Keep the file one single line.
  • Desktop wallpaper — First-boot writes wallpaper= and wallpaper_mode=crop into pcmanfms desktop-items-0.conf. To change later: pcmanfm --set-wallpaper /path/to/image --wallpaper-mode=crop. Other pcmanfm options: pcmanfm --desktop (start desktop manager), pcmanfm --desktop-pref (open desktop preferences GUI), pcmanfm --desktop-off (stop desktop manager), pcmanfm -w FILE (short form of --set-wallpaper). Wallpaper modes: crop, stretch, fit, center, tile, screen, color.