Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
702 changes: 74 additions & 628 deletions .github/workflows/release.yml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ work/
output*/
dl/
dist/
release-work/
*.img
*.7z
venv/
Expand Down
2 changes: 1 addition & 1 deletion docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Nine workflows, two composite actions, one Buildroot recipe. A build is
|---|---|---|
| `build.yml` | push to master, PRs | `gate` (skip doc-only changes) → `lint-config` (kernel patch headers, `scripts/check-defconfigs.sh`) → `build` (the action below, then `scripts/ci-tests.sh` via `verify-image`) → `status` |
| `lint.yml` | push, PRs | actionlint on the workflows, shellcheck on every script and on the composite actions' `run:` bodies |
| `release.yml` | `v*` tags | the same build, then: stage assets, fetch + verify the pinned stock archive, assemble `release_YYYYMMDD.7z` and round-trip it under the pinned ARM `7za`, build `sdcard.img.xz`, publish a draft release with provenance, submit the SBOM to the dependency graph |
| `release.yml` | `v*` tags | the same build, then `scripts/mk-release.sh` (stage assets, fetch + verify the pinned stock archive, assemble `release_YYYYMMDD.7z` and round-trip it under the pinned ARM `7za`, `SHA256SUMS`) and `scripts/mk-sdcard.sh`; then a draft release with provenance and the SBOM to the dependency graph. Runs locally: `MISTER_VERSION=… scripts/mk-release.sh` with the `STOCK_*` pins in the environment |
| `reproducibility.yml` | manual | two independent builds of one commit, hashes compared |
| `renovate-hash-sync.yml` | Renovate PRs | refresh the companion hash of whatever pin the PR bumped (each case is one `scripts/hash-sync-*.sh`) |
| `renovate-validate.yml` | push, PRs | `renovate.json` validates |
Expand Down
6 changes: 5 additions & 1 deletion docs/de25-nano-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,11 @@ Remaining, in unblock order:
pointed to from the DE25 series; the aarch64 leg's `symlink` case is the acceptance test —
it is the ONLY place 0031-on-7.x is executed rather than compiled.~~ **DONE 2026-09-06:**
beta-local copy, DE25 series relinked, aarch64 leg 8/8, arm compile clean on the RT config.
Remaining: the first `ln -s` on an RT-booted DE10 (32-bit 7.x is still compile-only).
~~Remaining: the first `ln -s` on an RT-booted DE10 (32-bit 7.x is still compile-only).~~
**2026-09-11:** executed as 32-bit ARM by `scripts/test-initramfs.sh --kernel rt` (7.2.4,
`symlink`/`exfat`/`fsck-request` pass; the 6.18-form patch on 7.2.4 reproduces the Oops),
after the rig, still on a pre-rewrite RT 7.2.3, panicked on the Arcade Organizer's first
symlink (ADR 0002 §8b). Hardware boot of the fixed RT kernel still owed.
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).
Expand Down
15 changes: 13 additions & 2 deletions docs/decisions/0002-initramfs.md
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,19 @@ device directly and never sees a dirty bdev buffer), and does the `valid_size` /
`zeroed_size` / `i_size` bookkeeping the write path would have done. Applies at `-F0` to
pristine 7.2.3; compiles for arm with the RT `.config` and for arm64 with the DE25's; the
aarch64 leg is **8/8** with the `symlink` case's full assertion set (hot+cold round-trip,
`DT_LNK`, the create+unlink cluster-leak tripwire via `statvfs`, host-side fsck-clean). What
remains unexecuted is 0031 on 32-bit 7.x — the RT kernel on a real board.
`DT_LNK`, the create+unlink cluster-leak tripwire via `statvfs`, host-side fsck-clean).

