Eliminate the rpi-eeprom configuration steps from the first-boot script, simplifying the installation process. Update the documentation to clarify that the EEPROM boot order is now set via the dashboard or manually, rather than during first boot. Adjust package installation logs to reflect the removal of rpi-eeprom and ensure clarity in the installation process. Enhance overall documentation to guide users on the new EEPROM update methods.
212 lines
10 KiB
Bash
212 lines
10 KiB
Bash
#!/bin/bash
|
|
# First-boot: packages, Chromium kiosk, rpd-labwc + touch, reTerminal DM drivers.
|
|
# Run by cloud-init (user-data-remote-gnss.example). Run as root.
|
|
|
|
set -e
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
|
|
# --- Constants ---
|
|
# All first-boot assets live in portal-files/first-boot/ on the file server.
|
|
FILE_SERVER="http://10.130.60.141:5000/files/first-boot"
|
|
HOSTNAME="guard"
|
|
PI_USER="pi"
|
|
PI_HOME="/home/$PI_USER"
|
|
AUTOSTART="$PI_HOME/.config/autostart"
|
|
LOGFILE="/var/log/first-boot.log"
|
|
PLYMOUTH_DIR="/usr/share/plymouth/themes/custom"
|
|
WALLPAPER_PATH="/usr/share/rpd-wallpaper/splash.png"
|
|
|
|
# --- Logging ---
|
|
log() { echo "[$(date -Iseconds)] $*"; }
|
|
exec > >(tee -a "$LOGFILE") 2>&1
|
|
log "=== first-boot.sh started ==="
|
|
log "FILE_SERVER=$FILE_SERVER PI_USER=$PI_USER LOGFILE=$LOGFILE"
|
|
|
|
# --- 0. Hostname and /etc/hosts (avoids "unable to resolve host" with sudo) ---
|
|
log "--- Hostname: $HOSTNAME ---"
|
|
echo "$HOSTNAME" > /etc/hostname
|
|
hostnamectl set-hostname "$HOSTNAME" 2>/dev/null || true
|
|
# Ensure hostname resolves so sudo and other tools don't warn
|
|
if ! grep -q "127.0.1.1[[:space:]]*$HOSTNAME" /etc/hosts 2>/dev/null; then
|
|
sed -i "/127.0.1.1[[:space:]].*$/d" /etc/hosts
|
|
echo "127.0.1.1 $HOSTNAME" >> /etc/hosts
|
|
fi
|
|
log "Hostname set to $HOSTNAME; /etc/hosts updated"
|
|
|
|
# --- Helpers ---
|
|
# Download script + .desktop from FILE_SERVER and install as one-shot autostart (runs once at pi's first login, then deletes itself).
|
|
install_oneshot() {
|
|
local name="$1"
|
|
log "--- Installing one-shot: $name ---"
|
|
if curl -fsSL "${FILE_SERVER}/${name}.sh" -o "$PI_HOME/${name}.sh"; then
|
|
log "Downloaded ${name}.sh to $PI_HOME/${name}.sh"
|
|
else
|
|
log "WARNING: Could not download ${name}.sh"; return 1
|
|
fi
|
|
if curl -fsSL "${FILE_SERVER}/${name}.desktop" -o "$AUTOSTART/${name}.desktop"; then
|
|
log "Downloaded ${name}.desktop to $AUTOSTART/${name}.desktop"
|
|
else
|
|
log "WARNING: Could not download ${name}.desktop"; return 1
|
|
fi
|
|
chmod 755 "$PI_HOME/${name}.sh" && chmod 644 "$AUTOSTART/${name}.desktop"
|
|
chown "$PI_USER:$PI_USER" "$PI_HOME/${name}.sh" "$AUTOSTART/${name}.desktop"
|
|
log "One-shot $name installed (will run at first login and then remove itself)"
|
|
}
|
|
|
|
# --- 1. Packages ---
|
|
log "--- Installing packages ---"
|
|
log "Running apt-get update ..."
|
|
apt-get update -qq
|
|
log "Installing: git chromium wmctrl openssh-server swaybg wlr-randr maliit-keyboard xinput-calibrator"
|
|
apt-get install -y -qq git chromium wmctrl openssh-server \
|
|
swaybg wlr-randr maliit-keyboard xinput-calibrator
|
|
log "Packages installed successfully"
|
|
|
|
# --- 2. Dirs and kiosk files from file server ---
|
|
log "--- Kiosk files ---"
|
|
log "Creating $AUTOSTART"
|
|
mkdir -p "$AUTOSTART"
|
|
log "Downloading start-chromium.sh from ${FILE_SERVER}/start-chromium.sh"
|
|
curl -fsSL "${FILE_SERVER}/start-chromium.sh" -o "$PI_HOME/start-chromium.sh"
|
|
log "Downloading chromium-kiosk.desktop from ${FILE_SERVER}/chromium-kiosk.desktop"
|
|
curl -fsSL "${FILE_SERVER}/chromium-kiosk.desktop" -o "$AUTOSTART/chromium-kiosk.desktop"
|
|
chmod 755 "$PI_HOME/start-chromium.sh" && chmod 644 "$AUTOSTART/chromium-kiosk.desktop"
|
|
chown -R "$PI_USER:$PI_USER" "$PI_HOME/start-chromium.sh" "$AUTOSTART/chromium-kiosk.desktop"
|
|
log "Kiosk files installed under $PI_HOME and $AUTOSTART"
|
|
|
|
# --- 3. Boot splash and wallpaper (splash.png + Plymouth theme from file server) ---
|
|
log "--- Boot splash and wallpaper ---"
|
|
log "Creating $PLYMOUTH_DIR and /usr/share/rpd-wallpaper"
|
|
mkdir -p "$PLYMOUTH_DIR" /usr/share/rpd-wallpaper
|
|
if curl -fsSL "${FILE_SERVER}/splash.png" -o "$PLYMOUTH_DIR/splash.png"; then
|
|
log "Downloaded splash.png; copying to $WALLPAPER_PATH"
|
|
cp "$PLYMOUTH_DIR/splash.png" "$WALLPAPER_PATH"
|
|
chmod 644 "$PLYMOUTH_DIR/splash.png" "$WALLPAPER_PATH"
|
|
if curl -fsSL "${FILE_SERVER}/custom.plymouth" -o "$PLYMOUTH_DIR/custom.plymouth" \
|
|
&& curl -fsSL "${FILE_SERVER}/custom.script" -o "$PLYMOUTH_DIR/custom.script"; then
|
|
chmod 644 "$PLYMOUTH_DIR/custom.plymouth" "$PLYMOUTH_DIR/custom.script"
|
|
log "Plymouth theme files (custom.plymouth, custom.script) installed"
|
|
else
|
|
log "WARNING: Could not download custom.plymouth/custom.script; boot splash theme may be incomplete"
|
|
fi
|
|
grep -q '^Theme=custom' /etc/plymouth/plymouthd.conf 2>/dev/null || printf '%s\n' '[Daemon]' 'Theme=custom' >> /etc/plymouth/plymouthd.conf
|
|
log "Running update-initramfs (may take a moment) ..."
|
|
update-initramfs -u -k all 2>/dev/null || true
|
|
mkdir -p /etc/lightdm/lightdm.conf.d
|
|
curl -fsSL "${FILE_SERVER}/99-wallpaper.conf" -o /etc/lightdm/lightdm.conf.d/99-wallpaper.conf 2>/dev/null || log "WARNING: Could not download 99-wallpaper.conf"
|
|
# Set desktop wallpaper once via pcmanfm config (rpd-labwc uses pcmanfm-pi; profile LXDE-pi or default)
|
|
for PROFILE in LXDE-pi default; do
|
|
PCMANFM_DESKTOP="$PI_HOME/.config/pcmanfm/$PROFILE/desktop-items-0.conf"
|
|
mkdir -p "$(dirname "$PCMANFM_DESKTOP")"
|
|
if [[ ! -f "$PCMANFM_DESKTOP" ]]; then
|
|
printf '%s\n' '[*]' "wallpaper=$WALLPAPER_PATH" 'wallpaper_mode=crop' 'wallpaper_common=1' > "$PCMANFM_DESKTOP"
|
|
else
|
|
grep -q '^wallpaper=' "$PCMANFM_DESKTOP" && sed -i "s|^wallpaper=.*|wallpaper=$WALLPAPER_PATH|" "$PCMANFM_DESKTOP" || echo "wallpaper=$WALLPAPER_PATH" >> "$PCMANFM_DESKTOP"
|
|
grep -q '^wallpaper_mode=' "$PCMANFM_DESKTOP" && sed -i 's/^wallpaper_mode=.*/wallpaper_mode=crop/' "$PCMANFM_DESKTOP" || echo 'wallpaper_mode=crop' >> "$PCMANFM_DESKTOP"
|
|
fi
|
|
chown -R "$PI_USER:$PI_USER" "$(dirname "$PCMANFM_DESKTOP")"
|
|
done
|
|
log "Set desktop wallpaper via pcmanfm config (LXDE-pi and default)"
|
|
log "Splash and wallpaper set from file server"
|
|
else
|
|
log "WARNING: Could not download splash.png"
|
|
fi
|
|
|
|
# --- 4. LightDM: rpd-labwc session + configs from file server ---
|
|
log "--- LightDM session (rpd-labwc) ---"
|
|
mkdir -p /etc/lightdm/lightdm.conf.d
|
|
if curl -fsSL "${FILE_SERVER}/99-default-session.conf" -o /etc/lightdm/lightdm.conf.d/99-default-session.conf 2>/dev/null; then
|
|
log "99-default-session.conf installed"
|
|
else
|
|
log "WARNING: Could not download 99-default-session.conf"
|
|
fi
|
|
# Raspberry Pi OS may apply main lightdm.conf after .conf.d; force session in main config too
|
|
if [[ -f /etc/lightdm/lightdm.conf ]]; then
|
|
sed -i 's/^user-session=.*/user-session=rpd-labwc/' /etc/lightdm/lightdm.conf
|
|
sed -i 's/^autologin-session=.*/autologin-session=rpd-labwc/' /etc/lightdm/lightdm.conf
|
|
log "Patched /etc/lightdm/lightdm.conf to use rpd-labwc"
|
|
fi
|
|
|
|
# --- 5. Maliit on-screen keyboard (from file server) ---
|
|
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) ---
|
|
log "--- reTerminal DM drivers ---"
|
|
REPO_DIR="/tmp/seeed-linux-dtoverlays"
|
|
log "Cloning seeed-linux-dtoverlays to $REPO_DIR ..."
|
|
git clone --depth 1 https://github.com/Seeed-Studio/seeed-linux-dtoverlays "$REPO_DIR"
|
|
# Script must run from repo root (it uses pwd for MOD_PATH). On bookworm+ --compat-kernel is not supported.
|
|
log "Running reTerminal.sh --device reTerminal-DM from $REPO_DIR ..."
|
|
if ( cd "$REPO_DIR" && "$REPO_DIR/scripts/reTerminal.sh" --device reTerminal-DM ); then
|
|
log "reTerminal DM drivers installed (reboot will apply)"
|
|
else
|
|
log "WARNING: reTerminal.sh failed (see log above). Display/touch may still work; you can retry later with: cd $REPO_DIR && sudo ./scripts/reTerminal.sh --device reTerminal-DM"
|
|
fi
|
|
log "Removing $REPO_DIR"
|
|
rm -rf "$REPO_DIR"
|
|
|
|
# --- 6b. Re-apply splash and display (Seeed script sets disable_splash=1 and can duplicate Plymouth theme) ---
|
|
log "--- Re-applying boot splash and Plymouth theme ---"
|
|
CFG_PATH="/boot/firmware/config.txt"
|
|
[[ -f /boot/firmware/config.txt ]] || CFG_PATH="/boot/config.txt"
|
|
if [[ -f "$CFG_PATH" ]]; then
|
|
if grep -q '^disable_splash=1' "$CFG_PATH"; then
|
|
sed -i 's/^disable_splash=1$/disable_splash=0/' "$CFG_PATH"
|
|
log "Set disable_splash=0 so Plymouth splash is shown"
|
|
fi
|
|
fi
|
|
# Ensure Plymouth uses our custom theme only (single [Daemon], Theme=custom)
|
|
if [[ -f /etc/plymouth/plymouthd.conf ]]; then
|
|
sed -i '/^Theme=/d' /etc/plymouth/plymouthd.conf
|
|
sed -i '/^\[Daemon\]$/d' /etc/plymouth/plymouthd.conf
|
|
grep -q '^\[Daemon\]' /etc/plymouth/plymouthd.conf || echo '[Daemon]' >> /etc/plymouth/plymouthd.conf
|
|
echo 'Theme=custom' >> /etc/plymouth/plymouthd.conf
|
|
log "Plymouth theme set to custom only"
|
|
fi
|
|
log "Running update-initramfs to apply Plymouth theme ..."
|
|
update-initramfs -u -k all 2>/dev/null || true
|
|
|
|
# --- 6b2. Kernel cmdline: swiotlb + DSI rotation (KMS, persistent across reboots) ---
|
|
CMDLINE_PATH="/boot/firmware/cmdline.txt"
|
|
[[ -f "$CMDLINE_PATH" ]] || CMDLINE_PATH="/boot/cmdline.txt"
|
|
if [[ -f "$CMDLINE_PATH" ]]; then
|
|
if ! grep -q 'swiotlb=' "$CMDLINE_PATH"; then
|
|
sed -i 's/rootwait/rootwait swiotlb=65536/' "$CMDLINE_PATH"
|
|
log "Added swiotlb=65536 to kernel cmdline (vc4-drm / DSI)"
|
|
fi
|
|
# Persistent rotation for DSI-1 (KMS): append at end of single line. 90 = 90° clockwise.
|
|
if ! grep -q 'video=DSI-1:rotate=' "$CMDLINE_PATH"; then
|
|
sed -i 's/$/ video=DSI-1:rotate=90/' "$CMDLINE_PATH"
|
|
log "Added video=DSI-1:rotate=90 to kernel cmdline (DSI rotation)"
|
|
fi
|
|
fi
|
|
|
|
# --- 7. One-shots (wallpaper already set in pcmanfm config above; rotation is via cmdline.txt) ---
|
|
log "--- One-shot scripts (if any) ---"
|
|
# Rotation is set persistently in cmdline.txt (video=DSI-1:rotate=90), not via one-shot script.
|
|
log "Rotation is set via kernel cmdline (video=DSI-1:rotate=90)"
|
|
|
|
# --- 8. Allow pi to append to first-boot.log (for one-shot scripts) ---
|
|
chmod 666 "$LOGFILE"
|
|
log "Log file $LOGFILE is now appendable by user $PI_USER for one-shot scripts"
|
|
|
|
# --- 9. Reboot ---
|
|
log "=== first-boot.sh finished, rebooting ==="
|
|
reboot
|