hi3518ev300: build the crypto modules into the kernel, off the rootfs - #2397
Conversation
hi3518ev300_lite went red in the 2026-09-10 nightly at 5128KB against its 5120KB squashfs cap. Nothing in this repository grew to do it: between the 09-09 and 09-10 runs majestic's master tarball gained 14,918 bytes and majestic-webui's dist gained 4,888, and both are unpinned moving refs, so every board's rootfs grew ~20KB with no pull request to point at. This board had 12KB of headroom and CI had printed the warning a day earlier. The slack that does exist is in the kernel partition -- 1864KB used of 2048KB -- and it cannot be lent to the rootfs. The 8MB map is compiled into U-Boot and saved in every deployed camera's environment (...,2048k(kernel),5120k(rootfs),-(rootfs_data)), so a squashfs over 5120k would run past the end of the rootfs MTD and into the owner's overlay. Code can move the other way, though. Building the 17 crypto symbols in rather than shipping them as modules takes 11 .ko out of /lib/modules for 12KB of kernel. The trade works because most of a small .ko is ELF symbol table, relocations and .modinfo, all of which disappear once the code is linked in -- 89,572 bytes of .ko become 12KB of uImage. before uImage 1864KB/2048KB rootfs.squashfs 5128KB/5120KB 8KB over after uImage 1876KB/2048KB rootfs.squashfs 5104KB/5120KB 16KB free Nothing is dropped. mt7601u.ko, r8188eu.ko, mac80211.ko and wireguard.ko all still ship, so both USB WiFi dongles behave exactly as before. busybox modprobe reads modules.builtin and answers "module ... is builtin" for a built-in name, and /etc/wireless/usb ignores modprobe's exit status, so the load path is unaffected. The config is shared with hi3518ev300_ultimate, whose 4096KB kernel cap absorbs the 12KB without coming close. One consequence worth knowing: the kernel and rootfs are a matched pair for this board from here on. A camera updated with `sysupgrade -r` alone would have the modules gone from the rootfs and not yet built into its kernel; the combined-image path writes both.
PR Summary by QodoBuild hi3518ev300 crypto modules into the kernel
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
Code Review by Qodo
1. Camera behavior lacks hardware proof
|
…nnot load Six boards were over or at their squashfs cap. All of them ship kernel modules that no code path on the image can load; this removes those, at no cost to the kernel partition and with nothing dropped that anything uses. gk7205v300_lite 5140 -> 5080KB/5120 (was 20KB over) gk7205v200_lite 5132 -> 5072KB/5120 (was 12KB over) gk7605v100_lite 5124 -> 5068KB/5120 (was 4KB over) gk7202v300_lite 5120 -> 5088KB/5120 (was 0KB free) hi3516ev300_lite 5124 -> 5060KB/5120 (was 4KB over) hi3516av300_neo 8208 -> 6688KB/8192 (was 16KB over) WHY THEY WENT OVER. Nothing in this repository grew to do it. Between the last green nightly (34771958692) and the red one (34874636710), every board carrying majestic-webui grew 12-44KB, and the only three at +0KB are exactly the three that ship neither majestic nor the webui. Both are unpinned moving refs by design. Full analysis, and the levers not spent here, in #2420. THE USB GADGET STACK HAS NO CONSUMER (goke x4, hi3516ev300). libcomposite, configfs, usb_f_acm/ecm/rndis/mass_storage, u_ether and u_serial exist on these images only for usb-dual-role -- selected by zero defconfigs and listed in ci-matrix.py's NOT_BUILT. There is no USB hotplug modprobe either: mdev.conf carries no $MODALIAS rule and S40network dispatches only on the `wlandev` U-Boot variable, so a module is loadable if and only if a script names it. Nothing names these. br_netfilter and i2c-tiny-usb go too -- no consumer anywhere in the tree. USB_GADGET itself stays =y. USB_DWC3_DUAL_ROLE depends on it, so turning the subsystem off would drop the controller out of dual-role and take USB host -- and the Wi-Fi dongle -- with it. Only the functions go. Not touched, having checked: usbnet, cdc_ether, mii, usb_wwan and usb-serial-simple are dependency-loaded by option/usbserial/rndis_host, which /etc/wireless/modem does modprobe; every crypto .ko is loaded by the kernel crypto API's own request_module(), which is why #2397 built those in rather than deleting them; tun is live via vtund-openipc/files/tunnel:24. THE cv500 NEO SHIPPED EVERY VENDOR MODULE TWICE. The neo variants build the 7.x upstream-patches kernel, where buildroot's kernel-module install lands the .ko in updates/ rather than the extra/ that hisilicon-opensdk's finalize hook clears, and INSTALL_TARGET_CMDS then copies the same open_*.ko set into hisilicon/. kmod searches "updates" first, so that is the copy modprobe resolves and depmod indexes; hisilicon/ is unreachable. On hi3516av300_neo that is 45 modules and 5.4MB -- 1520KB of squashfs. Verified against the nightly's own published image: the hisilicon/ names are a pure subset of updates/, modules.dep names updates/ 156 times and hisilicon/ never, and the two copies of a module are the same object differing only in that updates/ is stripped. Scoped to cv500+neo deliberately, because the same duplication has the opposite answer next door: hi3516cv300_neo renames its modules to hi3516cv300_*/hi_* in hisilicon/, names that exist nowhere in updates/ and that its load_hisilicon insmods by filename. The 4.9 boards have no updates/ directory at all. The remaining neo boards are tracked in #2420. usb-dual-role NOW BRINGS ITS OWN KERNEL SYMBOLS, through the same LINUX_CONFIG_FIXUPS mechanism linux-patcher uses, so disabling them per board cannot strand it. The audit behind that is worth recording: usb-mode modprobes exactly configfs, libcomposite and usb_f_uvc -- it never composes ACM, ECM, RNDIS or mass_storage, which are precisely the four functions these boards were shipping -- while USB_CONFIGFS_F_UVC, the one function it does load, was absent from those configs entirely. The previous state could not have worked. Verified by selecting the package on gk7205v300_lite and rebuilding: USB_GADGET, CONFIGFS_FS, USB_CONFIGFS and USB_LIBCOMPOSITE come back. F_UVC does not, because it also needs VIDEO_V4L2 and VIDEO_DEV; the request stays in the fixup and the limit is written into both the .mk and the Config.in help. MEASURED, full clean builds (make clean, so no stale per-package module trees), before and after taken from the same build: gk7205v300_lite 5,263,360 -> 5,201,920 B uImage [1810KB/2048KB] unchanged hi3516ev300_lite [5124KB] -> [5056KB] uImage [2005KB/2048KB] unchanged No kernel cost anywhere, which matters for hi3516ev300 -- it has the second-tightest kernel partition in the tree and could not have paid for a build-in trade. Verified in the built rootfs: the removed .ko are gone and mac80211, cfg80211, mt7601u, wireguard, tun, option, usbserial, rndis_host, usbnet and mii all still ship, with modules.dep still resolving mt7601u -> mac80211 -> cfg80211. SCSI is deliberately left alone on hi3516ev300; #2410 dropped it from hi3518ev300 after establishing that board had no transport, and scsi_mod/sd_mod here need that determination separately. NOT TESTED ON A CAMERA -- I have none of these boards. Someone with a goke camera should confirm an MT7601U dongle still associates and USB host still enumerates; someone with an hi3516av300 neo should confirm it still boots and streams. hi3516av300_neo was not built locally either (it needs the 7.x kernel tree); its evidence is the published image above, and CI builds it. Refs #2420
Problem
hi3518ev300_litehas been red since the 2026-09-10 nightly (run 34508971947):It is the only board of 99 that fails, and nothing in this repository grew to
do it. Diffing every downloaded tarball between the last green nightly
(34383640663, 09-09) and the red one, exactly two inputs changed size:
majestic.hi3516ev200.lite.master.tar.bz2majestic-webui-dist.tar.gzBoth are unpinned moving refs —
majestic.mkfetches…master.tar.bz2,majestic-webui.mkpinsVERSION = dist— so an upstream publish lands in thenext nightly with no pull request here to point at. The growth is uniform
across boards, confirmed by the headroom annotations:
hi3518ev300_litewent12KB free → 8KB over, and
hi3519v101_litewent 28KB free → 8KB free. Bothexactly −20KB. The Sigmastar
uImageheadroom barely moved (25→24KB), so thekernel did not change.
CI printed the warning a day early, exactly as
CHECK_SIZE's 32KB band ismeant to:
Why this board. It carries a USB-WiFi stack its
hi3516ev300_litesiblingdoes not —
wpa_supplicant,wireless-tools,json-c, andlinux-firmware-openipcwithMEDIATEK_MT7601UandRTL_8188EU.Why not simply rebalance the partitions. The kernel partition has 184KB
idle (1864KB of 2048KB), but it cannot be lent to the rootfs. The 8MB map is
compiled into U-Boot and saved in every deployed camera's environment:
rootfsstarts at 0x250000 and is immediately followed byrootfs_data, theowner's overlay. A squashfs over 5120k would run past the end of the rootfs MTD
and into it on every camera still on the old map. Code can move the other way,
though, and that is what this does.
Hardware tested on
Not run on a camera. There is no hi3518ev300 within reach — the change is
verified by local build only, and I have not ticked anything I did not observe.
Someone with the board should confirm it boots, streams, and still brings up an
MT7601U or RTL8188EU dongle before this is trusted in the field.
The evidence that does apply is below: two full local builds of
hi3518ev300_litefrom this tree, the second differing only by this diff. Thebaseline reproduces CI's numbers exactly (1864KB / 5128KB), which is what makes
the after-figures meaningful.
Evidence
Before:
After:
The repack now completes and produces
openipc.hi3518ev300-nor-lite.tgz(7,129,032 B).
What moved. 11
.kototalling 89,572 bytes leave/lib/modules; thekernel grows 12KB. The trade works because most of a small
.kois ELF symboltable, relocations and
.modinfo, all of which disappear once the code islinked in:
After the rebuild: 0 crypto
.kounder/lib/modules, 32 crypto entries inmodules.builtin.Nothing is dropped.
mt7601u.ko,r8188eu.ko,mac80211.koandwireguard.koall still ship, so both USB WiFi dongles behave as before. Theload path is unaffected: busybox
modprobereadsmodules.builtin(
modutils/modprobe.c:631) and answersmodule ... is builtinrather thannot found in modules.dep, andgeneral/overlay/etc/wireless/usbdoesmodprobe mt7601u; exit 0, ignoring the exit status.Shared config.
hi3518ev300.generic.configis used byhi3518ev300_liteandhi3518ev300_ultimate. The ultimate's kernel cap is4096KB, so it absorbs the 12KB without coming close.
Selector and self-tests, run from the repo root:
Known limitations
this buys one bump, not a year. The durable fix is upstream size discipline
or a pin; this stops the bleeding without dropping a feature.
camera updated with
sysupgrade -ralone would have the modules gone fromthe rootfs and not yet built into its kernel, and would lose WiFi until it
also takes the kernel. The combined-image path writes both.
hi3519v101_liteis the next domino, now at 8KB free of 5120KB. It isuntouched here.
Scope
general/package/all-patches/linux/(those go to OpenIPC/linux)general/overlay/or in a sharedload_<vendor>script hardcodes a value specific to my boardLD_PRELOAD, and no binaries that cannot be rebuilt from source