**2026-09-11 — the 32-bit gap closed, the hard way first.** The maintainer's rig was still on
an RT 7.2.3 kernel built 2026-09-05, before the rewrite shipped there; `update_all.sh`'s
Arcade Organizer created its first `.mra` symlink on `/media/fat` and the board Oopsed
exactly as above (`PC is at 0x0`, `LR is at page_symlink+0x90`, from `exfat_symlink`; captured
by netconsole) and, with `CONFIG_PANIC_ON_OOPS=y` + `panic=15`, rebooted 17 s later. The
same day `scripts/test-initramfs.sh --kernel rt` was added: the DE10 leg built at the RT pin
(`BR2_PACKAGE_LINUX_RT_VERSION`) with `linux-patches-beta/0031`, on `qemu-system-arm`, so the
rewrite is executed as 32-bit ARM. Result at 7.2.4: `symlink`, `exfat`, `fsck-request` pass;
the negative control (the 6.18-form patch on the same 7.2.4 source) reproduces the rig's
Oops in QEMU, so the leg detects the bug it exists for. `ci-tests.sh` runs it after the
DE10 leg. What remains is the ordinary hardware claim: a board boot of the fixed RT kernel.

## 8c. Amendment 2026-09-11 — stage 1 becomes a package of the main build (ADR 0030)

