`addgroup` lives in `adduser`, which Debian forky no longer pulls
into a minimal rootfs by default. `family_tweaks` then dies with
`bash: line 1: addgroup: command not found` (exit 127) on every
forky-armhf rockchip build.
`groupadd` is in `passwd` (Essential, every Linux), and works
identically for our use here. The only behavioural difference —
`groupadd` returns 9 if the group already exists where `addgroup`
returns 0 — is gated by the existing `getent group … ||` guard in
rockchip.conf, and added to rockchip-rv1106.conf to keep
re-runnability.
Repro: armbian/os tinkerboard-current forky-armhf, log
https://paste.armbian.com/iyasuwenum
`imx8m.conf` defined a bare `pre_config_uboot_target()`. The framework
treats a bare hook as the full implementation and drops any
`pre_config_uboot_target__<purpose>` companions, so #9407's
auto-enabled `uboot-binman-fix-pkg-resources` extension was never
firing on i.MX 8M boards — `tools/binman/control.py`'s
`import pkg_resources` stayed unpatched, and `make flash.bin` died
with `ModuleNotFoundError` on Python 3.12 / setuptools >= 82.
Rename to `pre_config_uboot_target__imx8m_firmware()`. Body unchanged.
Both hooks now register and run; order between them doesn't matter
(NXP firmware fetch vs. Python source rewrite are independent).
Repro: armbian/os run 25262303737, job uboot-mba8mpxl-ras314-current.
Five board configs were inheriting their architecture either implicitly
(via BOARDFAMILY → kernel-config selection) or by sourcing another
board's .csc and never overriding it. Declare ARCH explicitly so that
arch-aware tooling (e.g. the build matrix filter that picks which
boards a release/arch target should fan out to) can match them by a
direct field read instead of having to re-evaluate the
BOARDFAMILY-to-arch chain.
Boards touched:
aml-t95z-plus.tvb BOARDFAMILY=meson-gxl → ARCH=arm64
ayn-odin2mini.csc (sources ayn-odin2.csc) → ARCH=arm64
ayn-odin2portal.csc (sources ayn-odin2.csc) → ARCH=arm64
ayn-thor.csc (sources ayn-odin2.csc) → ARCH=arm64
gateway-dk.conf BOARDFAMILY=ls1046a → ARCH=arm64
No build behaviour change for these boards: the resolved ARCH was
already arm64 via inheritance, the declaration just makes it
addressable at config-load time without sourcing the kernel config
chain.
Also clean up a stray apostrophe in aml-t95z-plus.tvb's BOARDFAMILY
comment ("s912's" → "s912s").
`Validate changed board configs` (PR #9747 CI run 25258999953) failed
on the three Ayn-Odin2 derivative boards with:
ERROR: config/boards/ayn-odin2mini.csc: BOARDFAMILY: required, ...
ERROR: config/boards/ayn-odin2mini.csc: KERNEL_TARGET: required, ...
(same pair on ayn-odin2portal.csc and ayn-thor.csc)
The validator's header explicitly says it does NOT source the file
("boards have side-effecty function bodies"), and the regex
`parse_assignments` only sees top-level `KEY=value` lines. Boards
that consist of one `source "${SRC}/config/boards/<parent>.csc"` line
plus a handful of overrides (BOARD_NAME, BOARD_VENDOR, BOARD_MAINTAINER,
ARCH) inherit BOARDFAMILY / KERNEL_TARGET / KERNEL_TEST_TARGET from
the parent, so the validator saw them as missing and erred out.
The errors are pre-existing — they would fire on any future change
to those .csc files. PR #9747 just made them visible by being the
first PR to touch an inheriting board since the validator landed.
Add `collect_inherited_assignments`: when a top-level `source` line
points at another file under config/boards/ (matched by a regex
anchored to start-of-line so `source` calls inside function bodies —
which are always indented — aren't followed), parse that file's
top-level assignments and lay them behind the child's own. Child's
explicit values still win via dict.setdefault.
Recursion is guarded by a visited set keyed on resolved paths, so
a self-source or a parent-source-child cycle terminates instead of
looping. Missing source targets are silently skipped — the main
required-field checks will still flag any field that ends up unset
after the merge, so a typo'd source path doesn't mask a real gap.
Verified against the five PR-changed files: 6 errors → 0 errors,
4 warnings → 1 warning (the unmaintained-board warning on
aml-t95z-plus.tvb, which is unrelated to inheritance and was
already there). Self-contained boards (musepipro.conf etc.)
produce identical output to before this change.
Rename two .patch files to .patch.NEED_FIX so the patch driver
skips them on apply. Both are drm/xe kernel patches that stopped
applying cleanly after an upstream rebase and haven't been
refreshed yet:
- 0002-drm-xe-guc-use-GUC_SIZE-SZ_4K-for-alignment.patch
- 0005-drm-xe-query-use-PAGE_SIZE-as-the-minimum-page-align.patch
Kernels that were picking these up need them re-based against
current upstream drm/xe before re-enabling. Not a behaviour
change on its own — the patches were already failing the apply
step — but stops the noise in build logs and makes it obvious
at a glance which patches need maintainer attention.
The IPv4 row used a 14-char prefix (` IPv4:` + 8 trailing spaces);
the IPv6 row used 15 (` IPv6:` + 9 trailing spaces). The extra
space on v6 was an attempt to make the v6 address column line up
with the v4 address column when v4 had a `(LAN)` label and v6
didn't (v6's LAN appendix had no label at all, just the bare
address). Worked when v4 had `(LAN)` and v6 had something — broke
the moment LAN got dropped against WAN by the dedup at lines
76-81 and only the `(WAN)` half remained.
Net visible bug (addresses are RFC 5737 / RFC 3849 examples):
IPv4: (WAN) 192.0.2.42
IPv6: (WAN) 2001:db8::42
^ shifted by one column
Fix:
- Use the same 13-char prefix for both rows (IPv4: / IPv6: + 7
padding, no trailing space).
- Both `(LAN)` and `(WAN)` appendices start with a single
leading space — the label always sits at the same column
regardless of which (or both) are present.
- Add a `(LAN)` label to v6 too; the asymmetry was the original
reason the spacing was offset, and removing it lets v4 and v6
structurally mirror each other.
- Drop the trailing space the appendices used to carry — pure
EOL whitespace, never visible.
Verified across all four cases (LAN+WAN / LAN only / WAN only /
nothing): `(LAN)` and `(WAN)` always align column-for-column on
both rows.
Same fix as #9651 for v2026.01 and v2025.10, applied to the common
patch/u-boot/v2026.04/ directory so all boards on U-Boot v2026.04 pick
it up (cm3588-nas, nanopct6, orangepi5, rock-3a, nanopi-r3s-lts,
mekotronics-*, mixtile-blade3, radxa-rock-4d, helios64 via its own
self-contained board_helios64 subdir already has a copy).
Without this, booting from a BTRFS rootfs with zstd-compressed extents
fails with:
zstd_decompress: failed to decompress: 70
BTRFS: An error occurred while reading file /boot/boot.scr
See commit 5617ff3fd for the full rationale.
Code-style and defensive-programming fixes to the helios64 u-boot
overlay, applied on top of the pristine v2026.04 vendor bump. All
changes are additive safety nets — none alter the happy-path
behaviour of the previous Kobol/Armbian code.
board/helios64.c:
- setup_leds(): check led_get_by_label() return value. Without
this, led_set_state() is called on an uninitialised udevice
pointer if LED lookup fails.
- sata_power_enable(): add the matching 10s mdelay after
enabling hdd_b_power, mirroring the one already present after
hdd_a_power. Previously rail B had no spin-up time before
scsi_scan(true) in last_stage_init(), so drives on the second
rail could miss the scan. The staggered spin-up between rails
is preserved (PSU in-rush protection for two 3.5" HDDs).
board/sys_otp.c:
- replace the || chain magic-number check in is_valid_header()
with memcmp() against a const expected_magic[8] (fixes a real
pre-existing bug: the || chain was always true);
- introduce otp_serial() / otp_mfg_year() helpers that assemble
the multi-byte values byte-by-byte, eliminating unaligned
u64/u16 casts into the packed otp struct (UB per the C standard,
also over-read into adjacent fields);
- bounds-check otp.variant against BOARD_VARIANT_MAX before
indexing var_str[], adding BOARD_VARIANT_INVALID slot;
- use strnlen() when printing packed fixed-length fields;
- use snprintf() with target buffer size instead of sprintf();
- retry read_otp_data() in ensure_otp_data_ready() on the first
access after a failed board_early_init_r(), instead of silently
skipping OTP-provided values for the whole boot.
cmd-fileenv-read-string-from-file-into-env.patch:
add 'depends on CMD_FAT' to the cherry-picked CMD_FILEENV Kconfig
entry. do_fat_fsload() is called unconditionally from the
fileenv implementation, so the dependency reflects reality.
general-fix-btrfs-zstd-decompression.patch:
tighten the decompression-success check to also reject short
reads ('|| ret < dlen'). zstd_is_error() alone does not cover
truncated output.
Assisted-by: Claude:claude-opus-4-7
Self-contained board_helios64/ overlay bumped to v2026.04 from v2026.01.
The overlay is a pristine copy of v2026.01 plus the minimum set of
v2026.04-mandated changes and new cherry-picks:
- board/Kconfig: ENV_OFFSET 0x460000 → 0x3F8000
Required by the v2026.04 SPI NOR environment layout.
- 1001-fdt_fixup_ethernet-add-logs.patch.disabled
Cherry-pick of Ricardo Pardini's fdt_fixup_ethernet logging patch.
Shipped disabled; preserved for debugging MAC propagation issues.
- cmd-fileenv-read-string-from-file-into-env.patch
Cherry-pick of the Home Assistant 2018 vendor patch (rebased by
rpardini) adapting 'fileenv' u-boot command for v2026.04.
config/boards/helios64.conf: BOOTBRANCH / BOOTPATCHDIR → v2026.04.
No behaviour changes beyond what the u-boot version bump itself
requires; pre-existing code paths (sys_otp.c, helios64.c) are left
exactly as they were in v2026.01. Defensive code-style fixes on top
of this baseline are a separate follow-up commit.
Assisted-by: Claude:claude-opus-4-7
- those were added to ensure that code was actually being compiled
- we're pretty sure now, so avoid spurious warnings during compilation
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>