Compare commits
3 Commits
160f6bb799
...
f91b06da9d
| Author | SHA1 | Date | |
|---|---|---|---|
| f91b06da9d | |||
| 2aa5104812 | |||
| 6e5ec9b84f |
@ -51,23 +51,31 @@ jobs:
|
||||
if [ ! -e /proc/sys/fs/binfmt_misc/qemu-aarch64 ]; then
|
||||
docker run --privileged --rm tonistiigi/binfmt --install arm64
|
||||
fi
|
||||
# Per-version image tag. The matrix entries can run concurrently on a
|
||||
# single runner sharing one Docker daemon; a fixed tag (e.g. iec-kbuild)
|
||||
# is then a shared mutable name and the builds race — whichever `docker
|
||||
# build` finishes last wins the tag, so both `docker create` calls
|
||||
# resolve to the same image and every job emits the same vermagic.
|
||||
# A unique tag per kernel version isolates them.
|
||||
img="iec-kbuild:${KERNEL_VERSION//[:\/]/-}"
|
||||
# Builder image: toolchain + matching raspberrypi kernel headers.
|
||||
docker build --platform linux/arm64 \
|
||||
--build-arg DEBIAN_SUITE="$DEBIAN_SUITE" \
|
||||
--build-arg HEADERS_PKG="$HEADERS_PKG" \
|
||||
--build-arg KERNEL_VERSION="$KERNEL_VERSION" \
|
||||
-t iec-kbuild .
|
||||
-t "$img" .
|
||||
# Compile inside the container. We use `docker cp` instead of the bind
|
||||
# mount that build-in-docker.sh uses for local builds: under the runner's
|
||||
# docker-in-docker, /workspace is a volume the host daemon can't see, so
|
||||
# `-v "$PWD:/build"` mounts an empty dir and make finds no Makefile.
|
||||
cid=$(docker create --platform linux/arm64 --entrypoint sleep iec-kbuild infinity)
|
||||
cid=$(docker create --platform linux/arm64 --entrypoint sleep "$img" infinity)
|
||||
docker start "$cid"
|
||||
docker cp ./. "$cid:/build"
|
||||
docker exec "$cid" /usr/local/bin/docker-entrypoint.sh clean
|
||||
docker exec "$cid" /usr/local/bin/docker-entrypoint.sh
|
||||
docker cp "$cid:/build/iec_listener.ko" ./iec_listener.ko
|
||||
docker rm -f "$cid"
|
||||
docker rmi "$img" || true
|
||||
|
||||
- name: Stage build output (modules/iec_listener_<kernel_version>.ko)
|
||||
working-directory: kernel
|
||||
|
||||
@ -20,14 +20,35 @@ before connecting the real bus (see PLAN.md §10).
|
||||
### Running it
|
||||
|
||||
`selftest.sh` is non-persistent (nothing is installed into `/lib/modules`, no
|
||||
autoload): it checks vermagic, loads the module, runs the self-test, and always
|
||||
unloads it again.
|
||||
autoload): it detects the running kernel, picks the matching module, loads it,
|
||||
runs the self-test, and always unloads it again.
|
||||
|
||||
A released package ships several kernel builds side by side:
|
||||
|
||||
```
|
||||
comodore-iec-emu/
|
||||
├── selftest.sh
|
||||
└── modules/
|
||||
├── iec_listener_1-6.12.93-1+rpt1.ko # built for 6.12.x (bookworm)
|
||||
└── iec_listener_1-6.18.34-1+rpt1.ko # built for 6.18.x (trixie)
|
||||
```
|
||||
|
||||
You don't pick the file yourself: the script reads `uname -r`, then scans
|
||||
`modules/` (and a few fallback locations) and selects the `.ko` whose **vermagic**
|
||||
matches the running kernel. Matching is by vermagic rather than filename because
|
||||
the packaged name carries a Debian epoch/revision (`1:6.12.93-1+rpt1`) that
|
||||
`uname -r` (`6.12.93+rpt-rpi-v8`) does not.
|
||||
|
||||
```bash
|
||||
sudo ./selftest.sh # auto-finds ./ or ~/iec_listener.ko, address 4
|
||||
sudo ./selftest.sh ~/iec_listener.ko --address 5 # runs with ~/iec_listener.ko, address 5
|
||||
sudo ./selftest.sh # auto-selects the matching module, address 4
|
||||
sudo ./selftest.sh --address 5 # same, address 5
|
||||
sudo ./selftest.sh ~/iec_listener.ko --address 5 # force a specific module file
|
||||
```
|
||||
|
||||
If no module matches the running kernel, the script lists the modules it found
|
||||
(with the kernel each was built for) and exits — rebuild for the current kernel,
|
||||
or pass a path explicitly.
|
||||
|
||||
It exits non-zero unless the result is a full pass (`0x1F`), so it is usable in
|
||||
scripts/CI.
|
||||
|
||||
|
||||
@ -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_<kernel_version>.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"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user