# 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. **Constants** — `FILE_SERVER`, `PI_USER`, paths, log file. 2. **Logging** — All output tee’d 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 pi’s 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 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.** --- ## 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`. This script waits for the desktop, starts Chromium in kiosk mode (e.g. `--app=...`), 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). --- ## 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 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: 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, “Left”) The reTerminal DM default is portrait. Rotation is set using **wlr-randr** (labwc/Wayland), so nothing is written to `/boot/firmware/config.txt`. - **One-shot autostart** — A small script runs once when user `pi` first logs into the graphical session: - **`/home/pi/set-rotation-once.sh`** — Waits 5 seconds, detects the output name with `wlr-randr`, then runs `wlr-randr --output --transform 270` (Left / 90° counter-clockwise). Falls back to `DSI-1` if detection fails. - **`/home/pi/.config/autostart/set-rotation-once.desktop`** — Autostart entry that runs the script once at first login. Both the script and this desktop file **delete themselves** after a successful run, so rotation is applied only on first boot and never again. - **Effect** — Same as choosing “Left” in display settings. Rotation applies after the first login; no reboot needed for rotation (only for the Seeed drivers). --- ## 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. ## Reboot Runs **`reboot`** so the kernel and display stack load the new Seeed drivers. After reboot, the screen and touch work; on **pi**’s first login the one-shot sets rotation to “Left” (landscape), and the Chromium kiosk and Maliit start via autostart. --- ## 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** — The one-shot runs `wlr-randr --output --transform 270` (Left). To use another orientation, change `270` to `90` (right), `180` (inverted), or `normal`. - **Desktop wallpaper** — First-boot writes `wallpaper=` and `wallpaper_mode=crop` into pcmanfm’s `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`.