Revise the first-boot script to implement a structured approach with 13 numbered steps, allowing for better control over the execution order. Introduce two new one-shot scripts: `01-set-rotation-once.sh` and `02-set-wallpaper-once.sh`, replacing the previous single script approach. Update documentation to reflect these changes, including the new configuration options for enabling/disabling steps and the revised file structure for one-shot scripts. Enhance the dashboard to display first-boot progress, improving user feedback during the initial setup.
11 KiB
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.
Config file (first-boot.conf)
You can override script behaviour without editing first-boot.sh by using a config file. Copy first-boot.conf.example to first-boot.conf, edit the variables you need, and ensure the script can load it. The script looks for a config file in this order:
- Same directory as the script — e.g. if you host both at
.../first-boot/first-boot.shand.../first-boot/first-boot.conf. /tmp/first-boot.conf— when run via cloud-init, add a runcmd line to download your config to/tmp/first-boot.confbefore running the script./etc/cm4-provisioning/first-boot.conf— for host-side or pre-written config.
Only set variables you want to change; the rest use built-in defaults. See first-boot.conf.example for all options (FILE_SERVER, HOSTNAME, PI_USER, PACKAGES, LIGHTDM_SESSION, GTK_THEME_NAME, WALLPAPER_MODE, DSI_ROTATE, SWIOTLB_SIZE, RETERMINAL_DEVICE, RETERMINAL_REPO_URL, ONESHOT_SCRIPTS, etc.).
Structure (steps and enable flags)
The script runs 13 numbered steps (step_01_hostname … step_13_reboot). Disable a step by setting ENABLE_STEP_NN=0 in config (default: all 1). Step table: 01=hostname, 02=packages, 03=kiosk_files, 04=splash_wallpaper, 05=lightdm, 06=maliit, 07=dark_theme, 08=reterminal_drivers, 09=reapply_splash, 10=cmdline, 11=oneshots, 12=log_permissions, 13=reboot.
- Config & constants — Load optional
first-boot.conf; thenFILE_SERVER,PI_USER, paths, log file (defaults or from config). - Logging — All output tee’d to
/var/log/first-boot.log. - Helpers —
install_oneshot(name)downloads${name}.shfrom the file server and installs it as a one-shot autostart (runs once at pi’s first login, then deletes itself). - Packages — git, Chromium, wmctrl, SSH, swaybg, wlr-randr, maliit, xinput-calibrator.
- Kiosk files — Download
start-chromium.shandchromium-kiosk.desktop; create autostart dir. - Boot splash and wallpaper — Download
splash.png; install Plymouth custom theme; copy image for LightDM and desktop. - LightDM — Download
99-default-session.conf(rpd-labwc) and99-wallpaper.confto/etc/lightdm/lightdm.conf.d/. - Maliit — Download
maliit-keyboard.desktopfrom file server to pi’s autostart. - reTerminal DM drivers — Seeed repo clone and
reTerminal.sh. - Re-apply splash — Set
disable_splash=0, Plymouth theme tocustomonly,update-initramfs. - Dark theme — Set GTK dark theme for user
pi:~/.config/gtk-3.0/settings.iniwithgtk-application-prefer-dark-theme=1andgtk-theme-name=PiXnoir(Raspberry Pi OS dark theme).
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). |
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.20.50.1: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 bypi. Waits for the desktop, then starts Chromium in fullscreen. When the session is Wayland (rpd-labwc), Chromium runs with--ozone-platform=waylandso touch long-press produces right-click (context menu) like the rest of the desktop; on X11 it falls back to--ozone-platform=x11and useswmctrlto force fullscreen.chromium-kiosk.desktop— Downloaded to/home/pi/.config/autostart/chromium-kiosk.desktop, mode 644, owned bypi. This autostart entry runsstart-chromium.shwhenpilogs 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.20.50.1:5000/files/splash.png).
- Plymouth (boot splash): Downloads
splash.png,custom.plymouth, andcustom.scriptfrom the file server → installs to/usr/share/plymouth/themes/custom/→ setsTheme=customin/etc/plymouth/plymouthd.conf(single[Daemon]section) → runsupdate-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.pngand writes/etc/lightdm/lightdm.conf.d/99-wallpaper.confwithwallpaper=...andwallpaper_mode=crop. - Desktop wallpaper: First-boot sets the wallpaper once by writing pcmanfm config:
~/.config/pcmanfm/LXDE-pi/desktop-items-0.confanddefault/desktop-items-0.confwithwallpaper=/usr/share/rpd-wallpaper/splash.pngandwallpaper_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 pi’s config
Runs chown -R pi:pi /home/pi/.config so all files under pi’s 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:
- Clones https://github.com/Seeed-Studio/seeed-linux-dtoverlays into
/tmp/seeed-linux-dtoverlays(--depth 1for a shallow clone). - Runs
scripts/reTerminal.sh --device reTerminal-DMto install device-tree overlays and any required firmware/config for the reTerminal DM. - 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=90to/boot/firmware/cmdline.txt(or/boot/cmdline.txt). The file must remain one single line with no line breaks. - 90° clockwise — The value
90gives 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.
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_SERVERif your assets are served from another host/port. Host all files listed infiles-from-guard/README.mdandconfig-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.shon your file server (e.g.--app=http://127.0.0.1:8080); change it there. - User — If you use a user other than
pi, replacepiin 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). Use180or270for other orientations. Keep the file one single line. - Desktop wallpaper — First-boot writes
wallpaper=andwallpaper_mode=cropinto pcmanfm’sdesktop-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.