Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

native: wipe stale subsystem .o files on config change + verify drv syms

Smoking-gun diagnosis from G7 logs: canary check passed (CONFIG_PINCTRL_
JASPERLAKE=y made it into .config) yet the built kernel had zero JSL
pinctrl driver symbols, only gpiochip0 registered, MAX98360A amp bound
but never got its SD_MODE GPIO → silent speakers.

Cause: kbuild's incremental-build dependency tracker doesn't fully
rebuild when a `obj-\$(CONFIG_FOO) += bar.o` toggles from =n to =y IF
bar.o never existed in the prior persistent build tree. It sees the
config line change via include/generated/autoconf.h but the dead-code
elimination path stays elided. Plain `make clean` would fix it but
negates the Phase 1 speedup.

Two-layer fix:
1. Config-hash sentinel — hash the critical audio/GPIO/pinctrl config
lines each build. On change, wipe specifically
drivers/{pinctrl/intel,i2c/busses,mtd/spi-nor,mmc/host,spi,
net/wireless/realtek,gpio} + sound/soc/{intel,sof,codecs}
object files + force vmlinux relink. Untouched subsystems keep
their ccache wins.
2. Post-build symbol verification — `nm vmlinux | grep` for one
canonical symbol from each critical driver (jsl_pinctrl_acpi_match,
max98357a_sdmode_event, rt5682_i2c_probe, dw_i2c_dev_init). Fail
the build with a specific remediation message if any are missing.
This catches the "config says =y but driver isn't linked" class
of regression that silently shipped the last three builds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+57
+57
fedac/native/docker-build.sh
··· 828 828 fi 829 829 log " ✓ All critical audio/GPIO configs present" 830 830 831 + # Config-hash sentinel — if the audio/GPIO/pinctrl configs changed since 832 + # the last build in this persistent /kernel-build volume, kbuild's 833 + # dependency tracker misses object files gated by obj-$(CONFIG_X) += y.o 834 + # (it sees the .config line change but the .o target is wholly absent 835 + # from the previous vmlinux so nothing re-evaluates it). Symptom: canary 836 + # check passes because .config is correct, but the built vmlinux is missing 837 + # drivers/pinctrl/intel/pinctrl-jasperlake.o, drivers/i2c/busses/i2c-designware-*, 838 + # etc. entirely. Fix: compute a hash of the critical configs and wipe the 839 + # specific subsystem build dirs when it changes. Much faster than a full 840 + # `make clean` while still forcing re-link of anything that toggled. 841 + CONFIG_SENTINEL_FILE="$KBUILD_ROOT/.audio-gpio-config-hash" 842 + CONFIG_HASH=$(grep -E '^CONFIG_(PINCTRL_|GPIOLIB|GPIO_|I2C_DESIGNWARE|SND_SOC_|MMC_|SPI_INTEL|RTW|IKCONFIG)' .config 2>/dev/null | sort | sha256sum | cut -c1-16) 843 + PREV_HASH=$(cat "$CONFIG_SENTINEL_FILE" 2>/dev/null || echo "") 844 + if [ "$CONFIG_HASH" != "$PREV_HASH" ]; then 845 + log " Config hash changed ($PREV_HASH → $CONFIG_HASH), wiping critical build dirs" 846 + # Only nuke dirs that contain drivers whose toggle-on we just forced. 847 + # Everything else stays cached and re-uses ccache. 848 + for d in drivers/pinctrl/intel drivers/i2c/busses drivers/mtd/spi-nor \ 849 + drivers/mmc/host drivers/spi drivers/net/wireless/realtek \ 850 + drivers/gpio sound/soc/intel sound/soc/sof sound/soc/codecs; do 851 + rm -rf "$d"/*.o "$d"/.*.o.cmd "$d"/built-in.a "$d"/.built-in.a.cmd 2>/dev/null || true 852 + done 853 + # Force vmlinux relink by removing it. 854 + rm -f vmlinux .vmlinux.cmd arch/x86/boot/bzImage 855 + echo "$CONFIG_HASH" > "$CONFIG_SENTINEL_FILE" 856 + else 857 + log " Config hash unchanged ($CONFIG_HASH) — incremental build" 858 + fi 859 + 831 860 # With ccache, skip make clean — stale objects get cache misses anyway, 832 861 # and clean destroys the build tree that ccache relies on for hits. 833 862 # Without ccache, clean to avoid config mismatch errors. ··· 871 900 # variant — the kernel's EFI stub loads initramfs externally on every path. 872 901 cp arch/x86/boot/bzImage "$BUILD/vmlinuz-slim" 873 902 cp arch/x86/boot/bzImage "$OUT/vmlinuz-slim" 2>/dev/null || true 903 + 904 + # Post-build verification: confirm critical driver objects actually got 905 + # compiled. The .config saying =y isn't enough — kbuild's persistent 906 + # build state could skip re-compiling a driver whose toggle changed. 907 + # Symptom (seen on G7): canary passed at config-check time but the 908 + # running kernel had no jasperlake-pinctrl driver, no symbols, 909 + # no gpiochip for the SoC pins. Grep vmlinux's symbol table for a 910 + # canonical symbol from each critical driver. 911 + log " Verifying critical driver symbols linked into vmlinux..." 912 + MISSING_DRVS="" 913 + for probe in "jsl_pinctrl_acpi_match:pinctrl-jasperlake" \ 914 + "max98357a_sdmode_event:snd-soc-max98357a" \ 915 + "rt5682_i2c_probe:rt5682-i2c" \ 916 + "dw_i2c_dev_init:i2c-designware-core"; do 917 + sym="${probe%%:*}" 918 + drv="${probe##*:}" 919 + if ! nm vmlinux 2>/dev/null | grep -q " ${sym}\$"; then 920 + MISSING_DRVS="$MISSING_DRVS $drv(${sym})" 921 + fi 922 + done 923 + if [ -n "$MISSING_DRVS" ]; then 924 + err "BUILD SANITY: critical driver symbols missing from vmlinux:$MISSING_DRVS" 925 + err " This usually means the persistent /kernel-build volume has stale" 926 + err " object files and kbuild didn't rebuild them. Wipe the volume and" 927 + err " re-run: docker volume rm ac-os-kbuild (then re-trigger build)" 928 + exit 1 929 + fi 930 + log " ✓ All critical driver symbols present in vmlinux" 874 931 875 932 VMLINUZ_SIZE=$(stat -c%s "$BUILD/vmlinuz") 876 933 SHA=$(sha256sum "$BUILD/vmlinuz" | awk '{print $1}')