Expand Down
2 changes: 1 addition & 1 deletion docs/rt-beta-kernel.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ card, and nothing on the card referenced it), and deliberately NOT inside
| **Module-tree merge into the one linux.img** | ✅ **green** — the row's "first green run pending" was overtaken by CI run 29758320422 (2026-07-20, rc4: `build-kernel` + `build` both green, so the merge assert ran). Re-verified locally on rc5 (2026-07-28): after `make rt`, a `make all` produced `output/target/usr/lib/modules/` holding exactly `6.18.40` and `7.2.0-rc5` — two trees, no stale third — and `linux.img` passed every `check-linux-img.sh` assertion (512 MiB, pinned UUID/hash-seed, the 14-feature stock-derived set, ADR 0015 ssh-key checks) |
| **RT kernel boots on the DE10-Nano** | ⚠️ **NOT on the currently pinned 7.2 — re-opened 2026-08-17 by the rc7 → 7.2 bump.** ✅ **CONFIRMED 2026-07-20 on 7.2-rc4**, which booted and ran MiSTer on real hardware. That retired the single biggest open risk on the variant, and it is how the `0037` DualSense regression was caught: booting far enough to use a controller is what exposed the shifted PS5 button map (§7 item 3). ✅ **RE-CONFIRMED 2026-08-14 on 7.2-rc7** — the Wave-1 hardware pass ran on a `7.2.0-rc7 SMP PREEMPT_RT` kernel carrying `0043`, and the doorbell nodes enumerated and delivered events (that pass is also where H-1 and H-2 were found). Boot is a **per-version claim** and every bump re-opens it, which is exactly the state this row is in now: 7.2 final is patch-verified (**40/40** at `-F0`), DTS-verified, and **built on the whole 40-entry series** (`make rt` green from clean, 2026-08-17 — see the build rows above), but it has **not been booted**. Everything that can be checked without hardware has been checked and passed; none of it is a boot. This ✅ covers rc4 and rc7 and nothing else. It also does **not** cover `0044`, `0045`, `0046` or the re-added `0038`–`0042`: none were in the series when the rc7 kernel was built, and all six have since been built but never booted — §2, §8, §9 |
| **vsync/IRQ-40 latency under RT threaded IRQs** | ❌ **unproven** (the point of the exercise) — boot and general operation are confirmed, but the latency measurement that motivates RT has not been taken |
| **Patch 0031 (exFAT Samsung symlinks) on 7.x** | ✅ **FIXED 2026-09-06 — after being found BROKEN the same day**, not by this variant but by the DE25's aarch64 initramfs QEMU leg (`scripts/test-initramfs.sh --board de25nano`), the first thing ever to EXECUTE 0031 on a 7.x kernel: `exfat_symlink()` → `page_symlink()` → `a_ops->write_begin` is NULL on 7.x exFAT (iomap; no `write_begin`/`write_end`) → Oops, `pc: 0x0`, on the first symlink created. `linux-patches-beta/0031` WAS a symlink to the shared 6.18 file, so this kernel had the same crash on any `ln -s` on `/media/fat` (reading existing links was fine). The "applies at -F0" and "compiles" rows above were true and insufficient. Now a **beta-local re-anchored copy** (the fifth): `exfat_symlink_write_target()` allocates clusters via 7.x's `exfat_map_cluster()`, writes the sectors through buffer heads, `sync_blockdev_range()`s them (iomap reads go straight to the device), and does the `valid_size`/`zeroed_size`/`i_size` bookkeeping; the DE25 series links to this copy. Verified: applies at `-F0` to pristine 7.2.3 (12/12 hunks), **compiles for arm with this variant's own `output-rt` `.config`** (`fs/exfat/`, zero warnings), and the aarch64 leg's `symlink` case passes — hot+cold round-trip, `DT_LNK`, the create+unlink cluster-leak tripwire, fsck-clean (ADR 0002 §8b). Still not executed on 32-bit ARM: the DE10 leg boots 6.18 only, so the first `ln -s` on an RT-booted board is the remaining proof. |
| **Patch 0031 (exFAT Samsung symlinks) on 7.x** | ✅ **FIXED 2026-09-06 — after being found BROKEN the same day**, not by this variant but by the DE25's aarch64 initramfs QEMU leg (`scripts/test-initramfs.sh --board de25nano`), the first thing ever to EXECUTE 0031 on a 7.x kernel: `exfat_symlink()` → `page_symlink()` → `a_ops->write_begin` is NULL on 7.x exFAT (iomap; no `write_begin`/`write_end`) → Oops, `pc: 0x0`, on the first symlink created. `linux-patches-beta/0031` WAS a symlink to the shared 6.18 file, so this kernel had the same crash on any `ln -s` on `/media/fat` (reading existing links was fine). The "applies at -F0" and "compiles" rows above were true and insufficient. Now a **beta-local re-anchored copy** (the fifth): `exfat_symlink_write_target()` allocates clusters via 7.x's `exfat_map_cluster()`, writes the sectors through buffer heads, `sync_blockdev_range()`s them (iomap reads go straight to the device), and does the `valid_size`/`zeroed_size`/`i_size` bookkeeping; the DE25 series links to this copy. Verified: applies at `-F0` to pristine 7.2.3 (12/12 hunks), **compiles for arm with this variant's own `output-rt` `.config`** (`fs/exfat/`, zero warnings), and the aarch64 leg's `symlink` case passes — hot+cold round-trip, `DT_LNK`, the create+unlink cluster-leak tripwire, fsck-clean (ADR 0002 §8b). Still not executed on 32-bit ARM: the DE10 leg boots 6.18 only, so the first `ln -s` on an RT-booted board is the remaining proof. **2026-09-11: executed as 32-bit ARM** — the rig (still on a pre-rewrite RT 7.2.3 from 2026-09-05) panicked on `update_all.sh`'s first Arcade Organizer symlink (netconsole: `PC is at 0x0`, `LR is at page_symlink+0x90`; `CONFIG_PANIC_ON_OOPS=y` + `panic=15` rebooted it), and `scripts/test-initramfs.sh --kernel rt` now builds the DE10 QEMU leg at the RT pin with `linux-patches-beta/0031`: 7.2.4 passes `symlink`/`exfat`/`fsck-request`; the 6.18-form patch on the same source reproduces the Oops. Only a hardware boot of the fixed kernel remains. |
| `rtw88_8814au` firmware (`rtw88/rtw8814a_fw.bin`) present | ✅ ships via `BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW88` |

## 7. What is left
Expand Down
130 changes: 130 additions & 0 deletions mk-release.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@

==> mk-release: reading /MiSTer.version from /mnt/source/Buildroot_MiSTer-vanilla/output/images/linux.img
/MiSTer.version=260904 -> RELEASE_DATE=20260904

==> mk-release: staging image assets into /mnt/source/Buildroot_MiSTer-vanilla/dist
legal-info.tar.gz: 6923165 bytes (6 MiB)

