review: iteration-1 fixes across CI, bridge, VM harness, and docs
CI/pipeline: - KERNEL_TARBALL passed as a YAML env literal '~' was never tilde-expanded and would have failed every hosted kernel-build dispatch; the path is now exported from the shell. Verified reproducible before the fix. - Every job gets timeout-minutes; boot smoke uses timeout -k so a wedged qemu is SIGKILLed instead of holding the job. - Tarball fetch + fail-closed sha256 verification deduplicated into build/fetch-kernel-tarball.sh (with curl retries), used by build-kernel.sh and both CI jobs. busybox fetch gains retries too. - ccache layer for kernel-build (cache keyed on defconfig+patches) recovers the incremental-compile speed the ephemeral-runner move cost. - build-kernel.sh now asserts every fragment option survived olddefconfig — merge_config -m pastes text and Kconfig silently drops unmet symbols. rs485-bridge: - pending-buffer cap (2x max RTU ADU) instead of unbounded growth; explicit accept-loop error handling with backoff instead of .flatten(); per-arm inline bounds instead of the string-keyed lookup whose default would have mis-bounded a future get-input; control-socket cleanup errors surfaced; flag-shaped values rejected in arg parsing; doc example uses a private mktemp dir. Test timing margins widened for contended runners (gap 25->120ms, 60x margin on the split-frame test). VM harness: - stage-1/stage-2 boot scripts share one validated slot parser and one by-name populator (qemu/rootfs/etc/warden-lib.sh) — the duplicated parser had already diverged on validation; userdata/oem mount failures now fail fast with a greppable sentinel; udhcpc fallback keys off the interface actually having an address; switch_root applet guarded. - boot-smoke delegates the qemu invocation to run.sh (machine shape lives in ONE place); run.sh port 0 disables a hostfwd. - mkimage: unknown partition names fail at build time; DISK_END is a max, not last-entry; --state keys validated as filenames. - portal-scenario: mock readiness is asserted (no silent fall-through), hostfwd port collisions retried, mount-failure sentinel fails fast. - ui-shot: fixed sleeps replaced with bounded screendump polling; the repaint assertion is real and documented as such. qmp.py loses its module-global and gains argv validation. Docs/scrub: bench-host paths and the site AP name removed from six more port docs and two evidence tables; path-bearing build artifacts (.elf, .map) untracked (the 154-byte firmware .bin is path-free and stays); ADR-0003 marked visibility-superseded by ADR-0007; stale section cross-reference fixed; flare-edge noted as private for outside readers; stale root-level review report removed per the new workspace rule. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018HUayid7W5w7jBdb9Rrj1K
This commit is contained in:
co-authored by
Claude Fable 5
parent
b667ff5b1e
commit
2756de0b46
+40
-19
@@ -14,7 +14,9 @@
|
||||
# JOBS parallel make jobs (default: nproc)
|
||||
# WARDEN_KCONFIG_FRAGMENT
|
||||
# optional kconfig fragment merged onto warden_defconfig
|
||||
# (qemu/configs/virt.fragment builds the QEMU -M virt variant)
|
||||
# (qemu/configs/virt.fragment builds the QEMU -M virt variant);
|
||||
# every fragment option is verified to have taken effect
|
||||
# WARDEN_CCACHE=1 compile through ccache (CI caches ~/.ccache)
|
||||
#
|
||||
# Requires: `python` (not python3) on PATH — the SDK quirk; the CI runner provides
|
||||
# a project-local venv. Builds are SERIAL on the shared SDK box — never run two.
|
||||
@@ -24,9 +26,8 @@ KVER=6.18.46
|
||||
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # build/
|
||||
REPO="$(cd "$HERE/.." && pwd)"
|
||||
PATCHES="$REPO/patches"
|
||||
SHA_FILE="$HERE/linux-$KVER.tar.xz.sha256"
|
||||
JOBS="${JOBS:-$(nproc)}"
|
||||
URL="https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-$KVER.tar.xz"
|
||||
# The tarball URL + sha256 pin live in fetch-kernel-tarball.sh (shared with CI).
|
||||
|
||||
# A caller-provided WORK (e.g. CI's ${{ github.workspace }}/kbuild-out, from which
|
||||
# artifacts are uploaded) is left intact; a scratch dir we mktemp'd here is our own
|
||||
@@ -47,21 +48,9 @@ command -v python >/dev/null || { echo "need 'python' (not python3) on PATH —
|
||||
# 1. obtain + verify the pristine tarball
|
||||
mkdir -p "$WORK"
|
||||
TB="${KERNEL_TARBALL:-$WORK/linux-$KVER.tar.xz}"
|
||||
if [ ! -f "$TB" ]; then
|
||||
log "downloading $URL"
|
||||
curl -fSL "$URL" -o "$TB"
|
||||
fi
|
||||
# Fail closed: a missing pin (e.g. forgotten on a KVER bump) or a KERNEL_TARBALL
|
||||
# pointed at an arbitrary file must refuse to build, never silently skip the check
|
||||
# — the pristine tarball is the ONLY external input and integrity is the whole point.
|
||||
[ -f "$SHA_FILE" ] || {
|
||||
echo "FATAL: no pinned sha256 for linux-$KVER (expected $SHA_FILE) — refusing to build from an unverified tarball" >&2
|
||||
exit 1
|
||||
}
|
||||
want="$(cat "$SHA_FILE")"
|
||||
got="$(sha256sum "$TB" | awk '{print $1}')"
|
||||
[ "$want" = "$got" ] || { echo "tarball sha256 mismatch: want $want got $got" >&2; exit 1; }
|
||||
log "tarball sha256 verified"
|
||||
# Fetch + fail-closed sha256 verification live in ONE place shared with CI
|
||||
# (a missing pin or a mismatch always refuses to build).
|
||||
bash "$HERE/fetch-kernel-tarball.sh" "$TB"
|
||||
|
||||
# 2. extract pristine
|
||||
SRC="$WORK/linux-$KVER"
|
||||
@@ -124,9 +113,41 @@ command -v "${CROSS_COMPILE}gcc" >/dev/null \
|
||||
|| { echo "cross toolchain ${CROSS_COMPILE}gcc not on PATH (set SDK_TC, or CROSS_COMPILE to one that is)" >&2; exit 1; }
|
||||
make -C "$SRC" ARCH=arm CROSS_COMPILE="$CROSS_COMPILE" olddefconfig >/dev/null
|
||||
|
||||
# Fragment took-effect assertion: merge_config -m only pastes text, and
|
||||
# olddefconfig silently resolves any symbol whose dependencies are unmet —
|
||||
# a fragment option could be dropped without a word. Verify every explicit
|
||||
# request in the fragment survived into the final .config; fail loud if not.
|
||||
if [ -n "${WARDEN_KCONFIG_FRAGMENT:-}" ]; then
|
||||
frag_fail=0
|
||||
while IFS= read -r line; do
|
||||
case "$line" in
|
||||
CONFIG_*=*)
|
||||
grep -qxF "$line" "$SRC/.config" || {
|
||||
echo "FATAL: fragment option '$line' did not take effect (unmet Kconfig dependency?)" >&2
|
||||
frag_fail=1
|
||||
} ;;
|
||||
"# CONFIG_"*" is not set")
|
||||
opt="${line#\# }"; opt="${opt% is not set}"
|
||||
grep -qE "^$opt=" "$SRC/.config" && {
|
||||
echo "FATAL: fragment disabled '$opt' but it is set in the final .config" >&2
|
||||
frag_fail=1
|
||||
} ;;
|
||||
esac
|
||||
done < "$FRAG"
|
||||
[ "$frag_fail" = 0 ] || exit 1
|
||||
log "fragment options verified in final .config"
|
||||
fi
|
||||
|
||||
# Optional ccache (CI: cache ~/.ccache across dispatches; harmless if unset).
|
||||
KCC="${CROSS_COMPILE}gcc"
|
||||
if [ "${WARDEN_CCACHE:-0}" = 1 ]; then
|
||||
command -v ccache >/dev/null || { echo "FATAL: WARDEN_CCACHE=1 but ccache not installed" >&2; exit 1; }
|
||||
KCC="ccache ${CROSS_COMPILE}gcc"
|
||||
fi
|
||||
|
||||
# 5. build zImage + the board dtb
|
||||
log "building zImage + rv1106-warden.dtb (-j$JOBS)"
|
||||
make -C "$SRC" ARCH=arm CROSS_COMPILE="$CROSS_COMPILE" -j"$JOBS" \
|
||||
make -C "$SRC" ARCH=arm CROSS_COMPILE="$CROSS_COMPILE" CC="$KCC" -j"$JOBS" \
|
||||
zImage rockchip/rv1106-warden.dtb
|
||||
|
||||
Z="$SRC/arch/arm/boot/zImage"
|
||||
|
||||
Reference in New Issue
Block a user