Skip to content

ADR 0030 Phase D: Kconfig profiles, committed defconfigs, and a 99-line Makefile - #167

Merged
mcfbytes merged 11 commits into
feat/vanilla-buildrootfrom
feat/vanilla-buildroot-defconfigs
Sep 12, 2026
Merged

mcfbytes merged 11 commits into
feat/vanilla-buildrootfrom
feat/vanilla-buildroot-defconfigs

Conversation

@mcfbytes

Copy link
Copy Markdown
Owner

What this is

The third implementation phase of ADR 0030, stacked on #166 (Phases B+C). Merge #166 first; this PR then re-targets to master automatically.

After this, the newcomer's session is plain Buildroot:

make mister_de10nano_defconfig && make
make O=output-de25 mister_de25nano_defconfig && make O=output-de25
make linux-menuconfig   # linux-rt-menuconfig, legal-info, <pkg>-rebuild, help ...

The one departure from a plain defconfig (the caveat you asked for): package selection lives in three Kconfig profilespackage/mister-userspace (207 selects, the old fragment's 32 section headings kept as comments), package/mister-firmware (31, shared by both boards), package/mister-drivers (4). The defconfig enables them with one line each. Pointers: the profiles' own Kconfig help, the root Config.in menu comment, the Makefile header, README "Building it yourself", and a banner at the top of docs/buildroot-config.md saying where each section's lines now live.

Proof the artifacts are unchanged

  • Both candidate defconfigs were resolved with make <name>_defconfig and diffed against the fragment stacks' resolved configs: identical except for the profile symbols, set lines and is not set lines alike.
  • make mister_de10nano_defconfig && make on the Phase C tree rebuilt nothing (target-finalize and images only); ci-tests.sh 366 pass / 0 fail / 6 skip.
  • scripts/check-defconfigs.sh replaces the golden-hash machinery with upstream's own idiom (check-dotconfig.py) plus: canonical savedefconfig form, every profile select lands, the boards agree on the old common layer. Two real Kconfig traps it enforces: a select of a choice member is silently ignored (so BR2_PACKAGE_ZLIB_NG stays in the defconfig), and so is a select of a nonexistent symbol (it caught one in mister-initramfs).

Makefile: 799 → 99 lines

Pin, fetch/verify/unpack (scripts/fetch-buildroot.sh), the GNU-install shim (scripts/hostshim.sh), all with a configure-first hint, three aliases CI and docs use (de10nano-defconfig, de25nano-defconfig, de25), sdcard, clean/distclean, help, and % forwarding. Bare make builds, as in Buildroot.

Retired

configs/fragments/ (all), stacks.mk, golden.sha256, check-config-fragments.sh, hash-sync-golden.sh (hash-sync case 8), scripts/lib/config-stacks.sh. Every consumer is repointed at configs/mister_de10nano_defconfig (both kernel pins live there now; BR2_PACKAGE_LINUX_RT_VERSION deliberately has no Kconfig default so savedefconfig keeps the pin and Renovate can bump it).

Still open

Rig boot of both kernels; Option G (toolchain as a hash-verified release asset).

🤖 Generated with Claude Code

https://claude.ai/code/session_01V21CRKVv5f66XFNbcrteMD

mcfbytes and others added 3 commits September 11, 2026 13:03
…hase D)

Each board is now ONE committed Buildroot defconfig, loaded the vanilla way:

    make mister_de10nano_defconfig && make
    make O=output-de25 mister_de25nano_defconfig && make O=output-de25

The shared package sets are Kconfig PROFILES -- one symbol that `select`s a
documented list -- so two boards share a userspace by enabling the same
symbol and cannot drift apart on it:

- package/mister-firmware   (31 selects: the /lib/firmware set, both boards)
- package/mister-drivers    (4: the out-of-tree USB WiFi + xone drivers)
- package/mister-userspace  (207: the DE10 userspace, with the old fragment's
                             32 section headings carried as comments)

The DE25 selects only mister-firmware (rule 5: DE10 packages reach it by
owner decision). Two Kconfig facts shaped the profiles and are asserted by
the new checker: a `select` of a kconfig `choice` member is SILENTLY ignored
(BR2_PACKAGE_ZLIB_NG therefore stays in the defconfig), and a `select` of a
symbol that does not exist is ignored too (mister-initramfs's select of
BR2_PACKAGE_HOST_FAKEROOT -- a host package with no Kconfig symbol -- is
removed; the .mk dependency was always what carried it).