==> mk-release: fetching + verifying the pinned stock release
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00:01 0100 80.00M 100 80.00M 0 0 56.07M 0 00:01 00:01 56.10M100 80.00M 100 80.00M 0 0 56.07M 0 00:01 00:01 56.10M100 80.00M 100 80.00M 0 0 56.07M 0 00:01 00:01 56.10M
fetch-stock: fetched volume 1: https://raw.githubusercontent.com/MiSTer-devel/SD-Installer-Win64_MiSTer/76fd6f4ced6350b0ad56a7013b41526f47e3a2fb/release_20260907.7z.001
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 0100 32.47M 100 32.47M 0 0 35.98M 0 0100 32.47M 100 32.47M 0 0 35.97M 0 0100 32.47M 100 32.47M 0 0 35.97M 0 0
fetch-stock: fetched volume 2: https://raw.githubusercontent.com/MiSTer-devel/SD-Installer-Win64_MiSTer/76fd6f4ced6350b0ad56a7013b41526f47e3a2fb/release_20260907.7z.002
fetch-stock: 2 volume(s) joined -> /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock_release.7z
verify-stock: /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock_release.7z verified -- size/MD5/SHA-256/internal-CRC all match.

7-Zip 26.00 (x64) : Copyright (c) 1999-2026 Igor Pavlov : 2026-02-12
64-bit locale=C.UTF-8 Threads:32 OPEN_MAX:1048576, ASM

Scanning the drive for archives:
1 file, 117936766 bytes (113 MiB)

Extracting archive: /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock_release.7z
--
Path = /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock_release.7z
Type = 7z
Physical Size = 117936766
Headers Size = 765
Method = LZMA2:26 LZMA:20 BCJ2
Solid = +
Blocks = 2

Everything is Ok

