Update the one-shot script to set screen rotation using kanshi based on kernel command line parameters, replacing the previous wlr-randr method. The script now writes the configuration to ~/.config/kanshi/config and sets the GTK dark theme (PiXnoir or Adwaita-dark) at first login. Additionally, enhance documentation to reflect these changes and clarify the role of the new script in the first-boot process.
160 lines
12 KiB
Markdown
160 lines
12 KiB
Markdown
# 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:
|
||
|
||
1. **Same directory as the script** — e.g. if you host both at `.../first-boot/first-boot.sh` and `.../first-boot/first-boot.conf`.
|
||
2. **`/tmp/first-boot.conf`** — when run via cloud-init, add a runcmd line to download your config to `/tmp/first-boot.conf` before running the script.
|
||
3. **`/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.
|
||
|
||
1. **Config & constants** — Load optional `first-boot.conf`; then `FILE_SERVER`, `PI_USER`, paths, log file (defaults or from config).
|
||
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.
|
||
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. **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).
|
||
|
||
---
|
||
|
||
## 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. |
|
||
| **kanshi** | Display rotation: ~/.config/kanshi/config is written at login with transform from cmdline (same as Control Center). The same login scripts also set GTK dark theme (~/.config/gtk-3.0/settings.ini). |
|
||
| **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 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 long-press → right-click in Chromium:** Under Wayland (rpd-labwc), long-press may work for right-click elsewhere (e.g. desktop) but **not inside Chromium**—Chromium gets touch events directly and does not implement long-press-as-right-click. To get context menu on long-press in the browser (and everywhere), use **evdev-right-click-emulation** at the input layer so long-press is converted to right-click before any app sees it: [evdev-right-click-emulation](https://github.com/PeterCxy/evdev-right-click-emulation). Build, install the binary (e.g. to `/usr/local/bin/evdev-rce`), and run it as a systemd service at boot (works on both X11 and Wayland).
|
||
|
||
---
|
||
|
||
## 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`, 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, 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** — Kernel cmdline rotates at boot; at login ~/.config/kanshi/config is written with the same transform (kanshi applies it; same as Control Center).
|
||
|
||
---
|
||
|
||
## 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_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 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`.
|