diff --git a/kernel/selftest.sh b/kernel/selftest.sh index ed4b336..9327686 100755 --- a/kernel/selftest.sh +++ b/kernel/selftest.sh @@ -62,13 +62,60 @@ done case "$ADDRESS" in ''|*[!0-9]*) die "address must be 0-30 (got '$ADDRESS')" ;; esac { [ "$ADDRESS" -ge 0 ] && [ "$ADDRESS" -le 30 ]; } || die "address out of range 0-30: $ADDRESS" +command -v modinfo >/dev/null || die "modinfo not found (install kmod)" + +# ---- locate the module matching the running kernel ---------------------- +# A released package ships one module per supported kernel under modules/. +# The build workflow names each file iec_listener_.ko, with +# ':' and '/' in the version replaced by '-' (1:6.12.93-1+rpt1 -> +# iec_listener_1-6.12.93-1+rpt1.ko); local builds produce a bare +# iec_listener.ko. The glob below ($MODULE*.ko) matches both. +# +# We select by vermagic, not by filename: the package name carries a Debian +# epoch/revision (1:6.12.93-1+rpt1) that `uname -r` (6.12.93+rpt-rpi-v8) does +# not, so the .ko whose vermagic matches the running kernel is the one to load. +RUNNING="$(uname -r)" + +# Where to look, de-duplicated ($(dirname "$0") is often "." when run locally). +SEARCH_DIRS=() +for d in "$(dirname "$0")/modules" "$(dirname "$0")" "./modules" "." "$HOME"; do + skip=0 + for s in "${SEARCH_DIRS[@]:-}"; do [ "$s" = "$d" ] && skip=1; done + [ "$skip" = 0 ] && SEARCH_DIRS+=("$d") +done + if [ -z "$KO" ]; then - for cand in "./${MODULE}.ko" "$HOME/${MODULE}.ko" "$(dirname "$0")/${MODULE}.ko"; do - [ -f "$cand" ] && { KO="$cand"; break; } + info "running kernel: $RUNNING" + for dir in "${SEARCH_DIRS[@]}"; do + [ -d "$dir" ] || continue + for cand in "$dir"/${MODULE}*.ko; do + [ -f "$cand" ] || continue + vm="$(modinfo -F vermagic "$cand" 2>/dev/null)" || continue + if [ "${vm%% *}" = "$RUNNING" ]; then + KO="$cand"; break 2 + fi + done done fi -[ -n "$KO" ] && [ -f "$KO" ] || die "module not found; pass the path, e.g. sudo $0 ~/${MODULE}.ko" -command -v modinfo >/dev/null || die "modinfo not found (install kmod)" + +if [ -z "$KO" ]; then + msg="no module matching the running kernel ($RUNNING) found. + Pass a path explicitly (sudo $0 path/to/${MODULE}.ko), or rebuild for + this kernel. Modules seen:" + any=0 + for dir in "${SEARCH_DIRS[@]}"; do + [ -d "$dir" ] || continue + for cand in "$dir"/${MODULE}*.ko; do + [ -f "$cand" ] || continue + vm="$(modinfo -F vermagic "$cand" 2>/dev/null)" + msg="$msg"$'\n'" $cand (built for ${vm%% *})" + any=1 + done + done + [ "$any" = 1 ] || msg="$msg"$'\n'" (none)" + die "$msg" +fi +[ -f "$KO" ] || die "module not found: $KO" info "module: $KO" info "address: $ADDRESS"