Folders: 3
Files: 13
Size: 402464951
Compressed: 117936766
extract-stock: extracted files/linux/* from /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock_release.7z -> /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock-extract
verify-uboot: uboot.img and updateboot confirmed byte-identical to stock.

==> mk-release: assembling files/linux and packing release_20260904.7z
7za
MidiLink.INI
_samba.sh
_user-startup.sh
_wpa_supplicant.conf
gamecontrollerdb
linux
linux.img
mt32-rom-data
ppp_options
soundfonts
u-boot.txt_example
uboot.img
updateboot
zImage_dtb
wrote /mnt/source/Buildroot_MiSTer-vanilla/dist/release_20260904.7z (84632824 bytes)

==> mk-release: round-tripping the archive under the pinned ARM 7za (qemu-arm)
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0100 454.6k 100 454.6k 0 0 578.2k 0 0100 454.6k 100 454.6k 0 0 578.1k 0 0100 454.6k 100 454.6k 0 0 578.0k 0 0
fetch-7za: pinned ARM 7za fetched and verified -> /mnt/source/Buildroot_MiSTer-vanilla/release-work/7za

7-Zip (a) [32] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=C.UTF-8,Utf16=on,HugeFiles=on,32 bits,32 CPUs LE)

Scanning the drive for archives:
1 file, 84632824 bytes (81 MiB)

Testing archive: /mnt/source/Buildroot_MiSTer-vanilla/dist/release_20260904.7z
--
Path = /mnt/source/Buildroot_MiSTer-vanilla/dist/release_20260904.7z
Type = 7z
Physical Size = 84632824
Headers Size = 607
Method = LZMA2:28
Solid = +
Blocks = 1

Everything is Ok

Folders: 5
Files: 14
Size: 550398955
Compressed: 84632824

7-Zip (a) [32] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=C.UTF-8,Utf16=on,HugeFiles=on,32 bits,32 CPUs LE)

Scanning the drive for archives:
1 file, 84632824 bytes (81 MiB)

Extracting archive: /mnt/source/Buildroot_MiSTer-vanilla/dist/release_20260904.7z
--
Path = /mnt/source/Buildroot_MiSTer-vanilla/dist/release_20260904.7z
Type = 7z
Physical Size = 84632824
Headers Size = 607
Method = LZMA2:28
Solid = +
Blocks = 1

Everything is Ok

Folders: 3
Files: 14
Size: 550398955
Compressed: 84632824
roundtrip: pinned ARM 7za: both 't' and 'x -y ... files/linux/*' succeeded.
verify-uboot: uboot.img/updateboot survive our archive's create+pinned-7za-extract round trip unchanged.
verify-layout: archive layout matches docs/downloader-contract.md / docs/reference-materials.md.

==> mk-release: SHA256SUMS
cbbc891b430fec1aa4e926f6cedfd129c66e934d8c312afd482f6fbb9c26a0e1 release_20260904.7z
b10f7c33466af0f20b17b5d47062686a5f7775c4aa4053b51a4957fdcc4639ef linux.img
012a1dc459a6b3cbd3ef038abee2121eecd3b43fcc81e7c6454aaf22419d5eef zImage_dtb
d266dd5111edc581b1352c1b07847145c38686e896fadbcf898696c4eef9dd99 zImage_dtb-rt
b5e9cc0cb85f6250eaf0e150b975fab5b1466c31f27f59fe917d9c86996d9ebc buildroot.config
7c0909f0e02084951e9347f3589fe9e2228d54833681d885d24c464d8f6a8a6b linux.config
907b63c0adb62aecf3344a12958a5b45caf8e56b78498eba180d6f0991bb5a48 linux-rt.config
b6da2bf61e26858209e5936ea419bbcebe941dd4a604957c0a2f623a439c30a0 legal-info.tar.gz

==> mk-release: done: /mnt/source/Buildroot_MiSTer-vanilla/dist ready; stock archive kept at /mnt/source/Buildroot_MiSTer-vanilla/release-work/stock_release.7z for mk-sdcard.sh
exit=0
Expand Down
24 changes: 24 additions & 0 deletions scripts/ci-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,30 @@ else
fi
fi

# The same /init on the DE10's RT kernel series (7.2.y): the three cases that
# exercise the exfat driver, because 7.x exfat is iomap-based and board patch
# 0031 (Samsung-format symlinks, ADR 0019) is a separate re-anchored copy
# there (linux-patches-beta/). Its only other executions are aarch64 (the
# DE25 leg); the DE10-Nano runs it as 32-bit ARM, and the first field `ln -s`
# on an RT-booted board Oopsed (2026-09-11) on the pre-rewrite copy. Gated
# like the DE10 leg; a second multi_v7 kernel build, cached under
# work/test-initramfs-rt*.
if [ "${CI_TESTS_SKIP_QEMU_SYSTEM:-0}" = "1" ]; then
skip "test-initramfs.sh --kernel rt (32-bit QEMU boot test on the RT kernel, exfat cases)" "CI_TESTS_SKIP_QEMU_SYSTEM=1"
elif ! have qemu-system-arm; then
skip "test-initramfs.sh --kernel rt (32-bit QEMU boot test on the RT kernel, exfat cases)" "qemu-system-arm not found on PATH"
elif ! grep -q '^BR2_PACKAGE_LINUX_RT=y$' "$ROOT/configs/mister_de10nano_defconfig"; then
skip "test-initramfs.sh --kernel rt (32-bit QEMU boot test on the RT kernel, exfat cases)" "BR2_PACKAGE_LINUX_RT is not enabled in configs/mister_de10nano_defconfig"
else
printf -- '--- test-initramfs.sh --kernel rt: exfat fsck-request symlink ---\n'
printf ' (builds/reuses a second QEMU test kernel at the RT pin -- can take several minutes)\n'
if "$ROOT/scripts/test-initramfs.sh" --kernel rt exfat fsck-request symlink; then
pass "test-initramfs.sh --kernel rt (32-bit QEMU boot test on the RT kernel, 3 exfat cases)"
else
fail "test-initramfs.sh --kernel rt (32-bit QEMU boot test on the RT kernel, 3 exfat cases)" "one or more of the 3 cases failed -- see output above"
fi
fi

# The DE25-Nano's stage 1: the SAME package built for aarch64 by the DE25
# configuration -- once its stack enables BR2_LINUX_KERNEL_EXT_MISTER_INITRAMFS
# (ADR 0029 D11 keeps that off until a board has booted). Gated on the cpio
Expand Down
Loading
Loading