Proof: the candidate defconfigs were resolved with `make <name>_defconfig`
and diffed against the fragment stacks' resolved configs -- identical for
both boards except for the profile symbols themselves (set lines AND
`is not set` lines). The committed files are then Buildroot's own
`savedefconfig` form plus a header comment. BR2_PACKAGE_LINUX_RT_VERSION
loses its Kconfig default so the pin is a defconfig line savedefconfig
keeps (a default would have been dropped and the pin left unmanaged).

Retired: configs/fragments/ (every fragment, stacks.mk, golden.sha256),
scripts/check-config-fragments.sh, scripts/hash-sync-golden.sh (case 8),
scripts/lib/config-stacks.sh. New scripts/check-defconfigs.sh replaces
them, the way upstream Buildroot's own CI checks its defconfigs: each
loads, every line survives (support/scripts/check-dotconfig.py -- the
2026.08 headers regression would have failed here instead of moving a
hash), savedefconfig reproduces the file, every profile select lands, and
the boards agree on the old `common` layer's seven symbols.

The wrapper Makefile is rewritten (799 -> 99 lines): pin, fetch + verify +
unpack (scripts/fetch-buildroot.sh), the GNU-install shim
(scripts/hostshim.sh), `all` with a "configure first" hint, `de10nano-defconfig`
/ `de25nano-defconfig` / `de25` aliases for CI and muscle memory, `sdcard`,
clean/distclean, help (ours + Buildroot's), and `%` forwarding with O= and
BR2_EXTERNAL set. Bare `make` builds, as in Buildroot. The DE25 artifact
assertions the old `de25` recipe carried are already made by
board/mister/de25nano/post-image.sh, so nothing moved.

Consumers repointed to configs/mister_de10nano_defconfig: ci-tests.sh,
test-initramfs.sh, test-sdcard-install.sh, lint-kernel-patches.sh,
hash-sync-kernel.sh (both pins), renovate.json (both kernel managers),
export-kernel-tree.sh / check-export-tree.sh, the CI toolchain fingerprint
and dl cache key, renovate-hash-sync.yml's path filter (golden case gone).
README's build section, docs/buildroot-config.md (banner: where each
section's lines now live), docs/ci.md and ADR 0030's status follow.

Verified: check-defconfigs.sh OK (3 defconfigs); `make
mister_de10nano_defconfig && make` on the Phase C tree rebuilt nothing
(target-finalize + images only); ci-tests.sh 366 pass / 0 fail / 6 skip;
shellcheck clean on every touched script and the composite actions.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V21CRKVv5f66XFNbcrteMD
…follow-through)

.github/actions/buildroot-build: 545 -> 213 lines, 18 -> 16 steps. The
`variant` and `board` inputs and everything hung off them -- the sentinel
table (scripts/lib/board-expectations.sh, deleted), the variant-keyed host
cache and make targets, the two conditional build steps -- are gone: since
ADR 0030 Phases B-D there is one configuration and one tree. Cache key
strings are unchanged (buildroot-tarball-*, br-dl-*, br-host-*, ccache
<version>) so existing entries keep hitting. The `ccache-max-size` input
nobody passed is a literal. The header comment now states the four caches
and the two rules that keep them honest; the fingerprint check is one grep
for BR2_arm=y instead of a table.

