DE25-Nano wave 2: U-Boot/TF-A, bootable card image, kernel diet, 7.2.3 (stacked on #137) - #138
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
There are concrete correctness issues in the new DE10 fragment no-op checker (missing Kconfig path) and in the Makefile’s DE25_ALLOW_NO_UBOOT behavior (currently ineffective/inconsistent with the documented post-image escape hatch).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR advances the DE25-Nano bring-up (“wave 2”) by adding a Buildroot-built TF-A + U-Boot FIT, generating a bootable SD card image, and restructuring the DE25 kernel config to use a minimal base plus a shared MiSTer driver fragment (while bumping the DE25 kernel pin to 7.2.3).
Changes:
- Add DE25 SD-card image assembly + a fail-closed image verifier (
sdcard-de25.img, with strict FAT allow-listing and FIT validation). - Introduce DE25 bootloader build inputs (TF-A BL31 + U-Boot
u-boot.itb) plus U-Boot DTS/fragment configuration emphasizing “no QSPI write” posture. - Replace DE25 “arm64 defconfig + delta” with a pinned minimal
linux.configand new sharedboard/mister/common/linux-mister.fragment, plus a no-op enforcement script.
File summaries
| File | Description |
|---|---|
| scripts/check-sdcard-de25.sh | New static verifier for sdcard-de25.img (partitioning, FAT allow-list, FIT contents, extlinux args, ext4 sanity). |
| scripts/check-kernel-fragment-noop.sh | New enforcement script intended to prove the shared kernel fragment is a no-op on the DE10 kernel tree. |
| README.md | Documentation update clarifying portability/maintenance aspects of the loop/attach rewrite discussion. |
| Makefile | DE25 build target now asserts boot artifacts (BL31/FIT) and card image creation; help text updated. |
| docs/de25-sdcard.md | New documentation for DE25 SD layout, build/write process, and first-boot checklist. |
| docs/de25-nano-tasks.md | Wave-2 status recording, updated remaining task list. |
| docs/buildroot-config.md | DE25 kernel-pin bump notes + updated DE25 section reflecting bootloader/card/kernel-config changes. |
| configs/fragments/golden.sha256 | Update golden hash for the de25nano fragment stack. |
| configs/fragments/de25nano.fragment | Extend DE25 Buildroot fragment with TF-A/U-Boot/card/host-tooling + kernel config switch. |
| board/mister/de25nano/uboot.fragment | New U-Boot config fragment focusing on FAT env, disabling QSPI/MTD/UBI paths, and avoiding SPL handoff dependencies. |
| board/mister/de25nano/uboot-dts/* | New U-Boot board DTS + -u-boot.dtsi for console/MMC/FIT/binman shaping. |
| board/mister/de25nano/post-image.sh | New post-image script generating extlinux.conf, running genimage, and invoking the SD-card checker. |
| board/mister/de25nano/patches/uboot/* | New U-Boot hash and local patch to guard MTD env vars when MTD is compiled out. |
| board/mister/de25nano/patches/arm-trusted-firmware/* | New TF-A hash for the Buildroot-generated archive. |
| board/mister/de25nano/linux.fragment | Removed DE25 kernel delta fragment (replaced by pinned base config + shared fragment). |
| board/mister/de25nano/linux.config | New pinned minimal DE25 kernel base config. |
| board/mister/de25nano/linux-patches/README.md | Update patch-series docs for 7.2.3 re-verification notes. |
| board/mister/de25nano/genimage-sdcard.cfg | New genimage config for DE25 SD layout (MBR, FAT32 boot, ext4 rootfs). |
| board/mister/common/linux-mister.fragment | New shared, arch-neutral MiSTer driver/feature kernel fragment (intended to be DE10-no-op). |
| .github/workflows/lint.yml | Include per-board post-image.sh in shellcheck + executable-bit checks. |
Review details
- Files reviewed: 24/24 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
… exists Copilot review on #138: the bl31.bin/u-boot.itb assertions ran unconditionally, so the documented kernel/rootfs-only escape hatch could never succeed, and the card branch reported 'no u-boot.itb' whenever the variable was set even if a FIT had been built. Now the env var only matters when u-boot.itb is absent: with a FIT present the recipe behaves exactly as without the variable. check-kernel-fragment- noop.sh: comment explaining that exported srctree is what lets conf find Kconfig from the scratch dirs (the check runs and passes). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
board/mister/de25nano/genimage-sdcard.cfg: MBR, p1 FAT32 'DE25BOOT' (u-boot.itb, Image, dtb, extlinux/extlinux.conf), p2 = rootfs.ext4 verbatim, no 0xA2 partition (that is the Cyclone V BootROM contract). MBR chosen fail-closed: the only observed DE25 boot is from an MBR card; the factory SPL contract names no partition-table symbol. post-image.sh generates extlinux.conf, runs genimage, fails without u-boot.itb unless DE25_ALLOW_NO_UBOOT=1. scripts/check-sdcard-de25.sh asserts table type, partition types/sizes/labels, the four p1 files, extlinux directives and kernel args, ext4 label/features/fsck, and the absence of any QSPI reference; dry run passes, the DE10 card is rejected with nine failures. docs/de25-sdcard.md records the interim p2 decision (ext4 rootfs directly), write procedure and first-boot checklist. lint.yml's shipped-script lists gain post-image.sh (covers the DE10's too, which was unlisted). Defconfig/Makefile wiring lands with the U-Boot track, which owns those files. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
board/mister/common/linux-mister.fragment (409 lines): the arch-neutral MiSTer driver/feature set lifted from the DE10's resolved config — HID and gamepads, USB, Bluetooth, the Wi-Fi driver set, sound, filesystems, netfilter, loop/overlay. Proven a NO-OP on the DE10 6.18.48 tree (zero redefinitions, resolved config identical) by the new scripts/check-kernel-fragment-noop.sh, which also passes on the 7.2.2 DE25 tree. board/mister/de25nano/linux.config (51 lines): minimal arm64 + Agilex 5 base in the DE10 style. Base and fragment share no symbol; all 460 lines survive olddefconfig. Measured on a kernel-only build in a scratch output dir: =m symbols 1,481 -> 92 (DE10: 92); installed modules 90 MB -> 2.4 MiB; Image 41.9 MB -> 20.7 MB. The two boards' installed module name sets are identical. The wave-1 arm64-defconfig kernel had joydev, uinput, hidraw, HID_NINTENDO/PLAYSTATION, xpad and HZ_1000 all OFF — invisible in a green build. docs/de25-kernel-config.md: per-subsystem rationale, what is deliberately off, the symbols not shared and why (FB_MISTER, audio, CMA, cpufreq...), the per-bump re-check list, and two obligations: openssh needs BR2_PACKAGE_OPENSSH_SANDBOX off once added (SECCOMP is off as on the DE10), and the DE25 selects no linux-firmware yet. The defconfig switch (custom config + fragment, delete de25nano/linux.fragment) lands with the U-Boot track's defconfig edit. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
… wired; kernel diet switched in u-boot.itb built by binman from mainline, shape-verified with dumpimage against the factory SPL contract: uboot @0x80200000, atf (BL31) @0x80000000 = entry, fdt-0, config board-0 default, crc32 only — no rsa, no required keys, addresses disjoint from the 0x82000000 FIT staging area. Reproducible: two runs byte-identical. QSPI cannot be written from this U-Boot: ENV_IS_IN_UBI, CMD_SF, CMD_MTD, DM_SPI_FLASH, MTD_UBI, ENV_IS_IN_SPI_FLASH/NAND are absent from the resolved config (deps unmet); CADENCE_QSPI, MTD, CMD_UBI, HANDOFF off; ENV_IS_IN_FAT 0:1 is the only env location. Notably stock's BOOTENV_DEV_QSPI contains 'saveenv && ubi part root' inside the default boot command — gated on CMD_SF, which is off, so the target and the string are gone; boot_targets=mmc0 only. HANDOFF off because dram_init would otherwise require a bloblist from OUR SPL at OUR BLOBLIST_ADDR, but the factory SPL runs; /memory declared 1 GiB. Board DTS for U-Boot (uboot-dts/): socdk aliases serial0 to uart0 and the DE25 console is uart1, so a minimal board dts + -u-boot.dtsi; mmc0 alias pinned; conservative mmc (4-bit, 50 MHz, no UHS). One carried, upstreamable patch guards CFG_EXTRA_ENV_SETTINGS's mtdids/mtdparts reference for MTD-less configs. §8 Q6 closes negative: '# CONFIG_SPL is not set' removes BINMAN and the FIT; SPL is compiled but nothing of it ships. Hashes: U-Boot tarball .sig verified (Tom Rini); TF-A tag anchored TOFU on its commit from two clones. Defconfig: also switches the kernel to board/mister/de25nano/ linux.config + board/mister/common/linux-mister.fragment (c2ab0c9) and deletes de25nano/linux.fragment; wires the card image (host genimage/ mtools/dosfstools, post-image.sh). make de25 asserts Image, dtb, rootfs.ext4, bl31.bin, u-boot.itb and sdcard-de25.img; stat follows symlinks. Verified: make de25 green, check-sdcard-de25.sh all assertions passed on the real artefacts. docs/de25-uboot.md has the fragment rationale, dumpimage listing, QSPI audit table, boot flow and first-boot serial expectations. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
…k one is not Compile-verified: 0100 applied to pristine 6.18.48, ARCH=arm64 with the DE25 toolchain, init/do_mounts.o and drivers/block/loop.o build clean. It does not apply to 7.2.2 (one context hunk: load_ramdisk= removed), which is version drift, not an architecture problem. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
…ct, bloblist off Fable boot-path review: with no cdns,phy-* values, U-Boot proper drove the SD PHY with sdhci-cadence6.c's built-in defaults, which no Agilex 5 board has been validated with, at 50 MHz high-speed — the factory SPL reads u-boot.itb with vendor timing and our driver then re-inits the PHY. Now: the socdk-u-boot.dtsi sd-ds/sd-hs PHY delays (SoC-level, not the board vqmmc fact) copied verbatim, cap-sd-highspeed dropped, max-frequency 25 MHz. de25-uboot.md §5.1 gives the symptoms, the diagnosis order and the one-line lift once dd of the card is clean. CONFIG_BLOBLIST off: its fixed 0x7e000+0x1000 window overlapped TF-A's secondary-CPU handshake words at 0x7EFF0/0x7EFF8; unused with HANDOFF off; build verified, u-boot.itb still produced (728,176 B, crc32-only, addresses unchanged). Docs: linux_qspi_enable IS run by board_prep_linux() — the argument is the CADENCE_QSPI gate; card ships no uboot.env; BL31 prints on UART0, so no NOTICE: BL31 lines are expected on the header UART. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
Fable boot-path review: a FIT recompiled with sha256,rsa2048 + required keys passed the checker, as did 4 KiB of urandom named u-boot.itb, and a stray boot.scr (which distro boot executes the moment extlinux fails) or uboot.env was merely 'informational'. Now: p1's u-boot.itb must be byte-identical to images/u-boot.itb, dumpimage must show uboot @0x80200000, atf @0x80000000, fdt-0, a default config and a crc32 signature algo, and the decompiled FIT must contain no rsa/required/sha<n>; p1 may hold nothing beyond the four expected entries. dumpimage/dtc resolved from the Buildroot host dir, exit 2 if absent. Real card passes; m1 (uboot.env), m2 (rsa FIT), m3 (garbage FIT) and m5 (boot.scr with sf erase) all fail. docs/de25-sdcard.md: extlinux search path settled [V], BL31 silence on uart1 expected, uboot.env question settled: no. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
… the diet
Renovate's rt bump moved board/mister/de10nano/patches/linux/linux.hash from
7.2.2 to 7.2.3. That file is the DE25's hash registry too (the board's
patches/linux/linux.hash is a relative symlink into it), and the sync script
REPLACES the 7.2.y line rather than adding one -- so the hazard
docs/buildroot-config.md filed as a "known follow-up" stopped being
hypothetical. configs/fragments/de25nano.fragment already carries 7.2.3 from
the rebase base; this commit makes the rest of the tree say so and, more to the
point, re-runs the evidence at the new pin instead of assuming it carried over.
Re-verified on a linux-dirclean rebuild against a freshly downloaded,
hash-verified linux-7.2.3.tar.xz (make de25, green, card checker included):
- carried patch series: 34/34 applied at Buildroot's patch -F0, zero fuzz,
zero rejects. 79 hunks relocated by line OFFSET only, which -F0 permits
(-F caps context fuzz, not displacement).
- kernel diet: 460 asked-for symbols (51 base + 409 shared fragment), ZERO
dropped from the resolved config; zero merge_config redefinitions.
- 92 =m symbols / 91 installed .ko.xz / 2,565,868 B of modules -- unchanged,
and the installed module NAME SET is still exactly the DE10's (91 vs 91,
empty diff both directions against output/build/linux-6.18.48).
- check-kernel-fragment-noop.sh still PASSes on the DE10 tree.
- u-boot.itb and bl31.bin are byte-identical to the 7.2.2 build, as they must
be: nothing in the bootloader half depends on the kernel version. The board
.dtb is byte-identical too, so mainline's socfpga_agilex5.dtsi did not move
in the point release. Image differs (a stable-tree release changes code)
while coincidentally keeping the same length.
All four golden hashes are unchanged: the normalisation deliberately drops the
two kernel-version symbols, so a pin bump must not move them, and does not.
Doc changes are the pin statements only. Dated measurements keep their 7.2.2
provenance and say so; the dtbs_check warning count was NOT re-run at 7.2.3 and
is labelled accordingly. Nothing here has been on hardware at 7.2.3.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
The shared kernel fragment sets MODULE_COMPRESS_XZ but the DE25 stack did not set BR2_PACKAGE_HOST_KMOD_XZ, so build-time depmod silently produced a 0-line modules.dep and a 1-line modules.alias — the exact trap docs/buildroot-config.md §3.5 records for the DE10. Found by the rebase pass. After host-kmod-dirclean + make de25: modules.dep 91 lines, modules.alias 1,204, card checker passes. Golden refreshed for the de25nano stack only. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
… exists Copilot review on #138: the bl31.bin/u-boot.itb assertions ran unconditionally, so the documented kernel/rootfs-only escape hatch could never succeed, and the card branch reported 'no u-boot.itb' whenever the variable was set even if a FIT had been built. Now the env var only matters when u-boot.itb is absent: with a FIT present the recipe behaves exactly as without the variable. check-kernel-fragment- noop.sh: comment explaining that exported srctree is what lets conf find Kconfig from the scratch dirs (the check runs and passes). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
The previous commit's if-block began with a literal '@' inside a continued shell chain, which make passed through as a command (exit 2). Verified: make -n de25 | bash -n clean for both variants, make de25 green end to end. Adds the srctree comment the previous message described. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
echo "" \ + fi parsed as one command; now echo ""; \ then fi. Proven: make -n de25 | bash -n clean for both variants, make de25 green end to end (bl31, FIT, card all reported; checker passes). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm
ed64869 to
2d0b32d
Compare
Summary
Wave 2 of the DE25-Nano bring-up, stacked on #137 (config fragments). Everything a machine without the board can do toward a card that is safe to put in a borrowed DE25-Nano.
make de25is green end to end and emitssdcard-de25.img. Nothing here has run on hardware.u-boot.itbbuilt by binman,dumpimage-verified against the factory SPL contract (crc32 only, no keys, addresses disjoint). QSPI write paths compiled out (CMD_SF/MTD/UBI/ENV_IS_IN_UBIabsent from the resolved config, confirmed in the binary's strings). Stock's default boot command carried asaveenv && ubi part rootleg; gone withCMD_SF.HANDOFFandBLOBLISToff because the factory SPL, not ours, runs first. SD PHY: SoCDK-validated delays, default-speed 25 MHz for first contact.docs/de25-uboot.md.DE25BOOT(u-boot.itb,Image, dtb,extlinux/extlinux.conf), p2 = ext4 rootfs written directly (interim p2 decision).scripts/check-sdcard-de25.shopens the FIT, allow-lists p1, and rejects the DE10 card and every mutated card.docs/de25-sdcard.md.board/mister/common/linux-mister.fragment(the arch-neutral MiSTer driver set) + minimalde25nano/linux.config. 1,481 → 92 modules,Image41.9 → 20.7 MB; installed module name set identical to the DE10's. The fragment is proven a no-op on the DE10 kernel byscripts/check-kernel-fragment-noop.sh.docs/de25-kernel-config.md.-F0, 460/460 config symbols survive.configs/fragments/de25nano.fragment; rationale indocs/buildroot-config.md§6. Only the de25nano golden line changed.Reviews already applied
Two Fable adversarial passes ran before this PR: the boot path (no brick-class or boot-blocking finding; QSPI surfaces verified closed in the built U-Boot, TF-A and kernel) and the config refactor (in #137). Their fixes are in the commits.
For the borrowed-board owner
The QSPI must be at the factory image (our card relies on the factory SPL). First-boot notes: no
NOTICE: BL31lines will appear on the header UART (TF-A prints on UART0); capture the SPL'sDDR:lines; ifRetrieving file: /Imagestalls, the SD PHY timing is the first knob (de25-uboot.md§5.1). Full checklist indocs/de25-nano-tasks.md→ "Testing on a borrowed board".Open owner decisions
p2 filesystem / two-stage layout; DE25
linux-firmwareselection (the shared fragment builds the Wi-Fi/BT drivers that will request it); patch 0002 (audio); a Renovate manager for the DE25 kernel pin; upstream submission of 0101/0102.🤖 Generated with Claude Code
https://claude.ai/code/session_01FYjrnzEEu4HzJSPWNAaRvm