hi3516cv200, gk7205v200, gk7605v100: back under the squashfs cap - #2442
Conversation
PR Summary by QodoRestore image headroom and retry failed sensor detection
AI Description
Diagram
High-Level Assessment
Files changed (16)
|
Code Review by Qodo
1.
|
The 2026-09-18 master matrix (run 35375141337, at 49908b5) failed on three boards, each at 5124KB against the 5120KB squashfs cap -- over by exactly 4KB. All three were reproduced locally from a clean worktree at that commit before anything here was changed, and the cause is the same fleet-wide drift in the unpinned majestic and majestic-webui refs that #2404, #2410, #2421, #2433, #2437 and #2440 have each answered on other boards. #2437 landed one day ago and left these two Goke boards 8KB of headroom while saying in as many words that the drift would take them again; it did. hi3516cv200 shipped two Realtek drivers waiting on firmware the image does not carry. rtl8192cu asks for rtlwifi/rtl8192cufw*.bin, and rtl8xxxu -- with RTL8XXXU_UNTESTED off, so RTL8723AU only -- asks for rtlwifi/rtl8723aufw*.bin. The only Wi-Fi blobs this board installs are mediatek/mt7601u.bin and rtlwifi/rtl8188eufw.bin, so neither could finish probing, and nothing loads them either: /etc/wireless/usb, dispatched by S40network from the wlandev U-Boot variable, is the one entry point and names mt7601u and 8188eu. That was 350KB of .ko (rtl8xxxu 104KB, rtl8192cu 90KB, rtlwifi 85KB, rtl8192c-common 54KB, rtl_usb 15KB), and RTLWIFI_DEBUG=y is why rtlwifi.ko was as large as it was. Same argument as #2404 made for hi3519v101. R8188EU stays, and the line is drawn where the firmware is: rtl8188eufw.bin is what drivers/staging/rtl8188eu/hal/fw.c requests by name, and R8188EU is the only symbol on this board selecting WIRELESS_EXT and WEXT_PRIV, which the out-of-tree drivers a camera may add still need. This is #2410 in reverse -- there the same driver went, because that board had no wext consumer left. gk7205v200 and gk7605v100 are out of free levers: #2376 took their SCSI stack, #2421 stripped the modules they cannot load, #2437 built their crypto helpers in, and every module left is named by a script or dependency-loaded by one that is. So they take the cheaper half of the one lever #2420 found remaining, the same half #2440 gave gk7205v300. Only cfg80211 moves; mac80211 and mt7601u stay modules, because moving those too would trade "one commit from red on rootfs" for the same on uImage. The cost is worth stating: cfg80211 is now permanently resident, so every camera pays for the wireless core whether a dongle is ever plugged in or not. The load path survives being built in -- modules.builtin now lists kernel/net/wireless/cfg80211.ko, which busybox modprobe consults, and mac80211.ko's modules.dep line no longer names it. Measured locally, clean builds of both the before and the after -- an incremental rebuild keeps the old .ko in target/ and reports a nonsensical saving, which is the trap #2437 documented: hi3516cv200_lite rootfs 5124 -> 5012KB uImage 1656 -> 1657KB gk7205v200_lite rootfs 5124 -> 5044KB uImage 1821 -> 1876KB gk7605v100_lite rootfs 5124 -> 5044KB uImage 1799 -> 1855KB None of the three prints a headroom warning any more.
3cb475e to
a2b8843
Compare
The previous attempt at this put the recovery inside the branch reached when
SENSOR is empty, which on a real camera is the one branch that never runs.
/etc/init.d/rcS line 2 is
export SENSOR=$(fw_printenv -n sensor)
so by the time S70vendor calls load_<vendor> -i, an already-latched camera has
SENSOR=unknown in its environment. The loader takes
if [ -n "$SENSOR" ]; then
logger ... "SENSOR: ${SENSOR}"
logs the sentinel as a manually-set sensor, and the recovery below it is
unreachable. The fix was inert on exactly the cameras it was written for.
Clearing before that test, and blanking the shell variable as well as the
stored one, puts the camera back on the detection path.
Verified with the shipped block run under busybox ash, with fw_printenv /
fw_setenv backed by a file and -- this time -- SENSOR exported from that file
first, the way rcS does. The earlier harness set SENSOR= by hand, which is
precisely why it reported a fix that could not work:
A. latched camera, sensor now detectable
before: boot1 SENSOR=unknown detection_runs=0 env=[sensor=unknown]
after: boot1 SENSOR=sc2336 detection_runs=1 env=[sensor=sc2336]
B. fresh camera, undetectable then detectable
before: boot2 SENSOR=unknown detection_runs=1 env=[sensor=unknown]
after: boot2 SENSOR=sc2336 detection_runs=2 env=[sensor=sc2336]
C. working camera, sensor already stored
before: boot1 SENSOR=sc2336 detection_runs=0 env=[sensor=sc2336]
after: boot1 SENSOR=sc2336 detection_runs=0 env=[sensor=sc2336]
C is the no-regression case and is byte-identical either side.
Found by the Qodo review on #2442, which reviewed this branch's code against
that PR.
The previous attempt at this put the recovery inside the branch reached when
SENSOR is empty, which on a real camera is the one branch that never runs.
/etc/init.d/rcS line 2 is
export SENSOR=$(fw_printenv -n sensor)
so by the time S70vendor calls load_<vendor> -i, an already-latched camera has
SENSOR=unknown in its environment. The loader takes
if [ -n "$SENSOR" ]; then
logger ... "SENSOR: ${SENSOR}"
logs the sentinel as a manually-set sensor, and the recovery below it is
unreachable. The fix was inert on exactly the cameras it was written for.
Clearing before that test, and blanking the shell variable as well as the
stored one, puts the camera back on the detection path.
Verified with the shipped block run under busybox ash, with fw_printenv /
fw_setenv backed by a file and -- this time -- SENSOR exported from that file
first, the way rcS does. The earlier harness set SENSOR= by hand, which is
precisely why it reported a fix that could not work:
A. latched camera, sensor now detectable
before: boot1 SENSOR=unknown detection_runs=0 env=[sensor=unknown]
after: boot1 SENSOR=sc2336 detection_runs=1 env=[sensor=sc2336]
B. fresh camera, undetectable then detectable
before: boot2 SENSOR=unknown detection_runs=1 env=[sensor=unknown]
after: boot2 SENSOR=sc2336 detection_runs=2 env=[sensor=sc2336]
C. working camera, sensor already stored
before: boot1 SENSOR=sc2336 detection_runs=0 env=[sensor=sc2336]
after: boot1 SENSOR=sc2336 detection_runs=0 env=[sensor=sc2336]
C is the no-regression case and is byte-identical either side.
Found by the Qodo review on #2442, which reviewed this branch's code against
that PR.
Problem
Three boards produce no image on master. The 2026-09-18 matrix
(run 35375141337,
at 49908b5) failed on
hi3516cv200_lite,gk7205v200_liteandgk7605v100_lite— each at 5124KB against the 5120KB squashfs cap, over byexactly 4KB, so
repackfails and the board ships nothing.All three reproduce from a clean worktree at that commit with no changes, so
this is not a side effect of anything in flight. It is the same fleet-wide
drift in the unpinned
majestic/majestic-webuirefs that #2404, #2410,#2421, #2433, #2437 and #2440 each answered on other boards. #2437 merged
yesterday, left the two Goke boards 8KB of headroom, and said in as many
words that the drift would take them again. It did, in one day.
What this changes
hi3516cv200ships two Realtek drivers that wait on firmware the image doesnot carry:
request_firmware()forrtl8192cu(rtlwifi)rtlwifi/rtl8192cufw*.binrtl8xxxu(RTL8XXXU_UNTESTEDoff ⇒ RTL8723AU only)rtlwifi/rtl8723aufw*.binr8188eu(staging)rtlwifi/rtl8188eufw.binmt7601umediatek/mt7601u.binThe two with no firmware could never finish probing, and nothing loads them
either —
/etc/wireless/usb, dispatched byS40networkoff thewlandevU-Boot variable, is the single entry point and names
mt7601uand8188eu,never
rtl8192cu,rtlwifiorrtl8xxxu.mdev.confhas no module-autoloadrule. That is 350KB of
.koon a rootfs 4KB over its cap:Same argument #2404 made for
hi3519v101.R8188EUstays, and the line is drawn where the firmware is:rtlwifi/rtl8188eufw.binis whatdrivers/staging/rtl8188eu/hal/fw.crequestsby name, and
R8188EUis the only symbol on this board selectingWIRELESS_EXTandWEXT_PRIV, which out-of-tree drivers a camera may add stillneed. This is #2410 in reverse — there the same driver went, because that board
had no wext consumer left.
gk7205v200andgk7605v100are out of free levers: #2376 took their SCSIstack, #2421 stripped the modules they cannot load, #2437 built their crypto
helpers in, and every module left is named by a script or dependency-loaded by
one that is. So they take the cheaper half of the one lever #2420 found
remaining — the same half #2440 gave
gk7205v300. Onlycfg80211moves;mac80211andmt7601ustay modules, because moving those as well would trade"one commit from red on rootfs" for the same on uImage (1821 + 198 = 2019 of
2048KB). The cost is worth stating: cfg80211 is now permanently resident, so
every camera pays for the wireless core whether a dongle is ever plugged in or
not.
The load path survives being built in —
modules.builtinnow listskernel/net/wireless/cfg80211.ko, which busyboxmodprobeconsults, andmac80211.ko'smodules.depline no longer names it.Hardware tested on
Not run on a camera, and no output from one is offered below.
The lab has no
hi3516cv200and nogk7605v100. It does have thegk7205v200board this PR's Goke half targets, and it is the one board therewith
bootlimit/altbootcmd, serial and remote power recovery — but it isdown: neither address it has answered to (
gk7205v200-imx307->10.216.128.49,
openipc-gk7205v200-> 10.216.128.63) replies to ping, a sweepof the subnet finds no third address for it, no serial adapter is attached to
this workstation, and the PoE switch credentials needed to power-cycle it are
not available in this session. A
gk7205v300board is up, but this PR does nottouch its config, and flashing a board with no recovery path to produce
evidence for a size-only change is exactly what the wiki's flashing page warns
against.
So what follows is what can be verified without a camera, stated as that: the
boards build again, by how much, and that the image contents match the
intent — the two firmware-less drivers gone,
WIRELESS_EXT/WEXT_PRIValive,cfg80211moved intomodules.builtinwithmac80211.ko'smodules.deplineno longer naming it.
No hi3516cv200 camera — the lab has none. The
hi3518ev200board is thesame SoC family but builds from
hi3518ev200.generic.config, which this PRdoes not touch, so it would not be exercising the change and its output is not
offered as if it were. What is verified for that board is the part CI can
verify: it builds again, the two drivers are gone from the image, and
WIRELESS_EXT/WEXT_PRIVsurvive in the resolved.config.Evidence
Both numbers from clean builds (
make cleanfirst) at 49908b5 — anincremental rebuild keeps the old
.kointarget/and reports a nonsensicalsaving, the trap #2437 documented.
Before:
After:
None of the three prints a headroom warning any more.
CI reproduces those numbers to the KB — from this PR's own matrix
(run 35388844897),
all 11 selected boards green:
gk7205v200_ultimateis there because it sharesgk7205v200.generic.configand so pays the same 55KB of uImage; it has 172KB of kernel headroom left.
What is left on the built images, rather than what the config says:
CI selector, for the reviewer:
What this does not do
It buys 76–108KB, not a fix for the cause. The unpinned majestic refs took six
boards over cap in #2421, three in #2433, two in #2437 and two in #2440, and
they will take more.
hi3516cv200has one large lever left after this(
r8188eu, 435KB of.ko), and the Goke pair has only the expensive half ofthe wireless build-in, which their uImage headroom cannot pay for today.
Scope
general/package/all-patches/linux/— these are board kernel configs, which CLAUDE.md places in this repositorygeneral/overlay/or in a sharedload_<vendor>script hardcodes a value specific to my board — no file outsidebr-ext-chip-*/board/is touched*_SITEor*_VERSIONis touchedLD_PRELOAD, and no binaries that cannot be rebuilt from sourceALL_BOARDS