From 2aa51048123d4e61c30560f96ebf92646b1fe927 Mon Sep 17 00:00:00 2001 From: Christian Werner Date: Sat, 20 Jun 2026 04:53:40 +0200 Subject: [PATCH] feat(kernel): Improve selftest.sh module discovery and error handling Enhance module selection process by validating vermagic against the running kernel. Add detailed error messages with suggestions for manual path overrides or rebuilding for the current kernel. Ensure robust fallback behavior and improve user guidance. --- kernel/selftest.sh | 55 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) 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"