Makefile: the de10nano-defconfig / de25nano-defconfig aliases go (their
only caller, release.yml's azcopy job, now says `make
mister_de10nano_defconfig`); `de25` stays because the DE25 docs use it.
scripts/check-kernel-fragment-noop.sh had no caller and is removed
(docs/de25-kernel-config.md says so).

Docs: a fixed path/target map applied to the 33 live docs (fragment paths ->
the defconfig or the profile that now carries the line; `make rt` ->
`make linux-rt`; output-rt/ and output-initramfs/ artifacts -> output/images/),
with the passages the map could not fix rewritten by hand (docs/renovate.md's
kernel-pin rows and its retired golden-hash case; the debug-tooling and RT
build blocks). docs/ci.md gains "The pipeline today" at the top -- nine
workflows in a table, the action's four caches and two rules -- and the
1,400-line narrative moves under a "Historical design notes" heading with
its anchors intact. The dated DE25 planning ledgers get a layout-note banner
instead of line edits. ADRs and kernel-recon records are left as written.

Verified: every workflow/action parses; composite-action shellcheck and the
script sweep clean; check-defconfigs.sh OK; Makefile parses.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V21CRKVv5f66XFNbcrteMD
….yml 1,110 -> ~560 lines)

scripts/mk-release.sh owns everything release.yml's build job used to do
inline between `make` and the sdcard image: read /MiSTer.version back out
of linux.img and check the Downloader contract, stage the image assets and
the single legal-info bundle, fetch + verify + extract the pinned stock
archive (scripts/verify-stock-payload.sh, unchanged), assemble files/linux
with our linux.img/zImage_dtb/7za, pack release_YYYYMMDD.7z, round-trip it
under the pinned ARM 7za via qemu-arm, re-verify uboot.img/updateboot and
the member list, and write SHA256SUMS. It runs at a terminal with the
STOCK_* pins in the environment; proven locally against the worktree build
(release_20260904.7z, 84,632,824 B, every check green).

release.yml's build job goes from 27 steps to 9 (checkout, derive version,
build, verify-image, mk-release.sh, sdcard, summary, report, upload); the
two sdcard steps become one with SDCARD_CORES from the dispatch input; the
publish job checks a fixed asset list and `sha256sum -c SHA256SUMS` instead
of discovering kernel variants; the dependency-graph job extracts the one
manifest. The STOCK_* pin block, the build-azcopy job and the release-notes
prose are carried over verbatim. docs/ci.md's release row names the script.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V21CRKVv5f66XFNbcrteMD
mcfbytes and others added 8 commits September 11, 2026 15:41
The golden-case removal in Phase D consumed the COMMITMSG line that closes
the `git commit -F -` heredoc (actionlint/shellcheck on PR #167: SC1044).
Restored after the last bullet, with the guarded push it precedes; the
stale GOLDEN_CHANGED condition on the step is dropped too.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V21CRKVv5f66XFNbcrteMD
…s' patch 0031

The rig, still on an RT 7.2.3 kernel built 2026-09-05 (before PR #152's
7.x re-anchor of the exFAT symlink patch shipped there), Oopsed on the
first symlink update_all.sh's Arcade Organizer created on /media/fat:
PC 0x0 from page_symlink() via exfat_symlink() -- the NULL write_begin
that the DE25's aarch64 QEMU leg had found on 2026-09-06. With
CONFIG_PANIC_ON_OOPS=y and panic=15 the board rebooted 17 s later.

Nothing executed that patch as 32-bit ARM: the DE10 QEMU leg builds at
the shipped 6.18 pin with the shared (page_symlink) form, and the only
runs of the 7.x rewrite were aarch64. `--kernel rt` (de10nano only)
builds the same multi_v7 test kernel at BR2_PACKAGE_LINUX_RT_VERSION with
linux-patches-beta/0031 and its own work/test-initramfs-rt* caches.
ci-tests.sh runs its three exfat-driver cases after the DE10 leg.

Verified locally at 7.2.4: symlink, exfat, fsck-request pass; the 6.18
form of the patch applied to the same 7.2.4 source reproduces the rig's
Oops in QEMU (PC is at 0x0, LR is at page_symlink), so the leg catches
the bug it exists for. The shipped 6.18.50 leg still passes symlink.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V21CRKVv5f66XFNbcrteMD
test-initramfs: --kernel rt, the 32-bit QEMU leg for the RT series' exFAT symlink patch
release.yml: one script from a built output/ to a verified dist/
@mcfbytes
mcfbytes merged commit ff3a498 into feat/vanilla-buildroot Sep 12, 2026
4 checks passed
@mcfbytes
mcfbytes deleted the feat/vanilla-buildroot-defconfigs branch September 12, 2026 00:39
mcfbytes added a commit that referenced this pull request Sep 16, 2026
The golden-case removal in Phase D consumed the COMMITMSG line that closes
the `git commit -F -` heredoc (actionlint/shellcheck on PR #167: SC1044).
Restored after the last bullet, with the guarded push it precedes; the
stale GOLDEN_CHANGED condition on the step is dropped too.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V21CRKVv5f66XFNbcrteMD
mcfbytes added a commit that referenced this pull request Sep 16, 2026
ADR 0030 Phase D: Kconfig profiles, committed defconfigs, and a 99-line Makefile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant