diff --git a/.github/actions/buildroot-build/action.yml b/.github/actions/buildroot-build/action.yml index 45a8fc7..5b8690d 100644 --- a/.github/actions/buildroot-build/action.yml +++ b/.github/actions/buildroot-build/action.yml @@ -331,18 +331,20 @@ runs: # 2. dl/ — every package source tarball. Lives at repo root (survives # `make clean`) — NEVER move it under output/. Keyed on the full - # DE10-Nano fragment stack (the three files configs/fragments/stacks.mk + # DE10-Nano fragment stack (the four files configs/fragments/stacks.mk # lists for DE10NANO_FRAGMENTS — hashFiles() cannot read stacks.mk, so - # they are spelled out here; keep the two in step); restore-keys falls - # back to the version alone so an imperfect match still hydrates what - # didn't change. See docs/ci.md#dl-cache. + # they are spelled out here; keep the two in step, which + # scripts/check-config-fragments.sh (e) asserts by comparing this list + # with the stack); restore-keys falls back to the version alone so an + # imperfect match still hydrates what didn't change. See + # docs/ci.md#dl-cache. - name: Restore Buildroot dl/ download cache id: dl-cache if: env.VARIANT == 'main' uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: dl/ - key: br-dl-${{ env.BUILDROOT_VERSION }}-${{ hashFiles('configs/fragments/common.fragment', 'configs/fragments/de10nano.fragment', 'configs/fragments/de10nano-image.fragment') }} + key: br-dl-${{ env.BUILDROOT_VERSION }}-${{ hashFiles('configs/fragments/common.fragment', 'configs/fragments/de10nano.fragment', 'configs/fragments/image-common.fragment', 'configs/fragments/de10nano-image.fragment') }} restore-keys: | br-dl-${{ env.BUILDROOT_VERSION }}- diff --git a/TASKS.md b/TASKS.md index f8a139a..cc440ba 100644 --- a/TASKS.md +++ b/TASKS.md @@ -708,7 +708,9 @@ Exit criterion: hardware matrix (§11) green (P3.13). **Result: module-autoload half already done pre-task (kmod+depmod xz support, modules.dep/modules.alias populated — see the P3.3 (core) commit). This pass covers only `/lib/firmware` population.** `configs/mister_de10nano_defconfig` (now - `configs/fragments/de10nano-image.fragment`, §5.28 of `docs/buildroot-config.md`) gained + `configs/fragments/image-common.fragment`, §12.1 of `docs/buildroot-config.md` — + it was `de10nano-image.fragment` / §5.28 until the DE25 image adopted the same + set on 2026-09-03) gained `BR2_PACKAGE_LINUX_FIRMWARE` + 9 sub-options (`MEDIATEK_MT7601U/MT7610E/MT7650/MT76X2E`, `RALINK_RT2XX`, `RTL_81XX/RTL_87XX/RTL_87XX_BT/RTL_88XX_BT`), `BR2_PACKAGE_WIRELESS_REGDB` (a separate package from linux-firmware for `regulatory.db`/`.p7s`), and diff --git a/configs/fragments/de10nano-image.fragment b/configs/fragments/de10nano-image.fragment index 13ccda4..4b6a074 100644 --- a/configs/fragments/de10nano-image.fragment +++ b/configs/fragments/de10nano-image.fragment @@ -300,40 +300,8 @@ BR2_PACKAGE_DUALSENSECTL=y # --- ltunify: Logitech Unifying pairing (§5.27, docs/logitech-pairing.md) --- BR2_PACKAGE_LTUNIFY=y -# --- /lib/firmware population (P3.3, §5.28, docs/firmware-parity.md) --- -# WARNING: changing linux-firmware SUB-options on an incremental build installs -# nothing (Buildroot stamping) — `make linux-firmware-dirclean` first. -BR2_PACKAGE_LINUX_FIRMWARE=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7610E=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7650=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT76X2E=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7921=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7925=y -BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT2XX=y -BR2_PACKAGE_LINUX_FIRMWARE_RTL_81XX=y -BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX=y -BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX_BT=y -BR2_PACKAGE_LINUX_FIRMWARE_RTL_88XX_BT=y -BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW88=y -BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW89=y -BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_9271=y -BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_7010=y -BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_9170=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7921_BT=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7922_BT=y -BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7925_BT=y -BR2_PACKAGE_LINUX_FIRMWARE_QUALCOMM_6174A_BT=y -BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_6004=y -BR2_PACKAGE_LINUX_FIRMWARE_REDPINE_RS9113=y -BR2_PACKAGE_LINUX_FIRMWARE_REDPINE_RS9116=y -BR2_PACKAGE_LINUX_FIRMWARE_AR3011=y -BR2_PACKAGE_LINUX_FIRMWARE_AR3012_USB=y -BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM43XX=y -BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM43XXX=y -BR2_PACKAGE_WIRELESS_REGDB=y -BR2_PACKAGE_LINUX_FIRMWARE_EXTRA=y -BR2_PACKAGE_BCM20702_FIRMWARE=y +# --- /lib/firmware population: MOVED to image-common.fragment (§12.1) — the +# blob set is shared by BOTH boards' image stacks (§10, §12) — a note, no config --- # --- explicitly NOT carried forward: manifest §5 Drop list (§5.29) — a note, no config --- diff --git a/configs/fragments/de25nano.fragment b/configs/fragments/de25nano.fragment index 98199fa..9012f9f 100644 --- a/configs/fragments/de25nano.fragment +++ b/configs/fragments/de25nano.fragment @@ -2,10 +2,15 @@ # (Intel/Altera Agilex 5, HPS = 2x Cortex-A76 + 2x Cortex-A55, aarch64). # NO MiSTer packages, NO DE10 packages — that is the accepted release scope # (ADR 0027 Decision 6, ADR 0029, docs/de25-nano-tasks.md D2.7), not a gap. -# Layered on common only (configs/fragments/stacks.mk, DE25NANO_FRAGMENTS); -# no BR2_ symbol here is shared with the DE10 stacks except through that common -# layer. Two FILES are shared by path — the kernel-tarball hash registry (§6.3) -# and the MiSTer kernel-config fragment (§6.5) — and each says so at its line. +# The ONE package set this board shares with the DE10 image is the /lib/firmware +# blob set, and it is NOT listed here: the stack is `common de25nano +# image-common` (configs/fragments/stacks.mk, DE25NANO_FRAGMENTS) and +# image-common.fragment carries that selection once for both boards (owner +# decision 2026-09-03, docs/buildroot-config.md §12; the shared kernel fragment +# below already builds the Wi-Fi/Bluetooth drivers that ask for those blobs). +# No BR2_ symbol here is shared with the DE10 stacks except through those two +# shared layers. Two FILES are shared by path — the kernel-tarball hash registry +# (§6.3) and the MiSTer kernel-config fragment (§6.5) — each says so at its line. # Rationale for every line: docs/buildroot-config.md §6. # --- Architecture & toolchain (docs/buildroot-config.md §6.2) --- @@ -50,6 +55,9 @@ BR2_LINUX_KERNEL_IMAGE=y BR2_LINUX_KERNEL_CUSTOM_DTS_PATH="$(BR2_EXTERNAL_MISTER_PATH)/board/mister/de25nano/socfpga_agilex5_de25nano.dts" # --- Root filesystem: plain ext4, 256 MiB (docs/buildroot-config.md §6.6) --- +# MEASURED 2026-09-03, with image-common's ~52 MiB of firmware installed: +# 85.6 MiB used of 256 MiB (33%), 170 MiB free. No bump needed; the headroom is +# the point of the number, so it is not trimmed to fit either. BR2_TARGET_ROOTFS_EXT2=y BR2_TARGET_ROOTFS_EXT2_4=y BR2_TARGET_ROOTFS_EXT2_LABEL="rootfs" @@ -65,7 +73,9 @@ BR2_TARGET_GENERIC_ISSUE="Welcome to MiSTer DE25-Nano (developer OS)" # Empty = passwordless root; on this board the only way in (no SSH keys yet). BR2_TARGET_GENERIC_ROOT_PASSWD="" -# --- Packages: none, deliberately (docs/buildroot-config.md §6.8) --- +# --- Packages: none beyond the shared firmware set (docs/buildroot-config.md §6.8) --- +# The /lib/firmware blobs come from image-common.fragment (§12); nothing else +# is enabled here, and adding something needs a task that authorises it. # WARNING: the day BR2_PACKAGE_OPENSSH=y is added here it must be added # TOGETHER WITH `# BR2_PACKAGE_OPENSSH_SANDBOX is not set` — this board's # linux.config has no CONFIG_SECCOMP, and openssh's sandbox is `default y`, diff --git a/configs/fragments/golden.sha256 b/configs/fragments/golden.sha256 index 500a85a..f216612 100644 --- a/configs/fragments/golden.sha256 +++ b/configs/fragments/golden.sha256 @@ -6,5 +6,5 @@ # 2026.05.2 de10nano 3cb8e3d9b32d701c4e3eefa1b9993da9b76a73a29a3b29f57924c10b807138a1 2026.05.2 de10nano-kernel 5b372abe43c46c4eb5f3c88d51e48ff2eb6fa713b3c02f0f337c39d0f111dc69 -2026.05.2 de25nano 2adb6b4029bee4467053403fdcf290042ccd2b554cc126de9a2f7a155b433b28 +2026.05.2 de25nano 714728e0bd12e3fb6f86a0b932c204a1acae642a9aba3d0770501bc6b3d7952a 2026.05.2 rt e34a522a56eb088ac84b1e6db7350a22f12293d0d84086dbf1f405f68a58b7e5 diff --git a/configs/fragments/image-common.fragment b/configs/fragments/image-common.fragment new file mode 100644 index 0000000..37bb1ab --- /dev/null +++ b/configs/fragments/image-common.fragment @@ -0,0 +1,61 @@ +# image-common.fragment — the package set every board's SHIPPED IMAGE gets, +# whatever its architecture. Arch-neutral by construction: nothing here may +# name a CPU, an ABI, a board directory, a MiSTer binary or an out-of-tree +# driver for hardware only one board can host. +# +# In the IMAGE stack of every board (configs/fragments/stacks.mk: +# DE10NANO_FRAGMENTS and DE25NANO_FRAGMENTS) and in the kernel-only stack of +# none of them — that is the whole point of the fragment, and the reason it is +# not `common`: `common` IS in the kernel-only stack, so a package line there +# would spend a ~557 MiB fetch and ~52 MiB of install, on every kernel leg, on +# blobs that land in a rootfs.tar which ships nothing but modules and is then +# thrown away — and would move that stack's dl-cache key, which hashes +# common.fragment (docs/buildroot-config.md §10, its rule 6 and the firmware +# row; the toolchain fingerprint is the one key a BR2_PACKAGE_ line cannot +# move — it denies that prefix). It is equally not per-board: parity between +# the boards is exactly what this fragment makes structural, not remembered. +# +# THIS IS THE HOME FOR THE SHARED PACKAGE SET AS THE DE25 GROWS. A package +# both images want moves de10nano-image.fragment -> here, in a commit that +# shows the de10nano golden hash did NOT move (the resolved config is the +# same, only differently filed) and the de25nano one did. What must NOT come +# here: anything DE10-specific, and anything the DE25's bare-developer-OS +# scope has not taken (ADR 0027 Decision 6 / ADR 0029 — §10 rule 5 still +# applies; an owner decision per package, not a refactor's side effect). +# +# Rationale for every line: docs/buildroot-config.md §12. + +# --- /lib/firmware population (P3.3, §12.1, docs/firmware-parity.md) --- +# WARNING: changing linux-firmware SUB-options on an incremental build installs +# nothing (Buildroot stamping) — `make linux-firmware-dirclean` first. +BR2_PACKAGE_LINUX_FIRMWARE=y +BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y +BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7610E=y +BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7650=y +BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT76X2E=y +BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7921=y +BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7925=y +BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT2XX=y +BR2_PACKAGE_LINUX_FIRMWARE_RTL_81XX=y +BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX=y +BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX_BT=y +BR2_PACKAGE_LINUX_FIRMWARE_RTL_88XX_BT=y +BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW88=y +BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW89=y +BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_9271=y +BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_7010=y +BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_9170=y +BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7921_BT=y +BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7922_BT=y +BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7925_BT=y +BR2_PACKAGE_LINUX_FIRMWARE_QUALCOMM_6174A_BT=y +BR2_PACKAGE_LINUX_FIRMWARE_ATHEROS_6004=y +BR2_PACKAGE_LINUX_FIRMWARE_REDPINE_RS9113=y +BR2_PACKAGE_LINUX_FIRMWARE_REDPINE_RS9116=y +BR2_PACKAGE_LINUX_FIRMWARE_AR3011=y +BR2_PACKAGE_LINUX_FIRMWARE_AR3012_USB=y +BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM43XX=y +BR2_PACKAGE_LINUX_FIRMWARE_BRCM_BCM43XXX=y +BR2_PACKAGE_WIRELESS_REGDB=y +BR2_PACKAGE_LINUX_FIRMWARE_EXTRA=y +BR2_PACKAGE_BCM20702_FIRMWARE=y diff --git a/configs/fragments/stacks.mk b/configs/fragments/stacks.mk index 4c66b31..1b5ea67 100644 --- a/configs/fragments/stacks.mk +++ b/configs/fragments/stacks.mk @@ -12,6 +12,15 @@ # CONSTRUCTION — that is what keeps the kernel-only base (used by `make rt` # and every CI kernel leg) in lockstep with the shipped image without a # mirrored copy. scripts/check-kernel-defconfig-sync.sh asserts this. -DE10NANO_FRAGMENTS := common de10nano de10nano-image +# +# `image-common` is the second sharing axis, at right angles to the first: it +# is in the IMAGE stack of every board and in the kernel-only stack of NONE, +# so a package both images want is selected once instead of mirrored per +# board — and the kernel-only base keeps its no-packages shape (§10 rule 4: +# `common` is in the kernel-only stack's fingerprint text, `image-common` is +# not). Merge order within a stack is free here: no symbol may be defined +# twice in one stack (scripts/check-config-fragments.sh (a)), so the board +# layer and the shared image layer never race. +DE10NANO_FRAGMENTS := common de10nano image-common de10nano-image DE10NANO_KERNEL_FRAGMENTS := common de10nano kernel-only -DE25NANO_FRAGMENTS := common de25nano +DE25NANO_FRAGMENTS := common de25nano image-common diff --git a/docs/buildroot-config.md b/docs/buildroot-config.md index 0dcec47..f1ef663 100644 --- a/docs/buildroot-config.md +++ b/docs/buildroot-config.md @@ -27,6 +27,13 @@ Contents: 9. [`mister_installer_defconfig`](#9-mister_installer_defconfig) 10. [Placement decisions — what is common, what is board-only, and why](#10-placement-decisions) 11. [Checks, golden hashes, and the identity proof](#11-checks-golden-hashes-and-the-identity-proof) +12. [`image-common.fragment`](#12-image-commonfragment) + +`image-common.fragment` is a per-fragment section like §2–§9 and belongs, by +subject, between §5 and §6. It is numbered **12** and placed last on purpose: +roughly twenty cross-references to §6–§11 exist in other documents (two of them +in files this change may not touch), and renumbering to insert a §6 would break +every one of them for a cosmetic gain. Read §12 straight after §5. --- @@ -37,10 +44,12 @@ configs/ fragments/ stacks.mk the ONE place that says which fragments form which config common.fragment policy shared by every board and every kernel variant + image-common.fragment packages shared by every board's IMAGE stack — and by no + kernel-only stack (today: the /lib/firmware blob set, §12) de10nano.fragment DE10-Nano board layer: arch/ABI, headers series, kernel stanza de10nano-image.fragment DE10-Nano shipped image: board hooks, ext4 contract, packages, system config kernel-only.fragment turns a board stack into the kernel-only base variants build on - de25nano.fragment DE25-Nano developer OS (aarch64), layered on common only + de25nano.fragment DE25-Nano developer OS (aarch64), layered on common + image-common golden.sha256 sha256 of each stack's normalised resolved .config (§11) mister_rt.fragment the RT / 7.2 kernel variant, layered on the kernel-only stack mister_initramfs_defconfig stage-1 initramfs cpio (standalone Buildroot config, §8) @@ -51,9 +60,9 @@ configs/ | Stack | Fragments | Output dir | Make entry point | |---|---|---|---| -| `de10nano` | `common de10nano de10nano-image` | `output/` | `make de10nano-defconfig` (and `make all`) | +| `de10nano` | `common de10nano image-common de10nano-image` | `output/` | `make de10nano-defconfig` (and `make all`) | | `de10nano-kernel` | `common de10nano kernel-only` | — (base only) | used by every kernel variant | -| `de25nano` | `common de25nano` | `output-de25/` | `make de25nano-defconfig` (and `make de25`) | +| `de25nano` | `common de25nano image-common` | `output-de25/` | `make de25nano-defconfig` (and `make de25`) | | `rt` (variant) | `de10nano-kernel` + `configs/mister_rt.fragment` | `output-rt/` | `make rt` | **Generation** is the idiom `make rt` has used since ADR 0021: Buildroot's own @@ -88,8 +97,15 @@ produced — the only difference is `BR2_DEFCONFIG`, which is where - The kernel-only base shares `common` + `de10nano` with the image **by construction**. That replaces the old hand-mirrored copy; §4 and §11 say what the lockstep check still guards. +- The two sharing axes are at right angles: `common` is shared by every stack + INCLUDING the kernel-only one, `image-common` by every IMAGE stack and by NO + kernel-only stack. A package both images want goes in `image-common` (§12), + never in `common` — rule 4 of §10 says why (`common` is in the kernel-only + stack's fingerprint text, and the kernel-only rootfs.tar ships modules, not + blobs). - Adding a board = a new `.fragment` (+ optionally `-image`), a - `_FRAGMENTS` line in `stacks.mk`, a `BR_MAKE_` / `.config` rule + `_FRAGMENTS` line in `stacks.mk` (with `image-common` in it if the + board ships an image), a `BR_MAKE_` / `.config` rule pair in the Makefile mirroring the DE25's, a golden line (§11), and rows in `scripts/lib/board-expectations.sh`. Adding a kernel variant is unchanged from ADR 0021: one `configs/mister_.fragment`, its Makefile targets, and @@ -482,6 +498,13 @@ package set, and system configuration. Nothing in it may touch the toolchain or the kernel stanza (those are §3); package selection is by design invisible to CI's toolchain-cache fingerprint (`docs/ci.md#toolchain-fingerprint`). +DE10-ONLY, by definition: this fragment is in one stack. The part of the +package set BOTH boards' images share now lives one layer down, in +`image-common.fragment` (§12) — today exactly the `/lib/firmware` blob set, +whose section here (§5.28) is a redirect. When a package listed below is +adopted by another board's image, it moves there; nothing else about it +changes. + ### 5.1 Board hooks: post-build script, rootfs overlays `BR2_ROOTFS_POST_BUILD_SCRIPT="../../board/mister/de10nano/post-build.sh"` — @@ -1471,88 +1494,16 @@ No new selects worth noting: `select BR2_PACKAGE_LIBEXECINFO if !BR2_TOOLCHAIN_USES_GLIBC` is inert here (this image is glibc), so this is a one-line change with no transitive tail — unlike dualsensectl above. -### 5.28 P3.3: /lib/firmware population - -PLAN.md §3/§4.1, module loading & firmware infra — the -module-autoload/depmod/kmod/xz-compress half is already done (§3.5, §5.30). -Source of truth: `docs/firmware-parity.md` (the inventory -> sub-option mapping -+ the built-vs-stock diff). Target: `docs/stock-inventory/firmware.md`'s -66-file inventory (`xow_dongle.bin`, the 67th stock file, is P3.2's -xow-firmware, §5.25, not repeated here). - -linux-firmware itself (`BR2_PACKAGE_LINUX_FIRMWARE`) is a meta-option with no -files of its own — every actual file comes from a sub-option, each picked -because it is the SMALLEST upstream grouping that contains an inventory file -(Buildroot's own file lists are coarse per sub-option, so some non-inventory -sibling files ride along — a documented superset, not a problem; see the -parity doc). `regulatory.db`/`.p7s` come from a SEPARATE package -(wireless-regdb, not linux-firmware — upstream split them out after the -kernel gained direct .db-loading support in 4.15). - -Buildroot stamping trap: changing linux-firmware SUB-options on an incremental -build installs nothing and exits 0 — `make linux-firmware-dirclean` first. - -| symbol | files / reason | -|---|---| -| `_MEDIATEK_MT7601U` | `mt7601u.bin` (top-level, via WHENCE-driven symlink — see parity doc for the build-verified proof) | -| `_MEDIATEK_MT7610E` | `mediatek/mt7610e.bin` | -| `_MEDIATEK_MT7650` | `mt7650.bin` — filed under Buildroot's "Bluetooth firmware" menu (MT7650 is a WiFi+BT combo chip) but is the ONLY toggle that installs this WiFi file; stock's own inventory attributes it to rt2800usb, not to Bluetooth | -| `_MEDIATEK_MT76X2E` | `mediatek/mt7662.bin` + `mediatek/mt7662_rom_patch.bin` (top-level via symlink) — also what the in-tree mt76x2u USB driver requests (`mt76x2/usb_mcu.c`), not a separate `mt7662u.bin` (see parity doc: stock's own `mediatek/mt7662u.bin` / `mt7662u_rom_patch.bin` are the OLD out-of-tree name, superseded, not reproduced) | -| `_MEDIATEK_MT7921` | `WIFI_RAM_CODE_MT7961*.bin` — MT7921U (`mt7921u.ko`, WiFi6 USB; the USB part reports as MT7961) | -| `_MEDIATEK_MT7925` | `WIFI_RAM_CODE_MT7925*.bin` — MT7925U (`mt7925u.ko`, WiFi6E USB) | -| `_RALINK_RT2XX` | `rt2870.bin` (rt2800usb, `FIRMWARE_RT2870`) + siblings | -| `_RTL_81XX` | rtlwifi 8188e/8192c/8192d/8192s/8192eu family | -| `_RTL_87XX` | rtlwifi 8712u/8723a/8723b family | -| `_RTL_87XX_BT` | rtl_bt 8723a/8723b/8723bs/8761a/8761bu family | -| `_RTL_88XX_BT` | `rtl_bt/rtl88*.bin` glob — covers 8812ae/8821a/8821c/8822b/8822cu in one option | -| `_RTL_RTW88` | `rtw88/rtw8822b_fw.bin` etc. — firmware for the MAINLINE rtw88 driver we now use for RTL8822BU (replacing out-of-tree 88x2bu); also covers 8821cu/8822cu rtw88 | -| `_RTL_RTW89` | `rtw89/*.bin` — mainline rtw89 (RTL8851BU/RTL8852BU WiFi6/6E USB) | -| `_ATHEROS_9271` | `ar9271.fw` + `htc_9271*` — ath9k_htc (AR9271 802.11n USB) | -| `_ATHEROS_7010` | `ar7010*.fw` + `htc_7010*` — ath9k_htc (AR7010-based 802.11n USB) | -| `_ATHEROS_9170` | `carl9170-1.fw` — carl9170 (AR9170 802.11n USB) | -| `_MEDIATEK_MT7921_BT` | v10.2 Bluetooth firmware for combo/BT dongles whose driver we already build (`docs/bluetooth-parity.md`); same class of gap as ath3k below — the driver binds, then dies at `request_firmware()`. `mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin` — the BT half of the MT7921AU combo dongle whose WiFi half we already ship. Requested by `btmtk.c`; without it WiFi works and BT does not | -| `_MEDIATEK_MT7922_BT` | `mediatek/BT_RAM_CODE_MT7922_1_1_hdr.bin` — btusb carries MT7922 USB IDs, so this is a reachable USB path, not just the M.2 part | -| `_MEDIATEK_MT7925_BT` | `mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin` — BT half of the MT7925U combo | -| `_QUALCOMM_6174A_BT` | `qca/rampatch_usb_00000302.bin` + `qca/nvm_usb_00000302.bin` — QCA ROME 6174A over USB. btusb requests exactly the "_usb_" names (`btusb.c`: "qca/rampatch_usb_%08x.bin"), and its QCA path is self-contained — it needs no `CONFIG_BT_QCA`, so this firmware is the only missing piece. 132 KiB | -| `_ATHEROS_6004` | `ath6k/AR6004/hw1.2` + `hw1.3` (132 KiB) — ath6kl_usb (`CONFIG_ATH6KL_USB=m`, new in v10.1; AR6003/AR6004 802.11n USB) | -| `_REDPINE_RS9113` | `rsi/rs9113_*.rps` — rsi_usb | -| `_REDPINE_RS9116` | `rsi/rs9116_wlan.rps`, requested by `rsi_91x_hal.c:35` (both toggles needed; `CONFIG_RSI_USB=m`) | -| `_AR3011` | `ath3k-1.fw` — the ath3k driver (`CONFIG_BT_ATH3K=m`, already on) for AR3011 USB Bluetooth. The driver was built but its firmware was NEVER installed, so every AR3011 dongle failed at `request_firmware()`; this closes that gap | -| `_AR3012_USB` | `ar3k/*.dfu` — AR3012 USB Bluetooth patch/config RAM images, loaded by the same ath3k driver (and by btusb for the newer AR3012 IDs) | -| `_BRCM_BCM43XX` | `brcm/brcmfmac4373.bin` + the 43xx SDIO/PCIe siblings — brcmfmac (`CONFIG_BRCMFMAC=m`, new). Implicitly `select`s `BR2_PACKAGE_LINUX_FIRMWARE_CYPRESS_CYW43XX` (`cypress/cyfmac*`, the same silicon post-acquisition) | -| `_BRCM_BCM43XXX` | `brcm/brcmfmac43143.bin`, `43236b.bin`, `43242a.bin`, `43569.bin` — the four BCM43xx USB parts brcmfmac drives; `select`s `_CYPRESS_CYW43XXX` | -| `BR2_PACKAGE_WIRELESS_REGDB` | `regulatory.db` + `regulatory.db.p7s` (separate from linux-firmware, see above) | - -NOT enabled: `_QUALCOMM_9377_BT`. Its two files are `qca/rampatch_00230302.bin` -/ `nvm_00230302.bin` — the NON-usb names, which only the UART path (hci_qca, -`CONFIG_BT_HCIUART`, not built) ever requests. No consumer here. NOT enabled: -`_LINUX_FIRMWARE_IBT` (Intel Bluetooth, `intel/ibt-*`). 30 MiB, and Intel BT -controllers ship essentially only on M.2 WiFi+BT combo cards, which this board -cannot host — there is no realistic external Intel BT USB dongle. -`CONFIG_BT_INTEL` is nonetheless built because `CONFIG_BT_HCIBTUSB` `select`s -it unconditionally (it cannot be turned off while btusb is on), so this is a -DELIBERATE driver-without-firmware, unlike the ath3k/mt7663 cases which were -accidental. Flip this on if an Intel BT dongle ever needs to work. +### 5.28 P3.3: /lib/firmware population — MOVED to §12.1 -`BR2_PACKAGE_LINUX_FIRMWARE_EXTRA=y` — ten files that NO linux-firmware -sub-option covers, even though upstream linux-firmware carries them and this -project's pinned kernel has an in-tree consumer for each (verified by grep -against the actual built kernel source, not assumed; last checked on 6.18.40 — -re-grep on a kernel bump rather than trusting this line — see -`package/linux-firmware-extra/linux-firmware-extra.mk` and -`docs/firmware-parity.md` for the per-file citation). Same upstream tarball and -hash-pin as linux-firmware itself, just a different subset kept. Four are -stock-parity files; the other five are NOT (stock ships none of them) — -`mediatek/mt7663*` x4 back `CONFIG_MT7663U=m` and `rtlwifi/rtl8192dufw.bin` -backs `CONFIG_RTL8192DU=m`, both enabled beyond stock, and each would -otherwise probe and then fail at `request_firmware()`. See `docs/wifi-parity.md` -§6.2, §7. - -`BR2_PACKAGE_BCM20702_FIRMWARE=y` — Broadcom BCM20702 BT dongle firmware -(P3.14): `brcm/BCM20702A1-0b05-17cb.hcd`, the one brcm .hcd stock ships (35000 -bytes) but mainline linux-firmware lacks. Hash-pinned build-time fetch, never -a committed blob — same maintainer-approved vendor-firmware posture as xow -(ADR 0003). See `package/bcm20702-firmware/`. +The `/lib/firmware` blob set is no longer selected by this fragment: it moved, +symbol for symbol, to `image-common.fragment` when the DE25-Nano image adopted +the same set for parity (owner decision 2026-09-03). The rationale, the +sub-option table and the per-symbol placement calls are **§12.1**; the resolved +`de10nano` configuration is unchanged by the move (§11's golden line for this +stack did not budge — that is the proof the move was a filing change and +nothing else). This heading is kept as a redirect so §5's numbering, which +other documents cite, stays put. ### 5.29 Explicitly NOT carried forward (manifest §5 Drop list) @@ -2092,14 +2043,25 @@ get a shell on the board. That is not an oversight or a staging state — it is the accepted release scope for this board until the upstream MiSTer framework grows an aarch64 story (`de25-nano-tasks.md` D2.7 / Phase D3). +One thing has been added to that scope since, by owner decision (2026-09-03): +the `/lib/firmware` blob set, mirrored from the DE10 for parity because the +shared kernel fragment already builds the Wi-Fi/Bluetooth drivers that ask for +those blobs. It is not selected in `de25nano.fragment` — it comes from the +shared image layer, `image-common.fragment` (§12), which is why the stack grew +a third fragment. Firmware is data for drivers this board already builds, not a +package a user runs; the bare-developer-OS scope is otherwise untouched (§6.8). + THE DE10 IS NOT AFFECTED BY THIS FRAGMENT. The de25nano stack is `common` + -`de25nano` (§1); nothing from `de10nano.fragment`, `de10nano-image.fragment`, -`kernel-only.fragment` or `mister_rt.fragment` is in it, and the DE25 gets its -OWN Buildroot output directory (`output-de25/`, `make de25`) exactly the way -the RT variant and the two initramfs stages get theirs. No `BR2_` symbol is -shared between the boards outside `common.fragment`. Two FILES are shared by -path, each with its own reason and its own guard: the kernel-tarball hash -registry (a symlink, §6.3) and the MiSTer kernel-config fragment +`de25nano` + `image-common` (§1); nothing from `de10nano.fragment`, +`de10nano-image.fragment`, `kernel-only.fragment` or `mister_rt.fragment` is in +it, and the DE25 gets its OWN Buildroot output directory (`output-de25/`, `make +de25`) exactly the way the RT variant and the two initramfs stages get theirs. +The only `BR2_` symbols shared between the boards are those in +`common.fragment` and `image-common.fragment` — and sharing them is what those +two fragments are FOR: a symbol in either is one selection, read by both +stacks, not a copy that can drift. Two FILES are shared by path, each with its +own reason and its own guard: the kernel-tarball hash registry (a symlink, +§6.3) and the MiSTer kernel-config fragment (`board/mister/common/linux-mister.fragment`, proved a no-op on the DE10 by `scripts/check-kernel-fragment-noop.sh`, §6.5). @@ -2350,7 +2312,14 @@ guard's comment there. `BR2_TARGET_ROOTFS_EXT2_LABEL="rootfs"`, `BR2_TARGET_ROOTFS_EXT2_SIZE="256M"`. This is a developer OS, not the DE10's shipped `linux.img`. 256 MiB comfortably holds BusyBox + the toolchain runtime with room for a developer to -scp things in. There is deliberately none of the DE10's ceremony here — no +scp things in — and, since 2026-09-03, the ~52 MiB `/lib/firmware` set from +`image-common` (§12). MEASURED after that build, from the built image itself +(`dumpe2fs -h output-de25/images/rootfs.ext4`: 262,144 blocks of 1 KiB, +174,469 free): **85.6 MiB used of 256 MiB, 33%, 170 MiB free** — up from ~34 +MiB before the firmware. The size line therefore did NOT need to move; it is +left at 256M rather than trimmed to fit, because headroom for a developer to +copy things onto the rootfs is the point of the number. Re-measure the same way +when the package list next grows. There is deliberately none of the DE10's ceremony here — no pinned UUID/hash-seed, no forced feature list, no hard-link to `linux.img` — because none of it has a contract to satisfy yet: no Downloader channel, no stock artifact to be byte-compatible with, and no reproducibility lane (D2.8 @@ -2390,18 +2359,28 @@ there is no network provisioning, no `authorized_keys`, and no per-device SSH host-key machinery yet (ADR 0015 is a DE10 rootfs-overlay feature and is not carried here). -### 6.8 Packages — none, deliberately +### 6.8 Packages — none in this fragment; the shared firmware set from `image-common` BusyBox is Buildroot's own default (`BR2_PACKAGE_BUSYBOX` is `default y` in `package/busybox/Config.in`) and so does not appear as a line; it is the -entire userland. Nothing else is enabled: no MiSTer packages, no DE10 -packages, no out-of-tree WiFi or controller drivers, no debug tooling. When -something is eventually needed here, add it in a commit that says which task -authorised it — the empty package list is the D2.1/D2.7 scope decision made -visible, and a package added "just to have it" quietly repeals that decision. -The fragment split did not change this: the DE10 package set lives in +entire userland. `de25nano.fragment` itself still enables **no** package: no +MiSTer packages, no DE10 packages, no out-of-tree WiFi or controller drivers, +no debug tooling. When something is eventually needed here, add it in a commit +that says which task authorised it — the near-empty package list is the +D2.1/D2.7 scope decision made visible, and a package added "just to have it" +quietly repeals that decision. The DE10's package set lives in `de10nano-image.fragment`, which is not in the DE25 stack (§10). +The one exception, and it is deliberate: the `/lib/firmware` blob set reaches +this board through `image-common.fragment` (§12), which IS in the stack. That +is 31 symbols and ~52 MiB of `/lib/firmware` — data for the Wi-Fi/Bluetooth +drivers the shared kernel fragment already builds, so without it those drivers +bind and then fail at `request_firmware()` (`docs/de25-kernel-config.md` §7.1, +now closed). Owner decision, 2026-09-03: parity with the DE10's selection. It +is not a repeal of the bare-developer-OS scope — no binary a user invokes was +added — and the rootfs measurement §6.6 records is what keeps that claim +honest. + ONE STANDING OBLIGATION IS ALREADY BOOKED AGAINST THAT EMPTY LIST, and the fragment carries it as a WARNING so it cannot be missed at the moment it matters. `board/mister/de25nano/linux.config` carries @@ -2940,9 +2919,20 @@ and DE25 files side by side. Rules applied, in order: old single file's. It is (§11). 5. The DE25 is a bare developer OS by decision (ADR 0027 D6, ADR 0029): NO DE10 package or MiSTer symbol may reach its stack, whatever "arch-neutral" - would otherwise suggest. So "common" is the genuinely shared policy, not + would otherwise suggest — until the owner decides otherwise for a named + package, which is rule 6. So "common" is the genuinely shared policy, not the bulk of the DE10 file — the bulk (the package set) is DE10-only by construction, in `de10nano-image`. +6. **Added 2026-09-03 with `image-common.fragment`.** A symbol EVERY BOARD'S + IMAGE wants, and NO kernel-only stack may have, is `image-common` (§12). + Rules 1–5 were written when there was one image stack, so "shared" could + only mean `common`; the DE25 adopting the DE10's firmware set made the + second axis real. The test is two-sided and both sides are load-bearing: + *every image wants it* (else it is a board fragment, rule 3) **and** *the + kernel-only base must not build it* (else it is `common`, rule 1 — and + rule 4's cache consequence bites). Reaching this rule is an owner decision + per package, not a refactor's judgement: rule 5 still governs WHETHER the + DE25 takes a package, and this rule only says where it is then filed. The judgement calls, each recorded here: @@ -2956,7 +2946,8 @@ The judgement calls, each recorded here: | `BR2_PACKAGE_HOST_KMOD_XZ`, `BR2_ROOTFS_POST_IMAGE_SCRIPT` | `de10nano` (board), not `de10nano-image` | The kernel-only stack needs both (build-time depmod of `.ko.xz`; `zImage_dtb` assembly) — §3.5, §3.6. `BR2_ROOTFS_POST_IMAGE_SCRIPT` is now set by BOTH boards, to different scripts (the DE25's assembles the card, §6.11), so it is a per-board symbol on both sides rather than a `common` one. `BR2_PACKAGE_HOST_KMOD_XZ` is set by **both** board fragments (`de10nano` and `de25nano`), each for its own depmod: the shared kernel fragment (`board/mister/common/linux-mister.fragment`) sets `CONFIG_MODULE_COMPRESS_XZ`, so build-time depmod on either board needs host kmod with xz or it silently ships an empty `modules.dep` (§3.5; the DE25 hit exactly that on its first wave-2 card). It is not in `common` for the rule-4 reason above (`common` is in the kernel-only stack's fingerprint text). | | `BR2_ROOTFS_POST_BUILD_SCRIPT`, `BR2_ROOTFS_OVERLAY` | `de10nano-image` | Image-only by design (§4.2: `post-build.sh` stamps a rootfs that ships). | | `BR2_TARGET_ROOTFS_EXT2_SIZE`, `_INODE_SIZE`, `_MKFS_OPTIONS` | `de10nano-image` | The DE25's 256 MiB ext4 has none of the DE10's contracts yet (§6.6). | -| The whole package set, `BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV`, `BR2_GENERATE_LOCALE`, `BR2_TARGET_TZ_*`, `BR2_TARGET_LOCALTIME` | `de10nano-image` | Rule 5. Locale/timezone are arch-neutral and the owner's target listed them as common candidates, but the DE25 old file set none of them and giving a bare developer OS tzdata/locale data is a scope decision D2.x should take explicitly, not a side effect of a refactor. | +| `BR2_PACKAGE_LINUX_FIRMWARE` + its 27 sub-options, `BR2_PACKAGE_WIRELESS_REGDB`, `BR2_PACKAGE_LINUX_FIRMWARE_EXTRA`, `BR2_PACKAGE_BCM20702_FIRMWARE` (31 symbols) | `image-common` (moved out of `de10nano-image`, 2026-09-03) | **Not `common`:** `common` is in the kernel-only stack, whose rootfs is a tar of modules that is thrown away after the `.ko`s are lifted out of it — putting the firmware there would spend a ~557 MiB fetch and ~52 MiB of install on every kernel leg for files no variant ships (`package/linux-firmware-extra/linux-firmware-extra.mk` says the same thing about its own `depends on`), and would move the kernel-variant dl-cache key, which hashes `common.fragment`. The toolchain fingerprint is the one thing it would NOT move: that filter denies `BR2_PACKAGE_` outright (rule 4's usual bite does not apply to package symbols — the other three reasons stand on their own). **Not per-board:** parity IS the owner's decision (2026-09-03), and two copies of a 29-line selection is precisely the hand-mirroring the fragment split exists to end; the DE25 builds the same Wi-Fi/BT drivers from the shared kernel fragment, and they fail at `request_firmware()` without the blobs. Per-symbol calls, including what stayed behind, in §12.1. | +| The rest of the package set, `BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV`, `BR2_GENERATE_LOCALE`, `BR2_TARGET_TZ_*`, `BR2_TARGET_LOCALTIME` | `de10nano-image` | Rule 5. Locale/timezone are arch-neutral and the owner's target listed them as common candidates, but the DE25 old file set none of them and giving a bare developer OS tzdata/locale data is a scope decision D2.x should take explicitly, not a side effect of a refactor. | | `BR2_INIT_NONE`, `BR2_SYSTEM_BIN_SH_NONE`, `# BR2_PACKAGE_BUSYBOX is not set`, `BR2_TARGET_ROOTFS_TAR` | `kernel-only` | Exactly the old kernel defconfig minus what it shared with the image (§4). | | DE25 getty/hostname/issue, `BR2_KERNEL_HEADERS_7_0`, `USE_CUSTOM_CONFIG`, `CUSTOM_CONFIG_FILE`, `CONFIG_FRAGMENT_FILES`, `# USE_ARCH_DEFAULT_CONFIG is not set`, `IMAGE`, `CUSTOM_DTS_PATH` | `de25nano` | Board-specific by nature (§6). The kernel-config pair names DE25 files; the *fragment* file it names is shared with the DE10 by path, but that sharing is a file, not a symbol (§6.5). | | The whole DE25 bootloader stanza (`BR2_TARGET_ARM_TRUSTED_FIRMWARE*`, `BR2_TARGET_UBOOT*`) | `de25nano` | The DE10 has no bootloader in its Buildroot config at all — its boot chain is the stock/Terasic one, assembled outside Buildroot (`docs/boot-chain.md`). Nothing to share, so no `common` question arises. | @@ -2964,16 +2955,22 @@ The judgement calls, each recorded here: | `mister_initramfs_defconfig`, `mister_installer_defconfig` | left standalone | They share five arch lines and `BR2_KERNEL_HEADERS_6_18` with `de10nano.fragment` but differ on the toolchain (musl, static) and everything else; a "de10nano-arch" micro-fragment would save six lines at the price of a fourth stack shape and a toolchain-fingerprint change for the initramfs host cache (`BR_INITRAMFS_HOST_KEY` hashes that file). Not worth it; their comments moved here (§8, §9) for the same reason as the others. | | `BR2_PACKAGE_STRACE=y` twice in the old DE10 file | once, in the T5 section of `de10nano-image` | A duplicate within one fragment is a redefinition the check rejects and a kconfig "override: reassigning" warning; T5 had already made strace permanent (§5.32, §5.42). Resolved config unchanged. | -Symbol counts (assignments + explicit not-set lines): `common` 7; -`de10nano` 16; `kernel-only` 3 + 1 not-set; `de10nano-image` 257 + 10 not-set; -`de25nano` 45 + 2 not-set. de10nano stack total 280 + 10 not-set — the old -file had 281 assignment lines, of which one was the duplicate `BR2_PACKAGE_STRACE=y`, so -the SET of symbols is identical; de10nano-kernel stack 26 + 1, exactly the -old kernel defconfig's; de25nano stack 52 + 2 not-set, exactly the old DE25 -defconfig's (26 + 0 at the split; the bootloader, host-tool and card stanzas of -§6.9–§6.11 and the kernel-config switch of §6.5 arrived with wave 2 and were -ported symbol-for-symbol, the resulting stack symbol set diffed line-for-line -against the last version of the deleted file). +Symbol counts (assignments + explicit not-set lines), re-measured 2026-09-03 +with `config_strip_fragment` (`scripts/lib/config-stacks.sh`, the same reader +the checks use): `common` 7; `de10nano` 16; `kernel-only` 3 + 1 not-set; +`image-common` 31; `de10nano-image` 226 + 10 not-set; `de25nano` 46 + 2 +not-set. de10nano stack total 280 + 10 not-set — UNCHANGED by the firmware +move, which took 31 symbols out of `de10nano-image` (257 → 226) and put them in +`image-common`, in the same stack; the old file had 281 assignment lines, of +which one was the duplicate `BR2_PACKAGE_STRACE=y`, so the SET of symbols is +identical. de10nano-kernel stack 26 + 1, exactly the old kernel defconfig's. +de25nano stack 84 + 2 not-set: 53 + 2 of its own two layers (the bootloader, +host-tool and card stanzas of §6.9–§6.11 and the kernel-config switch of §6.5 +arrived with wave 2 and were ported symbol-for-symbol against the last version +of the deleted file) plus `image-common`'s 31. Two corrections to the numbers +this paragraph carried before: `de25nano` was 46, not 45, and the stack 53, not +52 — the paragraph was written at the split and a symbol was added after it, +which is why the counts are now measured rather than transcribed. --- @@ -3009,7 +3006,9 @@ compile; ~4 s warm; runs in `lint-config`): for each stack in `stacks.mk` plus - (e) path consumers: every `configs/fragments/` named in the code/CI surface (`Makefile`, `scripts/`, `.github/`, `renovate.json` — not docs) exists, and `action.yml`'s two `hashFiles()` lists equal the `DE10NANO` / - `DE10NANO_KERNEL` stacks' files. A fragment rename that updates `stacks.mk` + `DE10NANO_KERNEL` stacks' files (the DE10NANO one is four files since + `image-common` joined that stack; the comparison is set-wise, both sides + sorted, so the order inside `hashFiles()` is free). A fragment rename that updates `stacks.mk` would otherwise pass (a)-(d) while the dl-cache keys, Renovate's `managerFilePatterns`, the workflow path filter and the scripts that read a pin by filename (`hash-sync-kernel.sh`, `ci-tests.sh`, @@ -3072,9 +3071,191 @@ moved. The same identity was checked for `mister_initramfs_defconfig` and changed; the resolved configs are byte-identical, `BR2_DEFCONFIG` included, since the files kept their names). -SINCE THE SPLIT, one golden line has moved on purpose: `de25nano`, when the -DE25 wave-2 work (§6.5's kernel-config switch and the §6.9–§6.11 bootloader, -host-tool and card stanzas) was ported into `de25nano.fragment`. The -`de10nano`, `de10nano-kernel` and `rt` lines are unchanged from the split, and -must stay so — the DE25 shares no stack with them, so a DE25 change that moves -any of the other three is a bug in the change, not in the hash. +SINCE THE SPLIT, the `de25nano` golden line has moved on purpose twice: once +when the DE25 wave-2 work (§6.5's kernel-config switch and the §6.9–§6.11 +bootloader, host-tool and card stanzas) was ported into `de25nano.fragment`, +and once on 2026-09-03 when `image-common.fragment` joined its stack and +brought the `/lib/firmware` set (§12) with it — +`2adb6b40…` → `714728e0…`, the added lines being exactly the 31 moved symbols +plus the two sub-options `_BRCM_BCM43XX`/`_BRCM_BCM43XXX` `select` +(`_CYPRESS_CYW43XX`, `_CYPRESS_CYW43XXX`), and nothing else. The `de10nano`, +`de10nano-kernel` and `rt` lines are unchanged from the split, and must stay +so — the DE25 shares no stack with them, so a DE25 change that moves any of the +other three is a bug in the change, not in the hash. That rule did real work in +this change: moving 31 symbols from `de10nano-image` to `image-common` is +inside ONE stack, so `de10nano` had to hash the same afterwards, and it does. +The same argument in the CI dimension: the toolchain fingerprint is computed +over the stack's concatenated fragments, comment-stripped, `BR2_PACKAGE_`- +denied and **sorted**, so relocating package lines between fragments of one +stack cannot move it — measured byte-identical (26 lines) before and after. +The dl-cache key, which is `hashFiles()` over the same four files, DOES move +once; `restore-keys` falls back to the version prefix, so that run is warm. + +--- + +## 12. `image-common.fragment` + +The package set every board's SHIPPED IMAGE gets, whatever its architecture: +in `DE10NANO_FRAGMENTS` and `DE25NANO_FRAGMENTS`, and in no kernel-only stack +(`configs/fragments/stacks.mk`; §1's table). It is the second sharing axis, at +right angles to `common`'s: `common` is what every stack shares INCLUDING the +kernel-only base, `image-common` is what every stack that produces a rootfs +somebody boots shares and the kernel-only base must NOT have. §10 rule 6 is +the placement test; §10's table row is the argument for the one thing in it +today. + +Arch-neutral by construction. Nothing here may name a CPU, an ABI, a board +directory, a MiSTer binary, or an out-of-tree driver for hardware only one +board can host — those are board fragments. And arch-neutrality is necessary, +not sufficient: §10 rule 5 still decides WHETHER the DE25 takes a package at +all (locale data and tzdata are arch-neutral and are deliberately still +DE10-only, §10). A package arrives here by an owner decision naming it, in a +commit that shows the `de10nano` golden hash unmoved and the `de25nano` one +moved (§11) — that pair of facts is what "the same resolved config, differently +filed, plus a deliberate addition on the other board" looks like. + +**This is the home for the shared package set as the DE25 grows.** Today it is +one block, the `/lib/firmware` blobs. As the DE25 leaves bare-developer-OS +scope, each package both images want moves `de10nano-image` → here rather than +being duplicated; the DE10 fragment keeps only what is genuinely DE10-only. + +### 12.1 P3.3: /lib/firmware population + +Selected here for **both** boards' images since 2026-09-03 (it was §5.28, in +`de10nano-image.fragment`, from P3.3 until then). Everything below is the DE10 +rationale unchanged — every file, sub-option and citation still holds, because +the same symbols now resolve into both configs. What the DE25 adds is the +reason the set is shared: `board/mister/common/linux-mister.fragment` builds +the same Wi-Fi/Bluetooth driver set on both kernels (`docs/de25-kernel-config.md` +§7.1), so the DE25 had exactly these drivers binding and then failing at +`request_firmware()`. Owner decision, 2026-09-03: mirror the DE10's selection +rather than curate a second one — a curated subset would be a second thing to +keep in step, and the boards take the same USB dongles. + +PLAN.md §3/§4.1, module loading & firmware infra — the +module-autoload/depmod/kmod/xz-compress half is already done (§3.5, §5.30). +Source of truth: `docs/firmware-parity.md` (the inventory -> sub-option mapping ++ the built-vs-stock diff). Target: `docs/stock-inventory/firmware.md`'s +66-file inventory (`xow_dongle.bin`, the 67th stock file, is P3.2's +xow-firmware, §5.25, not repeated here). + +linux-firmware itself (`BR2_PACKAGE_LINUX_FIRMWARE`) is a meta-option with no +files of its own — every actual file comes from a sub-option, each picked +because it is the SMALLEST upstream grouping that contains an inventory file +(Buildroot's own file lists are coarse per sub-option, so some non-inventory +sibling files ride along — a documented superset, not a problem; see the +parity doc). `regulatory.db`/`.p7s` come from a SEPARATE package +(wireless-regdb, not linux-firmware — upstream split them out after the +kernel gained direct .db-loading support in 4.15). + +Buildroot stamping trap: changing linux-firmware SUB-options on an incremental +build installs nothing and exits 0 — `make linux-firmware-dirclean` first. + +| symbol | files / reason | +|---|---| +| `_MEDIATEK_MT7601U` | `mt7601u.bin` (top-level, via WHENCE-driven symlink — see parity doc for the build-verified proof) | +| `_MEDIATEK_MT7610E` | `mediatek/mt7610e.bin` | +| `_MEDIATEK_MT7650` | `mt7650.bin` — filed under Buildroot's "Bluetooth firmware" menu (MT7650 is a WiFi+BT combo chip) but is the ONLY toggle that installs this WiFi file; stock's own inventory attributes it to rt2800usb, not to Bluetooth | +| `_MEDIATEK_MT76X2E` | `mediatek/mt7662.bin` + `mediatek/mt7662_rom_patch.bin` (top-level via symlink) — also what the in-tree mt76x2u USB driver requests (`mt76x2/usb_mcu.c`), not a separate `mt7662u.bin` (see parity doc: stock's own `mediatek/mt7662u.bin` / `mt7662u_rom_patch.bin` are the OLD out-of-tree name, superseded, not reproduced) | +| `_MEDIATEK_MT7921` | `WIFI_RAM_CODE_MT7961*.bin` — MT7921U (`mt7921u.ko`, WiFi6 USB; the USB part reports as MT7961) | +| `_MEDIATEK_MT7925` | `WIFI_RAM_CODE_MT7925*.bin` — MT7925U (`mt7925u.ko`, WiFi6E USB) | +| `_RALINK_RT2XX` | `rt2870.bin` (rt2800usb, `FIRMWARE_RT2870`) + siblings | +| `_RTL_81XX` | rtlwifi 8188e/8192c/8192d/8192s/8192eu family | +| `_RTL_87XX` | rtlwifi 8712u/8723a/8723b family | +| `_RTL_87XX_BT` | rtl_bt 8723a/8723b/8723bs/8761a/8761bu family | +| `_RTL_88XX_BT` | `rtl_bt/rtl88*.bin` glob — covers 8812ae/8821a/8821c/8822b/8822cu in one option | +| `_RTL_RTW88` | `rtw88/rtw8822b_fw.bin` etc. — firmware for the MAINLINE rtw88 driver we now use for RTL8822BU (replacing out-of-tree 88x2bu); also covers 8821cu/8822cu rtw88 | +| `_RTL_RTW89` | `rtw89/*.bin` — mainline rtw89 (RTL8851BU/RTL8852BU WiFi6/6E USB) | +| `_ATHEROS_9271` | `ar9271.fw` + `htc_9271*` — ath9k_htc (AR9271 802.11n USB) | +| `_ATHEROS_7010` | `ar7010*.fw` + `htc_7010*` — ath9k_htc (AR7010-based 802.11n USB) | +| `_ATHEROS_9170` | `carl9170-1.fw` — carl9170 (AR9170 802.11n USB) | +| `_MEDIATEK_MT7921_BT` | v10.2 Bluetooth firmware for combo/BT dongles whose driver we already build (`docs/bluetooth-parity.md`); same class of gap as ath3k below — the driver binds, then dies at `request_firmware()`. `mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin` — the BT half of the MT7921AU combo dongle whose WiFi half we already ship. Requested by `btmtk.c`; without it WiFi works and BT does not | +| `_MEDIATEK_MT7922_BT` | `mediatek/BT_RAM_CODE_MT7922_1_1_hdr.bin` — btusb carries MT7922 USB IDs, so this is a reachable USB path, not just the M.2 part | +| `_MEDIATEK_MT7925_BT` | `mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin` — BT half of the MT7925U combo | +| `_QUALCOMM_6174A_BT` | `qca/rampatch_usb_00000302.bin` + `qca/nvm_usb_00000302.bin` — QCA ROME 6174A over USB. btusb requests exactly the "_usb_" names (`btusb.c`: "qca/rampatch_usb_%08x.bin"), and its QCA path is self-contained — it needs no `CONFIG_BT_QCA`, so this firmware is the only missing piece. 132 KiB | +| `_ATHEROS_6004` | `ath6k/AR6004/hw1.2` + `hw1.3` (132 KiB) — ath6kl_usb (`CONFIG_ATH6KL_USB=m`, new in v10.1; AR6003/AR6004 802.11n USB) | +| `_REDPINE_RS9113` | `rsi/rs9113_*.rps` — rsi_usb | +| `_REDPINE_RS9116` | `rsi/rs9116_wlan.rps`, requested by `rsi_91x_hal.c:35` (both toggles needed; `CONFIG_RSI_USB=m`) | +| `_AR3011` | `ath3k-1.fw` — the ath3k driver (`CONFIG_BT_ATH3K=m`, already on) for AR3011 USB Bluetooth. The driver was built but its firmware was NEVER installed, so every AR3011 dongle failed at `request_firmware()`; this closes that gap | +| `_AR3012_USB` | `ar3k/*.dfu` — AR3012 USB Bluetooth patch/config RAM images, loaded by the same ath3k driver (and by btusb for the newer AR3012 IDs) | +| `_BRCM_BCM43XX` | `brcm/brcmfmac4373.bin` + the 43xx SDIO/PCIe siblings — brcmfmac (`CONFIG_BRCMFMAC=m`, new). Implicitly `select`s `BR2_PACKAGE_LINUX_FIRMWARE_CYPRESS_CYW43XX` (`cypress/cyfmac*`, the same silicon post-acquisition) | +| `_BRCM_BCM43XXX` | `brcm/brcmfmac43143.bin`, `43236b.bin`, `43242a.bin`, `43569.bin` — the four BCM43xx USB parts brcmfmac drives; `select`s `_CYPRESS_CYW43XXX` | +| `BR2_PACKAGE_WIRELESS_REGDB` | `regulatory.db` + `regulatory.db.p7s` (separate from linux-firmware, see above) | + +NOT enabled: `_QUALCOMM_9377_BT`. Its two files are `qca/rampatch_00230302.bin` +/ `nvm_00230302.bin` — the NON-usb names, which only the UART path (hci_qca, +`CONFIG_BT_HCIUART`, not built) ever requests. No consumer here. NOT enabled: +`_LINUX_FIRMWARE_IBT` (Intel Bluetooth, `intel/ibt-*`). 30 MiB, and Intel BT +controllers ship essentially only on M.2 WiFi+BT combo cards, which this board +cannot host — there is no realistic external Intel BT USB dongle. +`CONFIG_BT_INTEL` is nonetheless built because `CONFIG_BT_HCIBTUSB` `select`s +it unconditionally (it cannot be turned off while btusb is on), so this is a +DELIBERATE driver-without-firmware, unlike the ath3k/mt7663 cases which were +accidental. Flip this on if an Intel BT dongle ever needs to work. + +`BR2_PACKAGE_LINUX_FIRMWARE_EXTRA=y` — ten files that NO linux-firmware +sub-option covers, even though upstream linux-firmware carries them and this +project's pinned kernel has an in-tree consumer for each (verified by grep +against the actual built kernel source, not assumed; last checked on 6.18.40 — +re-grep on a kernel bump rather than trusting this line — see +`package/linux-firmware-extra/linux-firmware-extra.mk` and +`docs/firmware-parity.md` for the per-file citation). Same upstream tarball and +hash-pin as linux-firmware itself, just a different subset kept. Four are +stock-parity files; the other five are NOT (stock ships none of them) — +`mediatek/mt7663*` x4 back `CONFIG_MT7663U=m` and `rtlwifi/rtl8192dufw.bin` +backs `CONFIG_RTL8192DU=m`, both enabled beyond stock, and each would +otherwise probe and then fail at `request_firmware()`. See `docs/wifi-parity.md` +§6.2, §7. + +`BR2_PACKAGE_BCM20702_FIRMWARE=y` — Broadcom BCM20702 BT dongle firmware +(P3.14): `brcm/BCM20702A1-0b05-17cb.hcd`, the one brcm .hcd stock ships (35000 +bytes) but mainline linux-firmware lacks. Hash-pinned build-time fetch, never +a committed blob — same maintainer-approved vendor-firmware posture as xow +(ADR 0003). See `package/bcm20702-firmware/`. + +### 12.2 Per-symbol placement calls + +Every symbol in the DE10's old "/lib/firmware population" block was decided +individually, plus the two neighbours that could plausibly have come along. + +| Symbol(s) | Call | Why | +|---|---|---| +| `BR2_PACKAGE_LINUX_FIRMWARE` + its 27 sub-options (the §12.1 table) | **moved** to `image-common` | The owner's decision names exactly this set. No sub-option carries a `depends on` in Buildroot's `package/linux-firmware/Config.in`, so nothing here is arch-gated and every line survives `olddefconfig` on aarch64 — proved by check (b) on the `de25nano` stack, 86 symbols, 0 dropped. | +| `BR2_PACKAGE_WIRELESS_REGDB` | **moved** | Not part of `linux-firmware` (upstream split it out, §12.1), but it is `/lib/firmware` content requested the same way — `cfg80211` loads `regulatory.db`/`.p7s` directly since 4.15 — and `cfg80211` is in the shared kernel fragment. Shipping the drivers and their firmware on the DE25 while leaving the regulatory database behind would mean a board that associates but is stuck on the world-roaming channel set. Arch-neutral data package, no dependencies. | +| `BR2_PACKAGE_LINUX_FIRMWARE_EXTRA` (ours) | **moved** | `depends on BR2_PACKAGE_LINUX_FIRMWARE` and installs out of that package's extracted tree (no source of its own), so it goes exactly where its parent goes or it is dead weight. Its files back in-tree drivers (`MT7663U`, `RTL8192DU`, btbcm) that the shared kernel fragment builds on both boards. Note its own `.mk` reasoning still holds unchanged on the other axis: it does not build in the kernel-only variants, because `linux-firmware` is not in that stack — which is precisely what keeping this fragment out of `kernel-only` preserves. | +| `BR2_PACKAGE_BCM20702_FIRMWARE` (ours) | **moved** | A one-file firmware package for a USB Bluetooth dongle (`brcm/BCM20702A1-0b05-17cb.hcd`), uploaded by btbcm under btusb — both built by the shared kernel fragment. Same class as the rest: blobs for drivers this board already has, no binary a user runs, arch-neutral (it installs a blob; nothing is compiled). Kept out would leave the identical `request_firmware()` gap on the DE25 that P3.14 closed on the DE10. | +| `BR2_PACKAGE_XOW_FIRMWARE` | **stayed** in `de10nano-image` | It is `depends on BR2_PACKAGE_XONE` (`package/xow-firmware/Config.in`), and `xone` is an out-of-tree kernel module the DE25 does not build. Moving it would not merely be wrong in principle — the symbol's dependency would be unmet in the `de25nano` stack and `olddefconfig` would silently drop it, which check (b) turns into a hard failure. The check makes this call for us. | +| `BR2_PACKAGE_XONE`, `BR2_PACKAGE_RTL8852CU_MORROWNR` | **stayed** | Out-of-tree kernel modules: they compile against a specific kernel and have never been built on aarch64/7.2 (§5.24, §5.25). Firmware is data; a driver is code that has to build and bind. Not the same decision, and not this fragment's business until someone builds and tests them. | +| `BR2_PACKAGE_KMOD_TOOLS` | **stayed** | Arch-neutral and a plausible "both images want it" candidate, but no owner decision has taken it for the DE25 (§10 rule 5), and the DE25 has no module-loading userland story yet — BusyBox's own `modprobe` covers its needs. A candidate for a later commit, not a side effect of this one. | + +### 12.3 What the move did, and did not, change + +- **The DE10's resolved configuration: nothing.** 31 symbols moved between two + fragments of the same stack, so the merged text is the same set; the + `de10nano` golden hash (§11) is byte-identical either side of the move, and + so are `de10nano-kernel` and `rt` (neither stack contains this fragment). +- **CI's toolchain fingerprint: nothing.** It is computed over the stack's + concatenated fragments, comment-stripped, `BR2_PACKAGE_`/`BR2_LINUX_KERNEL` + denied, and **sorted** (`.github/actions/buildroot-build/action.yml`), so + neither the relocation nor the fragment count can move it. Measured + byte-identical, 26 lines, before and after. +- **CI's dl-cache key: once.** It is `hashFiles()` over the DE10 stack's + files, which is now four (`check-config-fragments.sh` (e) asserts that list + equals the stack). `restore-keys` falls back to the Buildroot-version prefix, + so the first run after this change still hydrates `dl/` from the previous + entry. +- **Renovate: nothing.** No manager matches these lines. The only + `managerFilePatterns` entry naming a fragment is the 6.18 kernel pin's + (`configs/fragments/de10nano.fragment`), and the firmware packages' own pins + live in `package/*/*.hash` and `package/bcm20702-firmware/bcm20702-firmware.mk`, + matched by their own managers regardless of which fragment enables them. + `linux-firmware` itself is bumped by fork-syncing upstream Buildroot. +- **The DE25's rootfs: +52 MiB, measured.** Built 2026-09-03 in + `output-de25/`: `target/lib/firmware` holds **202 files + 66 symlinks, 52 + MiB**, and `find | sort` against the DE10's own `output/target/lib/firmware` + (204 + 67) differs by exactly three entries — `xow_dongle.bin`, + `xone_dongle_02fe.bin`, `xone_dongle_02e6.bin`, the xow-firmware package that + §12.2 deliberately left behind. That empty diff modulo three files is the + parity claim, checked rather than asserted. §6.6 records the ext4 numbers + (85.6 MiB used of 256 MiB) and why `BR2_TARGET_ROOTFS_EXT2_SIZE` still + stands; `scripts/check-sdcard-de25.sh` passes on the rebuilt card. diff --git a/docs/de25-kernel-config.md b/docs/de25-kernel-config.md index 9f28083..63170ce 100644 --- a/docs/de25-kernel-config.md +++ b/docs/de25-kernel-config.md @@ -475,20 +475,38 @@ Note the symbol name: `BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG`, **not** `BR2_LINUX_KERNEL_USE_DEFCONFIG` (that one names an in-tree defconfig and takes a bare name in `BR2_LINUX_KERNEL_DEFCONFIG`, `linux/linux.mk:360-361`). -### 7.1 Firmware — enabled drivers with no blobs - -`configs/fragments/de25nano.fragment` currently selects **no** -`BR2_PACKAGE_LINUX_FIRMWARE_*` at all, while the shared fragment now builds the -whole DE10 Wi-Fi/Bluetooth driver set. Those drivers will bind and then fail at -`request_firmware()`. That is not a regression — wave 1 had exactly the same -drivers as `=m` from arm64 `defconfig`, also without firmware — but it is now a -*deliberate* set, so the decision should be explicit. The DE10's 29 firmware -selections (`configs/fragments/de10nano-image.fragment`, its "/lib/firmware -population" block; `docs/buildroot-config.md` §5.28; **52 MB** installed at -`/lib/firmware`) are the menu to copy from; see -[`firmware-parity.md`](firmware-parity.md) and [`wifi-parity.md`](wifi-parity.md). -This is an **owner decision**, not a config fact: the initial DE25 scope is a -bare developer OS (ADR 0027), and the firmware set is tens of MB of rootfs. +### 7.1 Firmware — RESOLVED 2026-09-03: the DE25 ships the DE10's blob set + +**The obligation this section recorded is closed.** It read: `de25nano.fragment` +selects no `BR2_PACKAGE_LINUX_FIRMWARE_*` at all while the shared fragment +builds the whole DE10 Wi-Fi/Bluetooth driver set, so those drivers bind and +then fail at `request_firmware()`; the DE10's 29 selections are the menu to +copy from; and the call is an **owner decision**, not a config fact, because +the DE25's scope is a bare developer OS (ADR 0027) and the set is tens of MB of +rootfs. + +The owner took it on **2026-09-03: mirror the DE10's selection, for parity.** +How it was implemented — structurally, not by copying lines into +`de25nano.fragment`: + +* The whole block moved OUT of `de10nano-image.fragment` and INTO a new + `configs/fragments/image-common.fragment`, the layer shared by every board's + IMAGE stack and by no kernel-only stack. `DE25NANO_FRAGMENTS` gained it, so + the DE25 gets the identical 31 symbols with no second copy to keep in step + (`configs/fragments/stacks.mk`; `docs/buildroot-config.md` §12, per-symbol + calls in §12.2). +* `xow-firmware` did NOT come along: it `depends on BR2_PACKAGE_XONE`, an + out-of-tree module this board does not build (§12.2). +* Built and measured on the real DE25 output tree: `/lib/firmware` holds + **202 files + 66 symlinks, 52 MB** — byte-for-byte the DE10's tree minus + exactly the three xow/xone entries. The ext4 rootfs goes to **85.6 MiB used + of 256 MiB** (33%), so `BR2_TARGET_ROOTFS_EXT2_SIZE="256M"` stands unchanged. +* The DE10 is provably unaffected: its resolved configuration is identical + (its golden hash did not move), and CI's toolchain fingerprint is + byte-identical — see `docs/buildroot-config.md` §11 and §12.3. + +See [`firmware-parity.md`](firmware-parity.md) and +[`wifi-parity.md`](wifi-parity.md) for what each sub-option installs. --- diff --git a/docs/de25-nano-tasks.md b/docs/de25-nano-tasks.md index df761f4..a0f8c69 100644 --- a/docs/de25-nano-tasks.md +++ b/docs/de25-nano-tasks.md @@ -338,18 +338,17 @@ UART** is normal; capture the SPL's `DDR:` lines (the only real DRAM-size measur ### Still open after wave 2 -- p2 filesystem / DE10-style two-stage layout (FAT boot + exFAT data + `linux.img` loop root) - — owner decision; the initramfs route is arch-neutral and the rewritten `loop=` patch - compile-verifies on aarch64, so both are open. Recommendation: first hardware boot on the plain - ext4 card, then switch. +- ~~p2 filesystem / DE10-style two-stage layout~~ **Decided 2026-09-03 (ADR 0029 D11):** the + two-stage layout is the target; the plain ext4 card stays until hardware. Owed before the + switch: an aarch64 stage-1 initramfs stack + its QEMU test path. - The DE25 kernel pin has no Renovate manager and shares `linux.hash` by symlink with the DE10 registry, so an rt bump replaces the 7.2.y hash line rather than adding one. **This happened on 2026-09-02** (rt 7.2.2 -> 7.2.3): the DE25 pin was moved to 7.2.3 in the same series of commits and the series/config were re-verified there (34/34 patches at `-F0`, 460 symbols 0 dropped, `docs/de25-kernel-config.md` §8). Still needs its own Renovate manager, or a hash-sync rule that keeps every line a fragment still pins, so the next bump is not manual. -- DE25 selects no `linux-firmware`; the shared fragment builds the Wi-Fi/BT drivers that will - ask for it. Owner decision against the bare-developer-OS scope. +- ~~DE25 selects no `linux-firmware`~~ **Decided 2026-09-03 (ADR 0029 D12):** mirror the DE10 + set via a shared `image-common` fragment (PR in flight); seccomp stays off as on the DE10. - Patch 0002 (MiSTer audio) still excluded; `openssh` will need `_SANDBOX` off when added. ## What to do next — 2026-08-22 @@ -365,7 +364,10 @@ Remaining, in unblock order: test, SMMU-off first. 2. **`scripts/test-initramfs.sh` aarch64 path** (`qemu-system-aarch64 -M virt`) and the aarch64 initramfs itself, which the two-stage layout will need. -3. **Owner decisions** listed under "Still open after wave 2". +3. **Owner decisions still open**: a Renovate manager for the DE25 kernel pin; upstream + submission of 0101/0102; patch 0002 (audio). Hardware is expected after the owner's vacation + (ordered on return), so the aarch64 initramfs stack and its QEMU path are the pre-hardware + work that remains. Item 2 above should be done before the board arrives. 4. **Stand up D0.4** as a `/schedule` routine. Sequencing note learned the hard way on 2026-08-21: when a research phase feeds a claim set that a diff --git a/docs/decisions/0029-de25-implementation-path.md b/docs/decisions/0029-de25-implementation-path.md index 00e9db2..503d4f8 100644 --- a/docs/decisions/0029-de25-implementation-path.md +++ b/docs/decisions/0029-de25-implementation-path.md @@ -50,6 +50,8 @@ Accept the nine decisions below as the bounding constraints for DE25 wave 1. | D8 | Fix mainline's unbindable Agilex 5 svc node **upstream** | §3.1 note | **DP-9** | | D9 | A vendor `svc` carry is a hardware-gated escape hatch | §1 row 9, §2.6 | **DP-9**, **DP-1** | | D10 | The SMMU ships **disabled**; DMA isolation is a non-goal (DE10 parity) | [`de25-dts-rationale.md`](../de25-dts-rationale.md) §4 | **DP-9**, **DP-1** | +| D11 | Card layout **target** is the DE10-style two-stage layout; the plain-ext4 card stays until hardware | [`de25-sdcard.md`](../de25-sdcard.md) | **DP-3** | +| D12 | The DE25 mirrors the DE10's `linux-firmware` selection; seccomp stays off as on the DE10 | [`de25-kernel-config.md`](../de25-kernel-config.md) §7.1 | **DP-1**, 0027 **Decision 6** | ### D1 — Core loading goes through `fpga_manager` + a DT overlay @@ -256,11 +258,50 @@ fabric is loaded by its owner. non-goal by default); or the SMMU-off fabric test fails on hardware and the vendor remapper behaviour turns out to be required — that is D9's escape hatch, evaluated then. +### D11 — Card layout: the DE10-style two-stage layout is the target; plain ext4 until hardware + +**Decision (owner, 2026-09-03).** The DE25 card will use the DE10's model: p1 FAT holding the +boot files, p2 an exFAT data partition (the `/media/fat` equivalent) holding `linux/linux.img`, +loop-mounted as the root by the embedded initramfs. Until a board is in hand the shipped card +keeps the interim shape (p2 = the ext4 root written directly, `root=/dev/mmcblk0p2`), because it +isolates the factory-SPL, DTS and SD-controller questions the first boot has to answer. + +- **Evidence.** The initramfs two-stage design carries no architecture-specific line (README, + "The initramfs that deleted a kernel patch"); mainline U-Boot reads FAT and exFAT + (implementation-path §6.3); the factory SPL reads FAT on partition 1 only (boot-chain §8), which + fixes p1's role either way. The rewritten in-kernel `loop=` patch also compile-verifies on + aarch64, so both routes stay open, but the initramfs is the plan. +- **Consequences.** A new aarch64 stage-1 initramfs stack and its QEMU test path are owed before + the switch; `genimage-sdcard.cfg`, `extlinux.conf`'s kernel arguments and the card checker + change together. The DE25 inherits the DE10's `linux.img` update flow and downloader contract + unchanged. This closes §8 Q7 of the implementation path. +- **Re-open if.** The first hardware boot shows U-Boot cannot read the FAT boot files reliably, + or Main_MiSTer's DE25 port needs a layout the loop root cannot provide. + +### D12 — Firmware parity with the DE10; seccomp stays off + +**Decision (owner, 2026-09-03).** The DE25 image ships the DE10's `linux-firmware` selection +(the 29 `BR2_PACKAGE_LINUX_FIRMWARE_*` choices plus `linux-firmware-extra`), so a dongle that +works on a DE10 works on a DE25. The mechanism is a shared `image-common` fragment included by +both boards' image stacks and never by the kernel-only stack (rule 4 of +[`buildroot-config.md`](../buildroot-config.md) §10). `CONFIG_SECCOMP` stays off, exactly as on +the DE10; the obligation that travels with it — `BR2_PACKAGE_OPENSSH_SANDBOX` must be off when +openssh joins the image — is accepted, not argued. + +- **Evidence.** The shared kernel fragment (`board/mister/common/linux-mister.fragment`) already + builds every Wi-Fi/Bluetooth driver the DE10 has; without the blobs they bind and fail at + `request_firmware()` ([`de25-kernel-config.md`](../de25-kernel-config.md) §7.1). Cost measured + on the DE10: ~52 MB installed. +- **Consequences.** This is the first shared *package* content between the boards and the + natural home for more as the DE25 grows out of the bare developer OS (ADR 0027 Decision 6 is + refined, not reversed: still no MiSTer binaries). The DE25 rootfs size follows the measurement. +- **Re-open if.** The DE25 ever ships a Wi-Fi/Bluetooth driver set that differs from the DE10's. + ## Decisions deliberately left open None of these is decided here. Each is named so it is not mistaken for settled. -1. **p2's filesystem, and therefore whether the kernel lives on p1 or p2** (§8 Q7, §6.3). D3 fixes the +1. ~~**p2's filesystem, and therefore whether the kernel lives on p1 or p2**~~ **Decided 2026-09-03 — D11** (two-stage target, plain ext4 interim). Original text kept for the record: (§8 Q7, §6.3). D3 fixes the partition count and p1's FAT type only; mainline U-Boot now reads exFAT (`CONFIG_FS_EXFAT`) **[V]**, so this is a project decision, not a capability gap. 2. **Whether the DE10 and DE25 defconfigs are refactored into a shared base + per-board fragments.** diff --git a/docs/firmware-parity.md b/docs/firmware-parity.md index 269a221..ede6ec0 100644 --- a/docs/firmware-parity.md +++ b/docs/firmware-parity.md @@ -61,7 +61,8 @@ Config.in reasoning: > The original P3.3 run measured 56 present / 10 missing. `brcm/BCM20702A1-0b05-17cb.hcd` > was subsequently sourced by `package/bcm20702-firmware` (P3.14, -> `BR2_PACKAGE_BCM20702_FIRMWARE=y` at `configs/fragments/de10nano-image.fragment`; +> `BR2_PACKAGE_BCM20702_FIRMWARE=y` at `configs/fragments/image-common.fragment` +> (it was in `de10nano-image.fragment` until 2026-09-03, `docs/buildroot-config.md` §12.2); > `scripts/ci-tests.sh` fails the build if it is absent from the image), which is what > moves present 56→57 and flagged 2→1. The obsolete count was independently a miscount: > that section lists **seven** files, not six. @@ -140,7 +141,13 @@ driver exists to use them (harmless unused bytes, not a gap). ## defconfig changes -`configs/fragments/de10nano-image.fragment`, added after the P3.2 block: +These lines were added to `configs/fragments/de10nano-image.fragment` after +the P3.2 block. **Since 2026-09-03 they live in +`configs/fragments/image-common.fragment`** — the layer shared by every board's +image stack — because the DE25-Nano image adopted the same set for parity +(owner decision; `docs/buildroot-config.md` §12, and §12.1 for the full +sub-option table this document feeds). The symbols and their rationale are +unchanged by that move; only the file holding them changed. ``` BR2_PACKAGE_LINUX_FIRMWARE=y