Files
hermes-bot/host/check-pi-platform.sh
T
2026-10-04 14:49:43 -07:00

110 lines
4.5 KiB
Bash

#!/usr/bin/env bash
# check-pi-platform.sh: confirm, without the Pi, that Ubuntu 24.04's Raspberry Pi kernel ships the
# drivers and overlays the robot needs. It downloads the current linux-modules-*-raspi package for
# arm64 (about 50 MB) and inspects it. Nothing is installed; everything happens in a temp folder.
#
# Needs: curl, gzip, awk, ar (binutils), zstd, tar
# NixOS: nix-shell -p curl binutils zstd gnutar gawk --run ./check-pi-platform.sh
# Omarchy: sudo pacman -S --needed binutils zstd && ./check-pi-platform.sh
#
# Usage: ./check-pi-platform.sh [suite] (default suite: noble-updates)
# MIRROR=<url> overrides http://ports.ubuntu.com/ubuntu-ports
set -euo pipefail
SUITE="${1:-noble-updates}"
MIRROR="${MIRROR:-http://ports.ubuntu.com/ubuntu-ports}"
for tool in curl gzip awk ar zstd tar; do
command -v "$tool" >/dev/null || { echo "Missing tool: $tool (see the header of this script)" >&2; exit 2; }
done
work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT
cd "$work"
echo "==> Reading the arm64 package index for $SUITE"
curl -fsSL "$MIRROR/dists/$SUITE/main/binary-arm64/Packages.gz" | gzip -dc > Packages
# field <package> <Field>: the value of Field in that package's stanza (last stanza wins)
field() {
awk -v p="$1" -v f="$2" '
/^Package: / { inpkg = ($2 == p) }
inpkg && index($0, f ": ") == 1 { v = substr($0, length(f) + 3) }
END { if (v != "") print v }' Packages
}
meta_deps="$(field linux-image-raspi Depends)"
[[ -n "$meta_deps" ]] || { echo "linux-image-raspi not found in $SUITE" >&2; exit 1; }
abi="$(grep -oE 'linux-image-[0-9][^ ,(]*-raspi' <<<"$meta_deps" | head -1 | sed 's/^linux-image-//')"
modpkg="linux-modules-$abi"
debpath="$(field "$modpkg" Filename)"
[[ -n "$debpath" ]] || { echo "$modpkg not found in $SUITE" >&2; exit 1; }
echo "==> Current Pi kernel for Ubuntu 24.04: $abi"
echo "==> Downloading $modpkg"
curl -fsSL "$MIRROR/$debpath" -o modules.deb
member="$(ar t modules.deb | grep '^data\.tar' | head -1)"
case "$member" in
*.zst) decomp=(zstd -dc) ;;
*.xz) decomp=(xz -dc) ;;
*.gz) decomp=(gzip -dc) ;;
*.tar) decomp=(cat) ;;
*) echo "Unexpected package layout: $member" >&2; exit 1 ;;
esac
ar p modules.deb "$member" | "${decomp[@]}" | tar -t > files
ar p modules.deb "$member" | "${decomp[@]}" | tar -xO "./boot/config-$abi" > config 2>/dev/null || : > config
missing=0
# check <label> <module file name> <CONFIG_ key>
check() {
local label="$1" mod="$2" key="$3" state
if grep -qE "/${mod}\.ko(\.zst|\.xz|\.gz)?$" files; then
state="ok (module)"
elif grep -qx "${key}=y" config; then
state="ok (built in)"
else
state="MISSING"; missing=$((missing + 1))
fi
printf ' %-40s %s\n' "$label" "$state"
}
# overlay <name>
overlay() {
if grep -qE "/overlays/$1\.dtbo$" files; then
printf ' %-40s ok\n' "$1.dtbo"
else
printf ' %-40s MISSING\n' "$1.dtbo"; missing=$((missing + 1))
fi
}
echo
echo "Audio (BrainCraft HAT, WM8960 codec at I2C 0x1A)"
check "WM8960 codec driver" snd-soc-wm8960 CONFIG_SND_SOC_WM8960
check "Simple sound card" snd-soc-simple-card CONFIG_SND_SIMPLE_CARD
check "Pi I2S interface" snd-soc-bcm2835-i2s CONFIG_SND_BCM2835_SOC_I2S
overlay wm8960-soundcard
echo "Camera (Arducam UC-346, OV5647)"
check "OV5647 sensor driver" ov5647 CONFIG_VIDEO_OV5647
check "Pi camera receiver (Unicam)" bcm2835-unicam CONFIG_VIDEO_BCM2835_UNICAM
overlay ov5647
echo "Servos (hardware PWM on GPIO12/13)"
check "Pi PWM driver" pwm-bcm2835 CONFIG_PWM_BCM2835
overlay pwm-2chan
echo "Display (ST7789 on SPI)"
check "Pi SPI driver" spi-bcm2835 CONFIG_SPI_BCM2835
echo "USB link (gadget mode on the USB-C port)"
check "DWC2 USB controller" dwc2 CONFIG_USB_DWC2
check "Gadget framework (configfs)" libcomposite CONFIG_USB_LIBCOMPOSITE
check "NCM Ethernet function" usb_f_ncm CONFIG_USB_F_NCM
check "ECM Ethernet function (fallback)" usb_f_ecm CONFIG_USB_F_ECM
check "ACM serial function" usb_f_acm CONFIG_USB_F_ACM
overlay dwc2
echo
[[ -s config ]] || echo "Note: no kernel config in the package, so built-in drivers would show as MISSING."
if (( missing == 0 )); then
echo "Everything the robot needs is in Ubuntu's $abi kernel."
else
echo "$missing item(s) missing from $abi. Ubuntu 24.04 may not suit this robot as-is; see HANDOFF.md package 0a."
exit 1
fi