#!/usr/bin/env bash # build-linux-rpi.sh - build/install a newer linux-rpi from rpi-6.18.y set -euo pipefail if [[ ${EUID:-0} -ne 0 ]]; then echo "run as root (sudo) to install build deps and kernel packages" >&2 exit 1 fi BUILD_USER=${LESAVKA_KERNEL_BUILD_USER:-${SUDO_USER:-$(id -un)}} if [[ -z $BUILD_USER || $BUILD_USER == root ]]; then echo "missing non-root build user; set LESAVKA_KERNEL_BUILD_USER" >&2 exit 1 fi KERNEL_REPO=${LESAVKA_KERNEL_REPO:-https://github.com/raspberrypi/linux.git} KERNEL_BRANCH=${LESAVKA_KERNEL_BRANCH:-rpi-6.18.y} KERNEL_COMMIT=${LESAVKA_KERNEL_COMMIT:-} PKGBUILD_REPO=${LESAVKA_KERNEL_PKG_REPO:-https://github.com/archlinuxarm/PKGBUILDs.git} BUILD_ROOT=${LESAVKA_KERNEL_BUILD_ROOT:-/var/tmp/lesavka-linux-rpi} PKGREL=${LESAVKA_KERNEL_PKGREL:-2} JOBS=${LESAVKA_KERNEL_JOBS:-2} HEARTBEAT=/etc/lesavka/watchdog.touch if [[ -w $HEARTBEAT && -z ${LESAVKA_DISABLE_KEEPALIVE:-} ]]; then (while true; do touch "$HEARTBEAT"; sleep 600; done) & KEEPALIVE_PID=$! trap 'kill $KEEPALIVE_PID' EXIT fi if [[ -z $KERNEL_COMMIT ]]; then KERNEL_COMMIT=$(git ls-remote "$KERNEL_REPO" "refs/heads/$KERNEL_BRANCH" | awk '{print $1}') fi if [[ -z $KERNEL_COMMIT ]]; then echo "failed to resolve kernel commit for $KERNEL_BRANCH" >&2 exit 1 fi KERNEL_VERSION=$( curl -fsSL "https://raw.githubusercontent.com/raspberrypi/linux/$KERNEL_COMMIT/Makefile" | awk -F' = ' ' /^VERSION =/ {v=$2} /^PATCHLEVEL =/ {p=$2} /^SUBLEVEL =/ {s=$2} END { if (v && p && s) print v "." p "." s }' ) if [[ -z $KERNEL_VERSION ]]; then echo "failed to determine kernel version from $KERNEL_COMMIT" >&2 exit 1 fi TARGET_VERSION="${KERNEL_VERSION}-${PKGREL}" INSTALLED_VERSION=$(pacman -Qi linux-rpi 2>/dev/null | awk -F': ' '/Version/{print $2}') if [[ -n $INSTALLED_VERSION && $INSTALLED_VERSION == "$TARGET_VERSION"* ]]; then echo "linux-rpi already at $TARGET_VERSION" exit 0 fi echo "==> Building linux-rpi $KERNEL_VERSION ($KERNEL_COMMIT) pkgrel=$PKGREL" pacman -Sy --needed --noconfirm git bc kmod inetutils base-devel rm -rf "$BUILD_ROOT" mkdir -p "$BUILD_ROOT" chown "$BUILD_USER":"$BUILD_USER" "$BUILD_ROOT" sudo -u "$BUILD_USER" git clone --depth 1 "$PKGBUILD_REPO" "$BUILD_ROOT/PKGBUILDs" cp -a "$BUILD_ROOT/PKGBUILDs/core/linux-rpi" "$BUILD_ROOT/linux-rpi" chown -R "$BUILD_USER":"$BUILD_USER" "$BUILD_ROOT/linux-rpi" sudo -u "$BUILD_USER" bash -c " set -euo pipefail cd '$BUILD_ROOT/linux-rpi' sed -i 's/^pkgver=.*/pkgver=$KERNEL_VERSION/' PKGBUILD sed -i 's/^pkgrel=.*/pkgrel=$PKGREL/' PKGBUILD sed -i 's/^_commit=.*/_commit=$KERNEL_COMMIT/' PKGBUILD makepkg -g > /tmp/lesavka-kernel.sums " sudo -u "$BUILD_USER" BUILD_ROOT="$BUILD_ROOT" python - <<'PY' import re from pathlib import Path import os root = Path(os.environ["BUILD_ROOT"]) pkgbuild = root / "linux-rpi" / "PKGBUILD" sums = Path("/tmp/lesavka-kernel.sums").read_text().splitlines() text = pkgbuild.read_text() for line in sums: if not line.startswith("sha256sums"): continue key = line.split("=", 1)[0] text = re.sub(rf"^{re.escape(key)}=.*$", line, text, flags=re.M) pkgbuild.write_text(text) PY sudo -u "$BUILD_USER" bash -c " set -euo pipefail cd '$BUILD_ROOT/linux-rpi' MAKEFLAGS='-j$JOBS' makepkg -s --noconfirm " mapfile -t PKGS < <(ls "$BUILD_ROOT/linux-rpi"/*.pkg.tar.* 2>/dev/null) if [[ ${#PKGS[@]} -eq 0 ]]; then echo "no kernel packages built" >&2 exit 1 fi pacman -U --noconfirm "${PKGS[@]}" echo "✅ linux-rpi upgraded to $TARGET_VERSION (reboot required)"