Compare commits

..

57 Commits

Author SHA1 Message Date
fa93fe06c4 README: bump to v1.13.2-k6.12.47-1, list new patches
Some checks failed
Check Upstream Updates / check-and-build (push) Failing after 49s
- Talos version badge: v1.12.4 → v1.13.2
- Image-tag example + upgrade-command example: v1.13.2-k6.12.47-1
- Add patches 0006 (grub EFI upgrade fallback), 0007 (acquire.go STATE
  wait for slow-init eMMC) and 0008 (imager --insecure for Overlay) to
  the patches table
- Note the slow-eMMC tolerance + canonical 3-CP validation in the
  "Reliable in-place upgrades" roadmap row
2026-05-25 21:43:58 -04:00
56960b09a8 Merge branch 'talos-v1.13.2-bump' for v1.13.2-k6.12.47-1 release
All checks were successful
Build Talos CM5 Image / build (push) Successful in 1h1m23s
Brings the Talos v1.13.2 / pkgs v1.13.0 bump and three Talos patches:
- 0006 grub EFI-at-/boot fallback for BOOT-less SBC Upgrade path
- 0007 acquire.go wait for STATE on slow-init disks (CM5 eMMC) — fixes
  the post-upgrade maintenance-mode regression on CM5 hardware
- 0008 imager respect --insecure for Overlay assets (build-tool fix)

Validated 2026-05-25 via a canonical 3-CP rolling upgrade on a freshly
flashed home-test cluster: .94/.95/.96 upgraded sequentially from v1.12.4
to v1.13.2-7, each came back stage=running with config preserved and
k8s Ready within ~5 min, no manual remediation, etcd quorum maintained.
2026-05-25 20:05:24 -04:00
19625ba8c0 patches: add 0008 imager respect --insecure for Overlay assets
The imager's `--insecure` flag covered BaseInstaller, ImageCache, and
SystemExtensions but not the Overlay or OverlayInstaller ContainerAssets.
When pulling those from a plain-HTTP local registry (e.g. for offline
or development builds), they always tried HTTPS and failed with
"http: server gave HTTP response to HTTPS client" even with the flag set.

This patch sets `ForceInsecure: cmdFlags.Insecure` on both overlay
asset references, matching how the other Inputs are handled.

Build-tool only — no effect on the running Talos OS. Lets `gmake installer`
work end-to-end against an insecure registry like 192.133.7.111:5001.
2026-05-25 20:04:38 -04:00
40bfac268d patches: add 0007 acquire.go wait for STATE on slow-init disks (CM5 eMMC)
After upgrade kexec into v1.13.2, CM5 eMMC takes ~2m13s between the SDHCI
controller registering and mmc0 actually becoming usable. The Talos config
acquire state machine (`acquire.go::stateDisk`) checks STATE in the first
seconds of boot, sees `VolumePhaseMissing`, and transitions one-way to
`stateEmbedded` -> `stateMaintenanceEnter`. When STATE later becomes
ready, the state machine doesn't re-enter `stateDisk`, so the node stays
in maintenance forever despite the on-disk config.yaml being intact.

This patch makes stateDisk tolerate transient phase=missing for up to
5 minutes (stateMissingDiskTimeout) before falling through to embedded.
A 5-second ticker on the outer Run loop ensures the timeout can fire
even when no further volume-status events arrive (e.g. truly missing
STATE on a fresh install).

Validated 2026-05-25 via canonical 3-CP rolling upgrade on a freshly
flashed v1.12.4 home-test cluster: all 3 blades upgraded sequentially
to v1.13.2-7 (this patch), each came back stage=running with config
loaded automatically and k8s Ready within ~5 min, no manual remediation.
See doc-compute-blade-kubernetes/talos-upgrade-validation/session-2026-05-25/E2E-VALIDATED.md.

Fast-init hardware sees no change — STATE reaches ready within seconds
and the existing path runs.
2026-05-25 20:04:30 -04:00
8fada1ebfe patches: restore 0006 grub EFI-at-/boot fallback for BOOT-less SBC Upgrade
This patch file mirrors a commit that already existed in checkouts/talos
(`a50511de7` — "grub: EFI-at-/boot fallback for BOOT-less SBC layout in
Upgrade path") but was never landed back into patches/siderolabs/talos/.
Extracted with `git format-patch` from the checkout so subsequent
`make patches` runs reproduce the same tree on a fresh clone.

Complements 0005 by handling the Upgrade code-path (in addition to the
fresh-install code-path 0005 already covers) for SBC layouts that don't
have a separate BOOT partition.
2026-05-25 20:04:17 -04:00
d84ddc491a talos: restore modules-arm64.txt patch; metal step needs --network=host
Two complementary fixes after end-to-end local installer build:

1. New talos/0001 patch — Replace hack/modules-arm64.txt with the
   intersection of upstream's initramfs list and our RPi 6.12.47
   build's actual modules (155 entries, down from upstream's 241).
   Initramfs target was failing with exit 123 in xargs install -D
   because upstream lists modules our kernel doesn't build (SATA,
   HID device drivers, some upstream-only crypto helpers).

2. Makefile: add --network=host to the metal docker run.
   The installer step already had it, but the metal step did not.
   For local-registry builds (REGISTRY=127.0.0.1:5001), the imager
   container needs --network=host to reach the host's registry to
   pull the overlay image when generating the raw disk image.
   Harmless on CI (no behavioural change against docker.io).

Validated locally end-to-end:
- kernel image:    234MB  (RPi 6.12.47 with RP1 driver support)
- overlay image:    9.7MB (U-Boot + firmware + DTBs)
- imager image:   346MB
- installer-base: 105MB
- installer:      ~100MB
- metal-arm64.raw.zst: 94MB (final flashable disk image)
2026-05-18 19:03:12 -04:00
18fed4ec51 pkgs config-arm64: add missing RP1 symbols to fix kernel link
The v1.13.2 rebase of pkgs 0001 only restored some RP1-related kernel
options (PINCTRL_RP1, COMMON_CLK_RP1, PINCTRL_BCM2712) because those
hunks happened to apply cleanly against upstream v1.13.0's 6.18.24-era
config-arm64. Several others were silently dropped, causing:

    ld.lld: error: undefined symbol: rp1_get_platform

at the vmlinux link step (~19 min into local kernel build).

Re-added:
- CONFIG_MFD_RP1=y                 (defines rp1_get_platform)
- CONFIG_COMMON_CLK_RP1_SDIO=y
- CONFIG_FB_BCM2708=y              (RPi framebuffer)
- CONFIG_PWM_PIO_RP1=y             (RPi PWM via PIO)
- CONFIG_PWM_BRCMSTB=y             (was "not set")

Local build now succeeds: svrnty/talos-rpi5-kernel:v1.13.0-local
loaded into local Docker (234MB).
2026-05-18 18:43:22 -04:00
9638fb44f1 Bump to Talos v1.13.2 / pkgs v1.13.0
- Makefile: TALOS_VERSION v1.12.4 -> v1.13.2, PKG_VERSION v1.12.0 -> v1.13.0
- siderolabs/talos 0001 (modules-arm64.txt): removed; hack/modules-arm64.txt
  is a CI assertion file with no build-time references. Will be regenerated
  from a real RPi 6.12.47 kernel build as a follow-up.
- siderolabs/talos 0005 (BOOT partition GRUB): rebased onto v1.13.2's
  Install/Upgrade refactor. installEFI struct field is gone upstream; ported
  the BOOT-partition probe + EFI-at-/boot fallback to work with the new
  efiFound local var and added a bootFromEFI struct field for runGrubInstall.
- siderolabs/pkgs 0001: rebased onto v1.13.0. Kernel config header bumped
  to 6.12.47. config-arm64 not fully regenerated for RPi 6.12.47 yet -- some
  upstream v1.13 6.18.x symbols (LIBIE_ADMINQ, IDPF, etc) remain in the file
  but the kernel's Kconfig silently drops unknown options during build.
2026-05-18 17:20:29 -04:00
Mathias Beaulieu-Duncan
e1d9add5aa Use dedicated talos-rpi5 runner label for workflows
Some checks failed
Check Upstream Updates / check-and-build (push) Failing after 1s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 18:27:07 -05:00
118ef4dcc9 Add serial console support, remove wrong debug UART patch
Some checks failed
Check Upstream Updates / check-and-build (push) Failing after 6s
Enable GPIO UART0 on Pi5/CM5 via dtoverlay=uart0-pi5 in
configTxtAppend. Remove the old 0002 patch that targeted the
debug UART (ttyAMA10) — Compute Blade uses GPIO 14/15 (ttyAMA0).
Renumber overlay patches (old 0003 becomes 0002).

Update README with tested serial console docs: wiring diagram,
even parity config, 3.3V requirement, and read-only limitation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:04:39 -05:00
f604f468b7 Add Gitea releases badge to README
All checks were successful
Check Upstream Updates / check-and-build (push) Successful in 5s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 16:57:01 -05:00
d260fe20ab Add reference architecture for production CM5 clusters
Document recommended storage layouts per node role:
- Control planes: NVMe boot for fast etcd I/O
- Postgres/storage: eMMC boot + NVMe data at /var/mnt/data
- Compute workers: eMMC only, stateless

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 16:53:19 -05:00
4e867e2055 Fix boot failure: remove duplicate config.txt section headers
All checks were successful
Build Talos CM5 Image / build (push) Successful in 3m38s
The [pi5]/[all] section headers in configTxtAppend created duplicate
sections when concatenated with the overlay's base config.txt, which
already ends with [pi5]/[all]. The RPi firmware parser choked on the
duplicate headers, preventing NVMe boot on fresh installs.

Remove the section headers — dtparam and overclock settings now land
under the existing [all] scope from the base config.txt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 13:00:54 -05:00
d4a55c670c Apply SBC overlay upgrade fix, add PCIe Gen 3 docs
All checks were successful
Build Talos CM5 Image / build (push) Successful in 3m11s
Check Upstream Updates / check-and-build (push) Successful in 5s
Apply overlay patch 0003 (EFI mount path detection for SBC layouts)
in the build so upgrades write firmware/config.txt to the correct
path. Update README with patch 0003, PCIe Gen 3 in features list,
and expanded PCIe Gen 3 instructions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 14:29:17 -05:00
5152b6cb44 Simplify config: use configTxtAppend, drop SBC overlay patch
All checks were successful
Build Talos CM5 Image / build (push) Successful in 2m41s
Check Upstream Updates / check-and-build (push) Successful in 5s
Config.txt is set correctly at flash time. Upgrades via talosctl
don't override firmware config (overlay writes to wrong path on
SBC layout, which is harmless). Users who need custom config.txt
set it once during initial flash.

- Use configTxtAppend with PCIe Gen 3 + overclock
- Put dtparam=pciex1_gen=3 in [pi5] section
- Remove patch 0003 (SBC overlay upgrade fix) — too risky,
  deleted GRUB's BOOTAA64.EFI in v8
- Remove full configTxt replacement mode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 16:47:42 -05:00
338a2c0021 Fix SBC overlay upgrade: preserve GRUB, enable PCIe Gen 3
All checks were successful
Build Talos CM5 Image / build (push) Successful in 2m58s
The v8 overlay patch deleted /boot/EFI/ to clean up stale firmware,
but this also removed GRUB's BOOTAA64.EFI, bricking the node.

Fix: keep SBC layout detection (write to /boot/ not /boot/EFI/) but
remove the os.RemoveAll that destroyed GRUB. Stale firmware files in
/boot/EFI/ are harmless.

Re-enable PCIe Gen 3 (dtparam=pciex1_gen=3) and full configTxt mode,
now that the overlay installer correctly writes to the EFI partition
root on SBC layouts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 15:50:52 -05:00
b5201f7906 Revert PCIe Gen 3 config: restore safe defaults for public image
All checks were successful
Build Talos CM5 Image / build (push) Successful in 2m55s
Check Upstream Updates / check-and-build (push) Successful in 4s
The PCIe Gen 3 changes (dtparam=pciex1_gen=3, full configTxt
replacement, SBC overlay upgrade fix) caused boot failures during
talosctl upgrade on CM5 nodes. Revert to the pre-Gen3 state:
- configTxtAppend (overclock only) instead of full configTxt replacement
- Remove 0003 overlay patch application (kept in patches/ for future use)

PCIe Gen 3 support will be re-added after root cause analysis.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 20:27:37 -05:00
91d86de629 Fix SBC overlay upgrade + simplify PCIe Gen 3 config
All checks were successful
Build Talos CM5 Image / build (push) Successful in 3m22s
Two fixes in one:

1. SBC overlay upgrade path: the overlay installer was always writing
   to /boot/EFI, but on SBC layouts (no BOOT partition) the GRUB code
   mounts EFI at /boot. Config.txt and firmware ended up in a stale
   /boot/EFI/ subdirectory, invisible to the firmware. The installer
   now detects the SBC layout and writes to the correct location.

2. PCIe Gen 3: dtparam=pciex1_gen=3 works on CM5 (the DT overrides
   exist), so the custom pcie-gen3.dtbo overlay is unnecessary.
   Simplified to just use dtparam in config.txt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 19:45:39 -05:00
3cfbe794f7 Fix PCIe Gen 3 on CM5: custom DT overlay for missing pciex1 alias
All checks were successful
Build Talos CM5 Image / build (push) Successful in 3m20s
The CM5 DTB (bcm2712-rpi-cm5-cm5io.dtb) lacks the pciex1 alias that
the Pi 5 DTB provides, making dtparam=pciex1_gen=3 silently fail.

Add a custom device tree overlay (pcie-gen3.dtbo) that targets
/axi/pcie@1000110000 directly to set max-link-speed = <3>. The overlay
is embedded in the SBC installer and written to /boot/EFI/overlays/
during install/upgrade.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 19:08:26 -05:00
a9cc56e315 Fix PCIe Gen 3: move dtparam into [pi5] section of config.txt
All checks were successful
Build Talos CM5 Image / build (push) Successful in 2m53s
The dtparam=pciex1_gen=3 was being appended after the [all] section,
but RPi firmware requires PCIe dtparams in the [pi5] section.
Switch from configTxtAppend to full configTxt replacement to control
section ordering. Also add dtparam=pciex1 to explicitly enable the
external PCIe link.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 18:45:05 -05:00
66a3d11984 Enable PCIe Gen 3 for NVMe: ~800 MB/s vs ~375 MB/s Gen 2
All checks were successful
Build Talos CM5 Image / build (push) Successful in 3m25s
Adds dtparam=pciex1_gen=3 to config.txt overlay. Benchmarked Gen 2 baseline
on all 3 pg nodes showing consistent ~375 MB/s write throughput, bottlenecked
by the Gen 2 x1 lane limit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 18:09:30 -05:00
754f49c562 Update README: bump example tag to v1.12.4-k6.12.47-4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 13:51:17 -05:00
4fed64844a Fix GRUB patch: skip sd-boot probe on arm64 for first upgrade
All checks were successful
Build Talos CM5 Image / build (push) Successful in 4m50s
On fresh SBC images, the EFI partition has sd-boot UKI files but no
GRUB config. During upgrade, Probe() found sd-boot and used it, which
failed because RPi5/CM5 firmware lacks EFI SetVariableRT support.

Add arm64 guard to Probe(): when no GRUB config is found, skip sd-boot
probing and return a fresh GRUB config. This transitions from sd-boot
to GRUB on the first upgrade from a fresh flash.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 13:50:42 -05:00
8c562c7155 Update README: NVMe boot tested on Compute Blade
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 13:18:24 -05:00
fc020410f1 Update README: in-place upgrades tested, add patches table
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:40:13 -05:00
ca36438d12 Add GRUB SBC upgrade patch: handle missing BOOT partition
All checks were successful
Build Talos CM5 Image / build (push) Successful in 3m15s
Patch 0005 fixes talosctl upgrade on SBC layouts (RPi5/CM5) where
the disk has no separate BOOT (XFS) partition — only EFI (VFAT).
Falls back to mounting EFI at /boot for probe, install, and revert.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 11:37:05 -05:00
6cffb4e311 Add opentree fallback patch for RPi downstream kernel (<6.15)
All checks were successful
Build Talos CM5 Image / build (push) Successful in 2m56s
Check Upstream Updates / check-and-build (push) Successful in 4s
Talos assumes bare metal kernels support open_tree on anonymous FS
(added in 6.15). The RPi downstream kernel (6.12.x) does not, causing
shadow bind mount failures for /etc files and cascading network init
failures. This patch removes the InContainer() gate so the capability
check runs on all platforms.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 14:25:03 -05:00
Mathias Beaulieu-Duncan
5c81953278 Fix modules patch: ip6_gre.ko not in RPi downstream kernel
All checks were successful
Build Talos CM5 Image / build (push) Successful in 3m17s
ip6_gre.ko exists in Talos upstream module list (v1.12.4) but not
in the RPi downstream kernel build. Only add it to the removal side
of the patch, not our custom module list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:55:45 -05:00
Mathias Beaulieu-Duncan
a4e934a4e9 Fix CI PATH: prepend GNU sed via GITHUB_PATH instead of replacing PATH
Some checks failed
Build Talos CM5 Image / build (push) Failing after 28s
The hardcoded job-level PATH env wiped out nvm/node, breaking
actions/checkout. Use GITHUB_PATH to prepend GNU sed's gnubin
directory while preserving the runner's inherited PATH.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:54:34 -05:00
Mathias Beaulieu-Duncan
6c75585c0a Bump upstream: v1.12.4-k6.12.47-1
Some checks failed
Build Talos CM5 Image / build (push) Failing after 1s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:53:12 -05:00
Mathias Beaulieu-Duncan
37f9292ef1 Update arm64 modules patch for Talos v1.12.4 (add ip6_gre)
Talos v1.12.4 added kernel/net/ipv6/ip6_gre.ko to modules-arm64.txt.
Update our patch to match. Also silence gmake checkouts-clean stdout
in auto-update.sh to prevent it leaking into GITHUB_OUTPUT.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:50:45 -05:00
Mathias Beaulieu-Duncan
dc37b435c3 Fix GNU sed PATH in CI workflows for macOS runner
BSD sed on macOS requires `sed -i ''` but auto-update.sh uses GNU
`sed -i` syntax. The workflows installed gnu-sed via Homebrew but
never added it to PATH, causing "invalid command code M" failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:45:46 -05:00
Mathias Beaulieu-Duncan
58b9ccb56c Add supply chain attestation to installer image via crane + buildx
Some checks failed
Build Talos CM5 Image / build (push) Successful in 5m19s
Check Upstream Updates / check-and-build (push) Failing after 13s
Push the full installer tar with crane first (preserving all layers),
then re-wrap with docker buildx to add provenance and SBOM attestation
for Docker Scout compliance. Buildx can pull the image from the registry
since crane already pushed it, avoiding the docker-container driver
limitation with locally loaded images.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:57:54 -05:00
Mathias Beaulieu-Duncan
784fb4d5f6 Fix installer image missing kernel and overlay layers
All checks were successful
Build Talos CM5 Image / build (push) Successful in 4m5s
The docker buildx build wrapper with docker-container driver cannot
access locally loaded images, causing it to only capture the first
layer (22MB base) and drop the kernel (~98MB) and overlay (~3MB).

Switch back to crane push which pushes the tar as-is, preserving
all 3 layers. Attestation args remain on actual build steps where
buildx works correctly.

Fixes broken tags: v1.12.3-k6.12.47-3, v1.12.3-k6.12.47-4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 21:46:10 -05:00
Mathias Beaulieu-Duncan
9c0075057b Use rpiboot for EEPROM config in NVMe guide
CM5 on Compute Blade doesn't have an SD slot for booting Raspberry Pi
OS. Use rpiboot recovery mode over USB instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 20:05:13 -05:00
Mathias Beaulieu-Duncan
5b59f8de8d Add NVMe boot guide (untested) to README
Documents the dd + EEPROM configuration approach for booting Talos
from NVMe on RPi5/CM5. Includes BOOT_ORDER, PCIE_PROBE settings,
and optional PCIe Gen 3 configuration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 20:00:16 -05:00
Mathias Beaulieu-Duncan
f3132a310e Update NVMe boot status: dd + EEPROM config approach
NVMe kernel driver is already built-in (CONFIG_BLK_DEV_NVME=y). The
expected approach is simply dd'ing the metal image to NVMe and setting
EEPROM BOOT_ORDER=0xf416 + PCIE_PROBE=1. Pending hardware validation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:57:01 -05:00
Mathias Beaulieu-Duncan
970d9685f1 Fix serial console for RPi5/CM5 debug UART (ttyAMA10)
The overlay was using console=ttyAMA0 (GPIO 14/15) but the RPi5 debug
UART is ttyAMA10 (JST connector between HDMI ports on Pi5, test pads
TP35/TP36 on CM5). Also adds earlycon for early boot output and disables
GPIO UART on Pi5 in config.txt to avoid U-Boot compatibility issues.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:47:18 -05:00
Mathias Beaulieu-Duncan
689b9402a8 Add GRUB bootloader patches for talosctl upgrade on RPi5/CM5
All checks were successful
Build Talos CM5 Image / build (push) Successful in 1h4m48s
Force GRUB instead of sd-boot on arm64 and pass --no-nvram to
  grub-install, working around the SetVariableRT firmware limitation
  that prevents in-place upgrades on RPi5/CM5 hardware.

  Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:20:18 -05:00
Mathias Beaulieu-Duncan
b1eb322d7b Switch to 4K page size for production readiness
Remove the 16K page override from the kernel patch, preserving
upstream Talos's default 4K pages. RPi5 hardware works correctly
with 4K pages — the RPi Foundation's 16K default is a TLB
performance optimization (~5%), not a hardware requirement.

Benefits:
- Correct memory accounting (4x less overhead per page)
- Full software compatibility (jemalloc, Longhorn, F2FS, etc.)
- No OOM surprises on control-plane nodes
- Aligned with upstream Talos kernel config

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 18:28:22 -05:00
Mathias Beaulieu-Duncan
8178ba195e Add known issues, roadmap, and conditional Go toolchain patch
- Document SetVariableRT upgrade failure, 16K page size implications,
  serial console issue, and SBC install disk behavior
- Add production roadmap (4K pages, GRUB boot, serial fix, NVMe)
- Make overlay Go patch conditional: apply only on Go 1.24.x,
  skip on 1.25+ where CVEs are already fixed upstream

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 18:05:51 -05:00
Mathias Beaulieu-Duncan
d933444fbc Fix double-v badge bug and add table segment updates in README sync
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 17:33:33 -05:00
Mathias Beaulieu-Duncan
09addfa626 Auto-update README versions when upstream updates are detected
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 17:28:40 -05:00
Mathias Beaulieu-Duncan
7fceae1418 Point all version badges to upstream repo main pages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 17:16:25 -05:00
Mathias Beaulieu-Duncan
6ca561592f Fix RPi kernel badge link — repo has no version-tagged releases
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 17:14:58 -05:00
Mathias Beaulieu-Duncan
2b2205f503 Link version badges to upstream GitHub releases
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 17:06:48 -05:00
Mathias Beaulieu-Duncan
6f24c8ef46 Replace cosign with buildx attestations for Docker Scout compliance
All checks were successful
Build Talos CM5 Image / build (push) Successful in 2m49s
Docker Scout requires buildx-style provenance+SBOM, not cosign
attestations. Replace crane push with docker load + buildx build
(--provenance=mode=max --sbom=true) for the installer image. Use
buildx imagetools create for the release tag to preserve attestations.
Remove cosign/syft from CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 17:05:20 -05:00
Mathias Beaulieu-Duncan
2f307aecec Open all external links in new tab (target=_blank)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 16:57:29 -05:00
Mathias Beaulieu-Duncan
ee085a7606 Replace version table with Docker-style badges for all components
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 16:56:46 -05:00
Mathias Beaulieu-Duncan
907dd98b24 Split README into user manual and TECHNICAL.md
Move CI/CD, runner setup, secrets, and project structure to
TECHNICAL.md. Streamline README as a user-facing guide with
install/upgrade instructions. Fix Docker badges for arm64.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 16:55:37 -05:00
Mathias Beaulieu-Duncan
2618de74e8 Update README with Docker Hub badges, version table, and tag format
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 16:51:04 -05:00
Mathias Beaulieu-Duncan
ba3c42f561 Add SBOM attestations to installer/release images, remove Scout
All checks were successful
Build Talos CM5 Image / build (push) Successful in 7m0s
Attach cosign+syft SBOM attestations to crane-pushed installer and
release images to satisfy Docker Scout supply chain policy. Replace
docker tag/push with crane copy for the release target. Remove the
Scout CVE scan target and clean up release notes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 16:48:56 -05:00
Mathias Beaulieu-Duncan
44aa3793ee Add LICENSE, update README, upgrade provenance to max-mode
All checks were successful
Build Talos CM5 Image / build (push) Successful in 3m29s
- Add MPL 2.0 LICENSE file for compliance
- Add license section and upstream attribution to README
- Upgrade provenance attestation from mode=min to mode=max

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:57:11 -05:00
Mathias Beaulieu-Duncan
5abca73056 Fix 21 Go stdlib CVEs and enable supply chain attestations
All checks were successful
Build Talos CM5 Image / build (push) Successful in 3m26s
- Patch sbc-raspberrypi5 overlay to use Go 1.24.13 (fixes 1C/7H/12M/1L CVEs)
- Add ATTESTATION_ARGS (--provenance=true --sbom=true) to all buildx targets
- Override upstream --provenance=false via TARGET_ARGS (last flag wins)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:36:13 -05:00
Mathias Beaulieu-Duncan
0d3941eb91 Add daily auto-update workflow and fix overlay dirty tag
All checks were successful
Build Talos CM5 Image / build (push) Successful in 3m6s
- Rewrite check-upstream.sh to parse RPi kernel version from patch file
- Add auto-update.sh for automated version bumps with patch smoke test
- Rewrite check-updates.yaml as daily auto-build with issue fallback
- Update build.yaml release body to show Talos + kernel versions from tag
- Fix overlay dirty tag: remove --dirty from SBCOVERLAY_TAG git describe
  (the sed rewrite of pkg.yaml is intentional, not an accidental change)

Tag strategy: v{TALOS}-k{KERNEL}-{BUILD} (e.g. v1.12.3-k6.12.47-1)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 15:05:46 -05:00
Mathias Beaulieu-Duncan
3a824e960f Regenerate talos patch for v1.12.3
Some checks failed
Build Talos CM5 Image / build (push) Failing after 31m33s
Patch was stale — regenerated from the working checkout to match
the v1.12.3 hack/modules-arm64.txt index.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:27:34 -05:00
Mathias Beaulieu-Duncan
f2b8a0ec65 Fix talos patch — restore hack/modules-arm64.txt
Some checks failed
Build Talos CM5 Image / build (push) Failing after 13s
The talos patch was incorrectly replaced with pkgs-repo changes
(Pkgfile, kernel config). Restored the correct patch that modifies
hack/modules-arm64.txt in the talos checkout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:26:12 -05:00
22 changed files with 2156 additions and 1842 deletions

View File

@ -18,7 +18,7 @@ on:
jobs:
build:
runs-on: [self-hosted, macos]
runs-on: talos-rpi5
timeout-minutes: 180
steps:
@ -33,6 +33,7 @@ jobs:
for pkg in make gnu-sed crane; do
brew list --formula "$pkg" &>/dev/null || brew install "$pkg"
done
echo "/opt/homebrew/opt/gnu-sed/libexec/gnubin" >> "$GITHUB_PATH"
gmake --version | head -1
- name: Set up Docker Buildx
@ -66,9 +67,6 @@ jobs:
- name: Tag release images
run: gmake release TAG=${{ steps.version.outputs.tag }}
- name: Run Docker Scout CVE scan
run: gmake scout
- name: Compress disk image
run: |
# The imager outputs to checkouts/talos/_out/
@ -91,24 +89,20 @@ jobs:
REPO="${GITHUB_REPOSITORY}"
API="${GITEA_URL}/api/v1"
SCOUT_SECTION=""
if [ -f _out/scout-report.md ]; then
SCOUT_SECTION=$(cat _out/scout-report.md)
fi
# Extract component versions from tag (format: v1.12.3-k6.12.47-1)
TALOS_VER=$(echo "$TAG" | sed -E 's/^(v[0-9]+\.[0-9]+\.[0-9]+)-.*/\1/')
KERNEL_VER=$(echo "$TAG" | sed -E 's/.*-k([0-9]+\.[0-9]+\.[0-9]+)-.*/\1/')
RELEASE_BODY="Custom Talos Linux image for Raspberry Pi 5 / CM5 (Compute Blade)
**Talos version**: ${TAG}
**Kernel**: RPi downstream (CM5/RP1 support)
**Talos**: ${TALOS_VER}
**Kernel**: RPi downstream ${KERNEL_VER} (CM5/RP1 support)
**Extensions**: iscsi-tools, util-linux-tools
**Overclock**: 2.6GHz (arm_freq=2600)
## Artifacts
- \`metal-arm64.raw.zst\` — Raw disk image for eMMC flashing
- \`docker.io/svrnty/talos-rpi5:${TAG}\` — Installer image for talosctl upgrade
## Security Scan
${SCOUT_SECTION}"
- \`docker.io/svrnty/talos-rpi5:${TAG}\` — Installer image for talosctl upgrade"
# Strip leading whitespace from heredoc-style indentation
RELEASE_BODY=$(echo "$RELEASE_BODY" | sed 's/^ //')

View File

@ -1,25 +1,33 @@
# Check for upstream Talos and RPi kernel updates
# Daily upstream update check with auto-build
#
# Runs on a schedule and creates a Gitea issue when new versions are found.
# This is notification-only — builds require manual tag push after verifying
# patches still apply.
# Detects new Talos OS and RPi kernel versions, applies updates,
# smoke-tests patches, and pushes a release tag (which triggers build.yaml).
# Falls back to creating a Gitea issue if patches fail to apply.
name: Check Upstream Updates
on:
schedule:
# Run weekly on Monday at 08:00 UTC
- cron: '0 8 * * 1'
- cron: '0 8 * * *' # Daily at 08:00 UTC
workflow_dispatch:
jobs:
check-updates:
runs-on: [self-hosted, macos]
timeout-minutes: 10
check-and-build:
runs-on: talos-rpi5
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Need full history for tag-based build numbering
- name: Install dependencies
run: |
for pkg in make gnu-sed crane jq; do
brew list --formula "$pkg" &>/dev/null || brew install "$pkg"
done
echo "/opt/homebrew/opt/gnu-sed/libexec/gnubin" >> "$GITHUB_PATH"
- name: Check for upstream updates
id: check
@ -27,95 +35,83 @@ jobs:
chmod +x scripts/check-upstream.sh
scripts/check-upstream.sh >> "$GITHUB_OUTPUT"
- name: Create issue for Talos update
if: steps.check.outputs.talos_update == 'true'
uses: actions/github-script@v7
with:
script: |
const currentVersion = '${{ steps.check.outputs.talos_current }}';
const latestVersion = '${{ steps.check.outputs.talos_latest }}';
const title = `Talos update available: ${currentVersion} → ${latestVersion}`;
- name: Run auto-update
if: steps.check.outputs.talos_update == 'true' || steps.check.outputs.rpi_update == 'true'
id: update
env:
TALOS_UPDATE: ${{ steps.check.outputs.talos_update }}
RPI_UPDATE: ${{ steps.check.outputs.rpi_update }}
LATEST_TALOS: ${{ steps.check.outputs.talos_latest }}
LATEST_RPI_TAG: ${{ steps.check.outputs.rpi_latest }}
run: |
chmod +x scripts/auto-update.sh
scripts/auto-update.sh >> "$GITHUB_OUTPUT"
// Check if an open issue already exists
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'upstream-update',
});
- name: Commit and tag
if: steps.update.outputs.patch_failed != 'true' && steps.update.outputs.new_tag != ''
env:
NEW_TAG: ${{ steps.update.outputs.new_tag }}
run: |
git config user.name "Gitea Actions"
git config user.email "actions@openharbor.io"
git add -A
git commit -m "Bump upstream: ${NEW_TAG}"
git tag "$NEW_TAG"
git push origin main --tags
const existing = issues.data.find(i => i.title.includes('Talos update'));
if (existing) {
console.log(`Issue already exists: #${existing.number}`);
return;
}
- name: Create issue on patch failure
if: steps.update.outputs.patch_failed == 'true'
env:
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TALOS_CURRENT: ${{ steps.check.outputs.talos_current }}
TALOS_LATEST: ${{ steps.check.outputs.talos_latest }}
TALOS_UPDATE: ${{ steps.check.outputs.talos_update }}
RPI_CURRENT: ${{ steps.check.outputs.rpi_current }}
RPI_LATEST: ${{ steps.check.outputs.rpi_latest }}
RPI_UPDATE: ${{ steps.check.outputs.rpi_update }}
run: |
GITEA_URL="${GITHUB_SERVER_URL}"
REPO="${GITHUB_REPOSITORY}"
API="${GITEA_URL}/api/v1"
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: [
`## Talos Update Available`,
``,
`| | Version |`,
`|---|---|`,
`| Current | \`${currentVersion}\` |`,
`| Latest | \`${latestVersion}\` |`,
``,
`### Steps`,
`1. Update \`TALOS_VERSION\` in \`Makefile\``,
`2. Verify patches still apply: \`make checkouts patches\``,
`3. If patches fail, port them to the new version`,
`4. Push a version tag to trigger the build pipeline`,
``,
`### Links`,
`- [Talos Release Notes](https://github.com/siderolabs/talos/releases/tag/${latestVersion})`,
].join('\n'),
labels: ['upstream-update', 'talos'],
});
BODY="## Upstream update requires manual patch porting
- name: Create issue for RPi kernel update
if: steps.check.outputs.rpi_update == 'true'
uses: actions/github-script@v7
with:
script: |
const currentVersion = '${{ steps.check.outputs.rpi_current }}';
const latestVersion = '${{ steps.check.outputs.rpi_latest }}';
const title = `RPi kernel update available: ${currentVersion} → ${latestVersion}`;
Automated patch application failed. Manual intervention needed.
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'upstream-update',
});
| Component | Current | Latest | Update? |
|-----------|---------|--------|---------|
| Talos | \`${TALOS_CURRENT}\` | \`${TALOS_LATEST}\` | ${TALOS_UPDATE} |
| RPi kernel | \`${RPI_CURRENT}\` | \`${RPI_LATEST}\` | ${RPI_UPDATE} |
const existing = issues.data.find(i => i.title.includes('RPi kernel update'));
if (existing) {
console.log(`Issue already exists: #${existing.number}`);
return;
}
### Steps
1. Check out this repo and run \`scripts/auto-update.sh\` to see what fails
2. Port patches to the new upstream version
3. Verify: \`gmake checkouts patches && gmake checkouts-clean\`
4. Push changes — the next scheduled run will pick them up
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: [
`## RPi Kernel Update Available`,
``,
`| | Version |`,
`|---|---|`,
`| Current (in pkgs patch) | \`${currentVersion}\` |`,
`| Latest stable | \`${latestVersion}\` |`,
``,
`### Steps`,
`1. Update the kernel version in the pkgs patch`,
`2. Verify the patch still applies: \`make checkouts patches\``,
`3. Test build: \`make kernel\``,
`4. Push a version tag to trigger the full build pipeline`,
``,
`### Links`,
`- [RPi Linux Releases](https://github.com/raspberrypi/linux/tags)`,
].join('\n'),
labels: ['upstream-update', 'kernel'],
});
### Links
- [Talos Releases](https://github.com/siderolabs/talos/releases)
- [RPi Linux Tags](https://github.com/raspberrypi/linux/tags)"
# Strip leading whitespace from heredoc-style indentation
BODY=$(echo "$BODY" | sed 's/^ //')
BODY_JSON=$(jq -Rs '.' <<< "$BODY")
# Check for existing open issue to avoid duplicates
EXISTING=$(curl -sf \
-H "Authorization: token ${GITEA_TOKEN}" \
"${API}/repos/${REPO}/issues?state=open&type=issues&labels=upstream-update" \
| jq -r '[.[] | select(.title | contains("manual patch"))][0].id // empty')
if [ -n "$EXISTING" ]; then
echo "Issue already exists (id: $EXISTING), skipping creation"
exit 0
fi
curl -sf -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"title\":\"Upstream update requires manual patch porting\",\"body\":${BODY_JSON},\"labels\":[\"upstream-update\"]}" \
"${API}/repos/${REPO}/issues"
echo "Created issue for manual patch porting"

373
LICENSE Normal file
View File

@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@ -11,8 +11,8 @@
# make release # Tag and push release images
# make clean # Remove checkouts and build artifacts
PKG_VERSION = v1.12.0
TALOS_VERSION = v1.12.3
PKG_VERSION = v1.13.0
TALOS_VERSION = v1.13.2
SBCOVERLAY_VERSION = main
# Prefer GNU coreutils (macOS: brew install gnu-sed coreutils)
@ -45,11 +45,14 @@ PATCHES_DIRECTORY := $(PWD)/patches
PKGS_TAG = $(shell cd $(CHECKOUTS_DIRECTORY)/pkgs && git describe --tag --always --dirty --match v[0-9]\*)
TALOS_TAG = $(shell cd $(CHECKOUTS_DIRECTORY)/talos && git describe --tag --always --dirty --match v[0-9]\*)
SBCOVERLAY_TAG = $(shell cd $(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5 && git describe --tag --always --dirty)-$(PKGS_TAG)
SBCOVERLAY_TAG = $(shell cd $(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5 && git describe --tag --always)-$(PKGS_TAG)
# Build the --system-extension-image flags from the EXTENSIONS list
EXTENSION_FLAGS = $(foreach ext,$(EXTENSIONS),--system-extension-image=$(ext))
# Supply chain attestation flags (overrides upstream --provenance=false)
ATTESTATION_ARGS = --provenance=mode=max --sbom=true
# Common imager flags for overlay and extensions
IMAGER_COMMON_FLAGS = \
--overlay-name="rpi5" \
@ -71,7 +74,6 @@ help:
@echo " overlay — Build SBC overlay (U-Boot, firmware, DTBs)"
@echo " installer — Build Talos installer image + raw disk image"
@echo " release — Tag and push release images"
@echo " scout — Run Docker Scout CVE scan on all images"
@echo " clean — Remove checkouts and build artifacts"
@echo ""
@echo "Variables:"
@ -103,7 +105,7 @@ checkouts-clean:
#
# Patches
#
.PHONY: patches-pkgs patches-talos patches
.PHONY: patches-pkgs patches-talos patches-overlay patches
patches-pkgs:
cd "$(CHECKOUTS_DIRECTORY)/pkgs" && \
git am "$(PATCHES_DIRECTORY)/siderolabs/pkgs/"*.patch
@ -112,7 +114,19 @@ patches-talos:
cd "$(CHECKOUTS_DIRECTORY)/talos" && \
git am "$(PATCHES_DIRECTORY)/siderolabs/talos/"*.patch
patches: patches-pkgs patches-talos
patches-overlay:
@cd "$(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5" && \
GO_VER=$$(sed -n 's/^go //p' go.work | head -1) && \
GO_MINOR=$$(echo "$$GO_VER" | cut -d. -f1,2) && \
if [ "$$GO_MINOR" = "1.24" ]; then \
echo "Overlay Go $$GO_VER — applying Go toolchain patch (CVE fix)"; \
git am "$(PATCHES_DIRECTORY)/talos-rpi5/sbc-raspberrypi5/0001-"*.patch; \
else \
echo "Overlay Go $$GO_VER — skipping Go toolchain patch (CVEs fixed upstream)"; \
fi && \
git am "$(PATCHES_DIRECTORY)/talos-rpi5/sbc-raspberrypi5/0002-"*.patch
patches: patches-pkgs patches-talos patches-overlay
#
# Kernel — build and push the RPi downstream kernel
@ -121,7 +135,7 @@ patches: patches-pkgs patches-talos
kernel:
cd "$(CHECKOUTS_DIRECTORY)/pkgs" && \
$(MAKE) docker-kernel \
TARGET_ARGS="--tag=$(KERNEL_IMAGE):$(PKGS_TAG) --push=true" \
TARGET_ARGS="--tag=$(KERNEL_IMAGE):$(PKGS_TAG) --push=true $(ATTESTATION_ARGS)" \
PLATFORM=linux/arm64
#
@ -138,7 +152,7 @@ overlay:
rm -f "$(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5/internal/base/pkg.yaml.bak"
cd "$(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5" && \
$(MAKE) docker-sbc-raspberrypi5 \
TARGET_ARGS="--tag=$(OVERLAY_IMAGE):$(SBCOVERLAY_TAG) --push=true" \
TARGET_ARGS="--tag=$(OVERLAY_IMAGE):$(SBCOVERLAY_TAG) --push=true $(ATTESTATION_ARGS)" \
INSTALLER_ARCH=arm64 PLATFORM=linux/arm64
#
@ -160,13 +174,13 @@ installer:
PKG_KERNEL=$(KERNEL_IMAGE):$(PKGS_TAG) \
INSTALLER_ARCH=arm64 PLATFORM=linux/arm64 \
target-imager \
TARGET_ARGS="--output type=image,name=$(IMAGER_IMAGE):$(TALOS_TAG),push=true" && \
TARGET_ARGS="--output type=image,name=$(IMAGER_IMAGE):$(TALOS_TAG),push=true $(ATTESTATION_ARGS)" && \
$(MAKE) \
REGISTRY=$(REGISTRY) USERNAME=$(REGISTRY_USERNAME) \
PKG_KERNEL=$(KERNEL_IMAGE):$(PKGS_TAG) \
INSTALLER_ARCH=arm64 PLATFORM=linux/arm64 \
target-installer-base \
TARGET_ARGS="--output type=image,name=$(INSTALLER_IMAGE):base-$(TALOS_TAG),push=true" && \
TARGET_ARGS="--output type=image,name=$(INSTALLER_IMAGE):base-$(TALOS_TAG),push=true $(ATTESTATION_ARGS)" && \
docker pull $(IMAGER_IMAGE):$(TALOS_TAG) && \
docker run --rm -t -v ./_out:/out --privileged --network=host \
$(IMAGER_IMAGE):$(TALOS_TAG) \
@ -174,8 +188,12 @@ installer:
--base-installer-image="$(INSTALLER_IMAGE):base-$(TALOS_TAG)" \
$(IMAGER_COMMON_FLAGS) && \
crane push ./_out/installer-arm64.tar $(INSTALLER_IMAGE):$(TALOS_TAG) && \
printf "FROM $(INSTALLER_IMAGE):$(TALOS_TAG)\n" | docker buildx build \
--platform linux/arm64 \
$(ATTESTATION_ARGS) \
-t $(INSTALLER_IMAGE):$(TALOS_TAG) --push - && \
docker \
run --rm -t -v ./_out:/out -v /dev:/dev --privileged \
run --rm -t -v ./_out:/out -v /dev:/dev --privileged --network=host \
$(IMAGER_IMAGE):$(TALOS_TAG) \
metal --arch arm64 \
--base-installer-image="$(INSTALLER_IMAGE):$(TALOS_TAG)" \
@ -186,40 +204,9 @@ installer:
#
.PHONY: release
release:
docker pull $(INSTALLER_IMAGE):$(TALOS_TAG) && \
docker tag $(INSTALLER_IMAGE):$(TALOS_TAG) $(REGISTRY)/$(REGISTRY_USERNAME)/$(IMAGE_NAME):$(TAG) && \
docker push $(REGISTRY)/$(REGISTRY_USERNAME)/$(IMAGE_NAME):$(TAG)
#
# Scout — Docker Scout CVE scan on all pushed images
#
SCOUT_REPORT := _out/scout-report.md
SCOUT_IMAGES := \
$(KERNEL_IMAGE):$(PKGS_TAG) \
$(OVERLAY_IMAGE):$(SBCOVERLAY_TAG) \
$(IMAGER_IMAGE):$(TALOS_TAG) \
$(INSTALLER_IMAGE):base-$(TALOS_TAG) \
$(INSTALLER_IMAGE):$(TALOS_TAG)
.PHONY: scout
scout:
@mkdir -p _out
@if ! docker scout version >/dev/null 2>&1; then \
echo "Docker Scout not available -- skipping CVE scan." > $(SCOUT_REPORT); \
exit 0; \
fi
@echo "# Docker Scout CVE Summary" > $(SCOUT_REPORT)
@echo "" >> $(SCOUT_REPORT)
@for image in $(SCOUT_IMAGES); do \
echo "Scanning $$image ..."; \
echo "### $${image##*/}" >> $(SCOUT_REPORT); \
echo '```' >> $(SCOUT_REPORT); \
docker scout quickview "$$image" --platform linux/arm64 2>&1 >> $(SCOUT_REPORT) || \
echo "Scout scan failed for $$image" >> $(SCOUT_REPORT); \
echo '```' >> $(SCOUT_REPORT); \
echo "" >> $(SCOUT_REPORT); \
done
@echo "Scout report written to $(SCOUT_REPORT)"
docker buildx imagetools create \
-t $(REGISTRY)/$(REGISTRY_USERNAME)/$(IMAGE_NAME):$(TAG) \
$(INSTALLER_IMAGE):$(TALOS_TAG)
#
# Clean

308
README.md
View File

@ -1,95 +1,277 @@
# Talos CM5 Builder
Custom Talos Linux images for Raspberry Pi CM5 on Compute Blade hardware.
Custom Talos Linux images for Raspberry Pi 5 / CM5 on Compute Blade hardware.
<a href="https://git.openharbor.io/svrnty/talos-rpi5/releases" target="_blank"><img src="https://img.shields.io/badge/releases-Gitea-green?logo=gitea&logoColor=white" alt="Gitea Releases"></a>
<a href="https://hub.docker.com/r/svrnty/talos-rpi5" target="_blank"><img src="https://img.shields.io/docker/v/svrnty/talos-rpi5?sort=semver&label=talos-rpi5&logo=docker&arch=arm64" alt="Docker Hub"></a>
<a href="https://hub.docker.com/r/svrnty/talos-rpi5" target="_blank"><img src="https://img.shields.io/docker/pulls/svrnty/talos-rpi5?logo=docker" alt="Docker Pulls"></a>
<a href="https://hub.docker.com/r/svrnty/talos-rpi5" target="_blank"><img src="https://img.shields.io/docker/image-size/svrnty/talos-rpi5?sort=semver&logo=docker&arch=arm64" alt="Docker Image Size"></a>
The official Talos Image Factory does not support CM5 — the mainline kernel lacks CM5 device trees and RP1 driver support. This builder uses the RPi downstream kernel (via [talos-rpi5/talos-builder](https://github.com/talos-rpi5/talos-builder) patches) to produce working CM5 images with our extensions and overclock config.
## What it builds
## Current versions
- **Installer image**`docker.io/svrnty/talos-rpi5:<tag>` (for `talosctl upgrade`)
- **Raw disk image** → Gitea release `metal-arm64.raw.zst` (for eMMC flashing)
| Component | Version |
|-----------|---------|
| Talos Linux | <a href="https://github.com/siderolabs/talos" target="_blank"><img src="https://img.shields.io/badge/talos-v1.13.2-blue?logo=kubernetes&logoColor=white" alt="Talos version"></a> |
| RPi Kernel | <a href="https://github.com/raspberrypi/linux" target="_blank"><img src="https://img.shields.io/badge/kernel-6.12.47-blue?logo=linux&logoColor=white" alt="Kernel version"></a> |
| iscsi-tools | <a href="https://github.com/siderolabs/extensions" target="_blank"><img src="https://img.shields.io/badge/iscsi--tools-v0.1.6-blue?logo=docker" alt="iscsi-tools version"></a> |
| util-linux-tools | <a href="https://github.com/siderolabs/extensions" target="_blank"><img src="https://img.shields.io/badge/util--linux--tools-2.40.4-blue?logo=docker" alt="util-linux-tools version"></a> |
Baked-in config:
- RPi downstream kernel with CM5/RP1 support
- Overclock: 2.6GHz (`arm_freq=2600`, `over_voltage_delta=50000`, `arm_boost=1`)
- Extensions: `iscsi-tools`, `util-linux-tools`
## Image tags
Release images are published to <a href="https://hub.docker.com/r/svrnty/talos-rpi5" target="_blank"><code>docker.io/svrnty/talos-rpi5</code></a> with the format:
```
v<talos>-k<kernel>-<revision>
```
For example: `v1.13.2-k6.12.47-1`
| Segment | Meaning |
|---------|---------|
| `v1.13.2` | Upstream Talos Linux version |
| `k6.12.47` | RPi downstream kernel version |
| `1` | Build revision (bumped for config/patch changes on the same upstream versions) |
## Usage
### Building locally (ARM64 host required)
### Install from raw disk image
Download `metal-arm64.raw.zst` from the [latest release](../../releases/latest) and flash to eMMC:
```bash
make checkouts patches # Clone and patch sources
make kernel # Build RPi kernel
make overlay # Build SBC overlay
make installer # Build installer + disk image
zstd -d metal-arm64.raw.zst -o metal-arm64.raw
# Flash to eMMC/SD via your preferred tool (dd, balenaEtcher, etc.)
```
### CI/CD (Gitea Actions)
Push a version tag to trigger an automated build:
### Upgrade an existing node
```bash
git tag v1.11.5-1
git push origin v1.11.5-1
talosctl upgrade --image docker.io/svrnty/talos-rpi5:v1.13.2-k6.12.47-1 --nodes <node-ip>
```
The pipeline runs on the ARM64 self-hosted runner and:
1. Builds the kernel, overlay, and installer
2. Pushes the installer image to Docker Hub
3. Creates a Gitea release with the raw disk image
In-place upgrades are fully supported. The image includes patches to force GRUB with `--no-nvram` on arm64 (working around the RPi5/CM5 `SetVariableRT` firmware limitation) and to handle the SBC EFI-only disk layout (no separate BOOT partition).
### Upstream update checks
### What's included
A weekly scheduled workflow checks for new Talos and RPi kernel releases and creates Gitea issues when updates are available.
- RPi downstream kernel with CM5/RP1 support (4K page size, aligned with upstream Talos)
- GRUB bootloader with `--no-nvram` for reliable `talosctl upgrade` on RPi5/CM5
- SBC EFI-only boot layout support (probe, install, revert all fall back to EFI partition when BOOT partition is absent)
- Fallback to classic bind mounts on kernels without `open_tree` support (Linux <6.15)
- Overclock: 2.6GHz (`arm_freq=2600`, `over_voltage_delta=50000`, `arm_boost=1`)
- PCIe Gen 3 enabled for NVMe (~800 MB/s, via `dtparam=pciex1_gen=3` in `config.txt`)
- Serial console on GPIO UART0 (`dtoverlay=uart0-pi5`, 115200 baud, even parity)
- Extensions: `iscsi-tools`, `util-linux-tools`
## CI Secrets
## Known issues
| Secret | Description |
|--------|-------------|
| `REGISTRY_USERNAME` | Docker Hub username (org-level) |
| `REGISTRY_PASSWORD` | Docker Hub access token (org-level) |
### Serial console (read-only)
## Runner Setup (Apple Silicon Mac Mini)
The serial console outputs kernel logs, boot messages, and panic traces over GPIO UART0 (`ttyAMA0`) at 115200 baud with **even parity**. Talos Linux has no interactive shell — the console is **read-only** and cannot accept input.
The build runner needs:
- Docker Desktop with Buildx (arm64 native)
- Gitea `act_runner` registered with labels: `self-hosted`, `macOS`, `arm64`
- Sufficient disk space for kernel builds (~20GB)
On Pi5/CM5, GPIO 14/15 are not mapped to UART by default (unlike Pi4). The `dtoverlay=uart0-pi5` device tree overlay is required and is applied via `configTxtAppend` (after `disable-bt` and `disable-wifi` — ordering matters).
#### Wiring (Compute Blade)
Connect a **3.3V** USB-to-UART adapter to the front UART header (3-pin: GND, RX, TX). Only two wires are needed for read-only monitoring:
```
USB-UART Adapter Compute Blade (Front UART)
┌──────────────┐ ┌──────────────┐
│ GND ├──────────┤ GND │
│ RX ├──────────┤ TX │
│ TX │ │ RX │
└──────────────┘ └──────────────┘
3.3V logic 3.3V GPIO
```
- **Adapter RX** connects to **Blade TX** (adapter receives data from the blade)
- **GND** to **GND** (common ground reference)
- Adapter TX is not needed for read-only monitoring (Talos has no shell to send input to)
> **Warning:** CM5 GPIO is **3.3V only**. A 5V logic adapter will crash or damage the board.
Tested with: [USB to TTL Serial Cable (FT232RNL)](https://www.pishop.ca/product/usb-to-ttl-serial-cable-for-raspberry-pi-5-debugging-ft232rnl-chip/) set to 3.3V mode.
#### Reading the console
```bash
# Install act_runner via Homebrew
brew install act_runner
# macOS — use screen with even parity
screen /dev/cu.usbserial-XXXXXXXX 115200,,cse
# Or download directly
curl -sL https://gitea.com/gitea/act_runner/releases/latest/download/act_runner-darwin-arm64 -o act_runner
chmod +x act_runner
# Register
./act_runner register \
--instance https://git.openharbor.io \
--token <runner-token> \
--name mac-mini \
--labels self-hosted,macOS,arm64
# Run as service
./act_runner daemon
# Linux — configure with stty, then read with cat
stty -F /dev/ttyUSB0 115200 cs8 parenb -parodd
cat /dev/ttyUSB0
```
## Structure
*Upstream: <a href="https://github.com/talos-rpi5/talos-builder/issues/4" target="_blank">talos-builder#4</a>*
### Install disk config ignored on SBCs
Talos ignores the `machine.install.disk` config field on SBC platforms. You **must flash the disk image directly** to your target disk (eMMC, SD, NVMe). For NVMe boot, `dd` the metal image to the NVMe drive and configure the EEPROM boot order (`BOOT_ORDER=0xf416`, `PCIE_PROBE=1`).
*Upstream: <a href="https://github.com/talos-rpi5/talos-builder/issues/22" target="_blank">talos-builder#22</a>*
## Patches
| Patch | Target | Description |
|-------|--------|-------------|
| `0001` (pkgs) | Kernel | RPi downstream kernel 6.12.x with CM5/RP1 device tree and driver support |
| `0001` (talos) | Modules | arm64 kernel module list for RPi downstream kernel |
| `0002` (talos) | GRUB | `--no-nvram` for `grub-install` on arm64 (U-Boot lacks EFI `SetVariable`) |
| `0003` (talos) | Bootloader | Force GRUB over sd-boot on arm64 (sd-boot crashes without EFI runtime) |
| `0004` (talos) | Runtime | Fallback to classic bind mounts on kernels without `open_tree` (Linux <6.15) |
| `0005` (talos) | GRUB | Handle missing BOOT partition for SBC EFI-only disk layouts (install path) |
| `0006` (talos) | GRUB | EFI-at-/boot fallback for BOOT-less SBC layouts on the upgrade path |
| `0007` (talos) | Config | Wait up to 5 min for STATE volume on slow-init disks (CM5 eMMC) — prevents maintenance-mode fall-through on `talosctl upgrade` |
| `0008` (talos) | Imager | Respect `--insecure` flag for Overlay and OverlayInstaller assets (build-tool only) |
| `0001` (overlay) | Toolchain | Bump Go to 1.24.13 (CVE fix) |
| `0002` (overlay) | Upgrade | Detect EFI mount path for SBC layouts (no BOOT partition) |
## Roadmap
This project targets production-ready Talos clusters on RPi5/CM5 hardware.
| Status | Milestone | Description |
|--------|-----------|-------------|
| Tested | **4K page size** | Aligned with upstream Talos kernel config. Reduces memory overhead and improves workload compatibility (Longhorn, jemalloc, F2FS, etc.). |
| Tested | **Reliable in-place upgrades** | Force GRUB bootloader with `--no-nvram` on arm64, handle SBC EFI-only disk layout, tolerate slow eMMC init on CM5 (waits up to 5 min for STATE before falling back to maintenance). Verified end-to-end via canonical 3-CP rolling upgrade `v1.12.4 → v1.13.2`. |
| Tested | **Kernel <6.15 compatibility** | Unconditional `open_tree` capability check — falls back to classic bind mounts on RPi downstream kernel 6.12.x. |
| Tested | **Serial console** | GPIO UART0 (`ttyAMA0`) via `dtoverlay=uart0-pi5`. Read-only output at 115200 baud, even parity. Verified on Compute Blade with FT232RNL adapter. |
| Tested | **NVMe boot support** | `dd` image to NVMe + set EEPROM `BOOT_ORDER=0xf416` and `PCIE_PROBE=1`. Verified on 1TB Kingston NVMe on Compute Blade. |
## NVMe boot
The kernel has NVMe built-in (`CONFIG_BLK_DEV_NVME=y`), so booting from NVMe should work by flashing the disk image directly and configuring the RPi5/CM5 EEPROM.
### 1. Flash the image to NVMe
Connect the NVMe drive via a USB adapter and flash:
```bash
zstd -d metal-arm64.raw.zst | sudo dd of=/dev/<nvme-device> bs=4M status=progress
sync
```
.gitea/workflows/
build.yaml # Build pipeline (tag push trigger)
check-updates.yaml # Upstream update checker (weekly cron)
Makefile # Build orchestration
config/
config.txt.append # CM5 overclock settings
extensions.yaml # System extensions list
scripts/
check-upstream.sh # Version comparison script
patches/
siderolabs/
pkgs/0001-*.patch # RPi kernel patch
talos/0001-*.patch # Module list patch
### 2. Configure EEPROM boot order
Use `rpiboot` to update the CM5 EEPROM. Clone the usbboot repo and edit the boot config:
```bash
git clone --depth=1 https://github.com/raspberrypi/usbboot
cd usbboot && make
# Edit the EEPROM config for CM5
cp recovery/boot.conf recovery/boot.conf.bak
```
Add or update these values in `recovery/boot.conf`:
```ini
BOOT_ORDER=0xf416
PCIE_PROBE=1
```
Then flash via USB with the CM5 in USB boot mode (hold nRPIBOOT or disable eMMC boot on your carrier board):
```bash
sudo ./rpiboot -d recovery
```
`BOOT_ORDER` is read right-to-left: try NVMe (`6`) first, then SD (`1`), then USB (`4`), then restart (`f`). `PCIE_PROBE=1` is required for non-HAT+ NVMe adapters (Compute Blade, most M.2 carrier boards).
### 3. Boot from NVMe
Power on. The RPi firmware should find the boot partition on NVMe, load U-Boot, and boot Talos.
### Optional: enable PCIe Gen 3
PCIe Gen 3 doubles NVMe throughput (~400 MB/s → ~800 MB/s). Not officially certified by Raspberry Pi but stable on most NVMe drives.
**New installs** — PCIe Gen 3 is enabled by default in images built from this repo (`config.txt.append` includes `dtparam=pciex1_gen=3`).
**Existing nodes** — After a `talosctl upgrade`, the overlay rewrites `config.txt` with the baked-in settings (including PCIe Gen 3). If you need to enable it manually on an older image:
1. Power off the node and remove the NVMe drive
2. Connect via USB adapter and mount the first (EFI) partition
3. Add to `config.txt` under the `[pi5]` section:
```ini
dtparam=pciex1_gen=3
```
4. Unmount, reinstall the drive, and power on
To verify after boot:
```bash
talosctl -n <ip> dmesg | grep -i pcie
# Look for "Gen 3" in the PCIe link speed output
```
## Reference architecture
Recommended storage layout for production Talos clusters on CM5 Compute Blade hardware. Each CM5 has a 32GB eMMC and an M.2 NVMe slot.
| Role | Boot disk | NVMe | EEPROM `BOOT_ORDER` | Rationale |
|------|-----------|------|---------------------|-----------|
| **Control plane** | NVMe | Talos OS | `0xf416` (NVMe first) | etcd lives on the STATE partition — NVMe gives ~800 MB/s sequential and ~50K random IOPS for fast consensus and snapshot I/O. |
| **Postgres / storage** | eMMC | Data (`/var/mnt/data`) | `0xf214` (eMMC first) | Talos OS on eMMC keeps `talosctl upgrade` away from the data drive. The full 1TB NVMe is dedicated to database storage via `machine.disks`. |
| **Compute workers** | eMMC | None | `0xf214` (eMMC first) | Stateless workloads — no local storage needed. eMMC is more than enough for Talos OS (~2.2GB used). |
### Storage configuration
**Control planes** — no extra config needed. Talos installs to the NVMe automatically when it's the boot disk.
**Postgres / storage nodes** — add `machine.disks` to mount the NVMe as a data volume:
```yaml
machine:
disks:
- device: /dev/nvme0n1
partitions:
- mountpoint: /var/mnt/data
```
Talos automatically partitions, formats (XFS), and mounts the NVMe on first boot. The data persists across `talosctl upgrade` since upgrades only touch the boot disk (eMMC).
**Compute workers** — no storage config needed.
### EEPROM setup
All CM5 modules require `PCIE_PROBE=1` for NVMe detection on Compute Blade (non-HAT+ carrier). Set via `rpiboot`:
```ini
# recovery/boot.conf
BOOT_ORDER=0xf416 # NVMe-first (control planes)
# or
BOOT_ORDER=0xf214 # eMMC-first (storage/compute workers)
PCIE_PROBE=1 # always required
```
### Overclock
All node types share the same overclock config (baked into the image via `config.txt.append`):
```ini
dtparam=pciex1_gen=3
dtoverlay=uart0-pi5
arm_freq=2600
over_voltage_delta=50000
arm_boost=1
```
Verified stable at 44.6°C max under full CPU + memory + disk stress across 10 nodes with Compute Blade heatsinks.
## Building
For local builds, CI/CD setup, runner configuration, and project structure, see [TECHNICAL.md](TECHNICAL.md).
## License
This project is licensed under the [Mozilla Public License 2.0](LICENSE).
It builds upon the following MPL 2.0 licensed upstream projects:
- [siderolabs/talos](https://github.com/siderolabs/talos) — Talos Linux OS
- [siderolabs/pkgs](https://github.com/siderolabs/pkgs) — Talos package definitions
- [talos-rpi5/sbc-raspberrypi5](https://github.com/talos-rpi5/sbc-raspberrypi5) — Raspberry Pi 5 SBC overlay
Our patches to these projects are in the `patches/` directory and are distributed under the same MPL 2.0 terms.

87
TECHNICAL.md Normal file
View File

@ -0,0 +1,87 @@
# Technical Guide
Build infrastructure, CI/CD configuration, and project structure for the Talos CM5 Builder.
## Building locally (ARM64 host required)
```bash
make checkouts patches # Clone and patch upstream sources
make kernel # Build RPi kernel
make overlay # Build SBC overlay
make installer # Build installer + disk image
```
## CI/CD (Gitea Actions)
Push a version tag to trigger an automated build:
```bash
git tag v1.12.3-k6.12.47-2
git push origin v1.12.3-k6.12.47-2
```
The pipeline runs on the ARM64 self-hosted runner and:
1. Builds the kernel, overlay, and installer
2. Attaches SBOM attestation (cosign + syft)
3. Pushes the installer image to Docker Hub
4. Creates a Gitea release with the raw disk image
### Upstream update checks
A weekly scheduled workflow checks for new Talos and RPi kernel releases and creates Gitea issues when updates are available.
## CI Secrets
| Secret | Description |
|--------|-------------|
| `REGISTRY_USERNAME` | Docker Hub username (org-level) |
| `REGISTRY_PASSWORD` | Docker Hub access token (org-level) |
## Runner Setup (Apple Silicon Mac Mini)
The build runner needs:
- Docker Desktop with Buildx (arm64 native)
- Gitea `act_runner` registered with labels: `self-hosted`, `macOS`, `arm64`
- Sufficient disk space for kernel builds (~20GB)
```bash
# Install act_runner via Homebrew
brew install act_runner
# Or download directly
curl -sL https://gitea.com/gitea/act_runner/releases/latest/download/act_runner-darwin-arm64 -o act_runner
chmod +x act_runner
# Register
./act_runner register \
--instance https://git.openharbor.io \
--token <runner-token> \
--name mac-mini \
--labels self-hosted,macOS,arm64
# Run as service
./act_runner daemon
```
## Project Structure
```
.gitea/workflows/
build.yaml # Build pipeline (tag push trigger)
check-updates.yaml # Upstream update checker (weekly cron)
Makefile # Build orchestration
config/
config.txt.append # CM5 overclock settings
extensions.yaml # System extensions list
scripts/
check-upstream.sh # Version comparison script
patches/
siderolabs/
pkgs/0001-*.patch # RPi kernel patch
talos/0001-*.patch # Module list patch
talos/0002-*.patch # Skip NVRAM writes for GRUB on arm64
talos/0003-*.patch # Force GRUB bootloader on arm64
talos-rpi5/
sbc-raspberrypi5/ # Overlay patches (Go toolchain bump)
cosign.pub # Public key for verifying image attestations
```

View File

@ -1,3 +1,8 @@
# Enable PCIe Gen 3 for NVMe (~800 MB/s vs ~400 MB/s Gen 2)
dtparam=pciex1_gen=3
# Enable GPIO UART0 (ttyAMA0) on Pi5/CM5 for serial console
# Must load AFTER disable-bt and disable-wifi overlays in config.txt
dtoverlay=uart0-pi5
# CM5 Overclock — 2.6GHz stable on Compute Blade with heatsink
arm_freq=2600
over_voltage_delta=50000

4
cosign.pub Normal file
View File

@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPkZxXgi280kakXdVwjygCvIs5chd
Ns/gANqNilq0OZDkmcAzeaKJRkRbiDjqNeW1JLv1CYwN/1olypEdVyjLoQ==
-----END PUBLIC KEY-----

View File

@ -1,27 +1,27 @@
From d4788cfac4085fd281d2849cc740a9cbfd83a36b Mon Sep 17 00:00:00 2001
From: Patrick Hunziker <patrick@hunziker.io>
Date: Mon, 22 Sep 2025 18:47:02 +0200
From d60ac2d35158faae78899da5f03479498ac6b317 Mon Sep 17 00:00:00 2001
From: Mathias Beaulieu-Duncan <mathias@svrnty.io>
Date: Sat, 14 Feb 2026 13:14:00 -0500
Subject: [PATCH] Patched for Raspberry Pi 5
---
Pkgfile | 8 +-
kernel/build/config-arm64 | 412 +++++++++++++++++++++++---------------
kernel/build/config-arm64 | 315 ++++++++++++++++++++++++++------------
kernel/build/pkg.yaml | 2 +-
kernel/prepare/pkg.yaml | 6 +-
4 files changed, 263 insertions(+), 165 deletions(-)
4 files changed, 222 insertions(+), 109 deletions(-)
diff --git a/Pkgfile b/Pkgfile
index 8799e13..209c74c 100644
index a272582..ce10086 100644
--- a/Pkgfile
+++ b/Pkgfile
@@ -91,10 +91,10 @@ vars:
kspp_sha256: 3e5f3ea80c6e82afd5550211d240daabf0676e900ca651b3a207c6946e04521d
kspp_sha512: 6ca9521dc15a5897b490a6e2a3e262f09922f0cbf03e1abba4819f9bdee36e2f08fb5acd7c6cb49d50fcd323cdf571222da42f934fa7d8f55c4fa69be5b2b545
@@ -97,10 +97,10 @@ vars:
kspp_sha256: 640b25473f86557d082f680b0f57653a69f4146e97825673bf582f9a4c8b7739
kspp_sha512: 82dae1debbe94a3f82766a8cdbfe59ff8698d433175803458499b76c50b47b89e9280b677a9f16b2a44711badd6f4001aba951a41722a74dd51c03a18b8b9219
- # renovate: datasource=git-tags extractVersion=^v(?<version>.*)$ depName=git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
- linux_version: 6.17.7
- linux_sha256: ddf2ea0d4439e1d57136be3623102af9458f601f5b1cb77e83246e88aea09d0e
- linux_sha512: f16f28c395374099ccf21d9df654a31746ed3f09376f7f9eca172579787b7b493d3878cb0a44348c2846bba93f7950f04b0e45235152860e4789fdd2aa9711cb
- linux_version: 6.18.24
- linux_sha256: c207c557ce58103b4dda30e26da5203f3d8467c6dadc53d709f6d83ae1d1255f
- linux_sha512: ad734fae886272f0c22853c885f618711baa2128b6447d6b996c884a16781893b73c65f5cf58087637a44d33ced1e5ecff9ead2fbca0bbeb7686dbbd4628de98
+ # renovate: datasource=git-tags extractVersion=^v(?<version>.*)$ depName=https://github.com/raspberrypi/linux.git
+ linux_version: stable_20250916
+ linux_sha256: 4639fe79697970b71cf708234b71d855a58ce5e28c377a4f7cf6ecbbe40647f3
@ -30,27 +30,18 @@ index 8799e13..209c74c 100644
# renovate: datasource=git-tags extractVersion=^libaio-(?<version>.*)$ depName=https://pagure.io/libaio.git
libaio_version: 0.3.113
diff --git a/kernel/build/config-arm64 b/kernel/build/config-arm64
index 65b3647..7ba70c0 100644
index b095bcd..1aad7d4 100644
--- a/kernel/build/config-arm64
+++ b/kernel/build/config-arm64
@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
-# Linux/arm64 6.17.7 Kernel Configuration
-# Linux/arm64 6.18.24 Kernel Configuration
+# Linux/arm64 6.12.47 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="gcc (GCC) 15.2.0"
CONFIG_CC_IS_GCC=y
@@ -22,7 +22,7 @@ CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
CONFIG_CC_HAS_COUNTED_BY=y
CONFIG_CC_HAS_MULTIDIMENSIONAL_NONSTRING=y
CONFIG_LD_CAN_USE_KEEP_IN_OVERLAY=y
-CONFIG_PAHOLE_VERSION=130
+CONFIG_PAHOLE_VERSION=129
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_TABLE_SORT=y
CONFIG_THREAD_INFO_IN_TASK=y
@@ -296,6 +296,7 @@ CONFIG_TRACEPOINTS=y
CONFIG_CC_VERSION_TEXT="clang version 22.1.2"
CONFIG_GCC_VERSION=0
@@ -294,6 +294,7 @@ CONFIG_TRACEPOINTS=y
CONFIG_CRASH_RESERVE=y
CONFIG_VMCORE_INFO=y
CONFIG_KEXEC_CORE=y
@ -58,18 +49,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_KEXEC is not set
CONFIG_KEXEC_FILE=y
CONFIG_KEXEC_SIG=y
@@ -450,8 +451,8 @@ CONFIG_ROCKCHIP_ERRATUM_3588001=y
CONFIG_SOCIONEXT_SYNQUACER_PREITS=y
# end of ARM errata workarounds via the alternatives framework
-CONFIG_ARM64_4K_PAGES=y
-# CONFIG_ARM64_16K_PAGES is not set
+# CONFIG_ARM64_4K_PAGES is not set
+CONFIG_ARM64_16K_PAGES=y
# CONFIG_ARM64_64K_PAGES is not set
# CONFIG_ARM64_VA_BITS_39 is not set
CONFIG_ARM64_VA_BITS_48=y
@@ -660,7 +661,7 @@ CONFIG_CPU_FREQ_STAT=y
@@ -665,7 +666,7 @@ CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
@ -78,7 +58,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
@@ -960,7 +961,7 @@ CONFIG_BLK_DEV_WRITE_MOUNTED=y
@@ -976,7 +977,7 @@ CONFIG_BLK_DEV_WRITE_MOUNTED=y
# CONFIG_BLK_DEV_ZONED is not set
CONFIG_BLK_DEV_THROTTLING=y
# CONFIG_BLK_WBT is not set
@ -87,32 +67,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_BLK_CGROUP_FC_APPID is not set
# CONFIG_BLK_CGROUP_IOCOST is not set
# CONFIG_BLK_CGROUP_IOPRIO is not set
@@ -1093,23 +1094,8 @@ CONFIG_COREDUMP=y
#
# Memory Management options
#
-CONFIG_ZPOOL=y
CONFIG_SWAP=y
-CONFIG_ZSWAP=y
-# CONFIG_ZSWAP_DEFAULT_ON is not set
-# CONFIG_ZSWAP_SHRINKER_DEFAULT_ON is not set
-# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set
-# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO is not set
-# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set
-# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set
-# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set
-CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y
-CONFIG_ZSWAP_COMPRESSOR_DEFAULT="zstd"
-CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC=y
-CONFIG_ZSWAP_ZPOOL_DEFAULT="zsmalloc"
-CONFIG_ZSMALLOC=y
-# CONFIG_ZSMALLOC_STAT is not set
-CONFIG_ZSMALLOC_CHAIN_SIZE=8
+# CONFIG_ZSWAP is not set
#
# Slab allocator options
@@ -1198,7 +1184,6 @@ CONFIG_ARCH_HAS_ZONE_DMA_SET=y
@@ -1222,7 +1223,6 @@ CONFIG_ARCH_HAS_ZONE_DMA_SET=y
CONFIG_ZONE_DMA=y
CONFIG_ZONE_DMA32=y
CONFIG_ZONE_DEVICE=y
@ -120,7 +75,7 @@ index 65b3647..7ba70c0 100644
CONFIG_GET_FREE_REGION=y
CONFIG_DEVICE_PRIVATE=y
CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
@@ -1369,7 +1354,7 @@ CONFIG_NETLABEL=y
@@ -1398,7 +1398,7 @@ CONFIG_NETLABEL=y
# CONFIG_MPTCP is not set
CONFIG_NETWORK_SECMARK=y
CONFIG_NET_PTP_CLASSIFY=y
@ -129,7 +84,7 @@ index 65b3647..7ba70c0 100644
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_BRIDGE_NETFILTER=y
@@ -1431,8 +1416,7 @@ CONFIG_NF_TABLES_INET=y
@@ -1460,8 +1460,7 @@ CONFIG_NF_TABLES_INET=y
CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=y
CONFIG_NFT_CT=y
@ -139,7 +94,7 @@ index 65b3647..7ba70c0 100644
CONFIG_NFT_LOG=y
CONFIG_NFT_LIMIT=y
CONFIG_NFT_MASQ=y
@@ -2230,6 +2214,7 @@ CONFIG_TURRIS_MOX_RWTM=y
@@ -2259,6 +2258,7 @@ CONFIG_TURRIS_MOX_RWTM=y
CONFIG_TURRIS_MOX_RWTM_KEYCTL=y
# CONFIG_ARM_FFA_TRANSPORT is not set
# CONFIG_GOOGLE_FIRMWARE is not set
@ -147,7 +102,7 @@ index 65b3647..7ba70c0 100644
#
# EFI (Extensible Firmware Interface) Support
@@ -2413,6 +2398,7 @@ CONFIG_OF_RESERVED_MEM=y
@@ -2442,6 +2442,7 @@ CONFIG_OF_RESERVED_MEM=y
CONFIG_OF_RESOLVE=y
CONFIG_OF_OVERLAY=y
CONFIG_OF_NUMA=y
@ -155,7 +110,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_PARPORT is not set
CONFIG_PNP=y
CONFIG_PNP_DEBUG_MESSAGES=y
@@ -2445,7 +2431,7 @@ CONFIG_BLK_DEV_UBLK=m
@@ -2486,7 +2487,7 @@ CONFIG_BLK_DEV_UBLK=m
#
CONFIG_NVME_AUTH=m
CONFIG_NVME_CORE=y
@ -164,7 +119,7 @@ index 65b3647..7ba70c0 100644
CONFIG_NVME_MULTIPATH=y
# CONFIG_NVME_VERBOSE_ERRORS is not set
CONFIG_NVME_HWMON=y
@@ -2471,6 +2457,7 @@ CONFIG_NVME_TARGET_AUTH=y
@@ -2512,6 +2513,7 @@ CONFIG_NVME_TARGET_AUTH=y
#
# Misc devices
#
@ -172,7 +127,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_AD525X_DPOT is not set
# CONFIG_DUMMY_IRQ is not set
# CONFIG_PHANTOM is not set
@@ -2480,7 +2467,7 @@ CONFIG_NVME_TARGET_AUTH=y
@@ -2521,7 +2523,7 @@ CONFIG_NVME_TARGET_AUTH=y
# CONFIG_ICS932S401 is not set
CONFIG_ENCLOSURE_SERVICES=y
# CONFIG_HI6421V600_IRQ is not set
@ -181,7 +136,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_QCOM_COINCELL is not set
# CONFIG_QCOM_FASTRPC is not set
# CONFIG_APDS9802ALS is not set
@@ -2504,6 +2491,8 @@ CONFIG_SRAM=y
@@ -2545,6 +2547,8 @@ CONFIG_SRAM=y
# CONFIG_MARVELL_CN10K_DPI is not set
# CONFIG_MCHP_LAN966X_PCI is not set
# CONFIG_C2PORT is not set
@ -190,7 +145,7 @@ index 65b3647..7ba70c0 100644
#
# EEPROM support
@@ -2581,7 +2570,7 @@ CONFIG_ISCSI_BOOT_SYSFS=y
@@ -2623,7 +2627,7 @@ CONFIG_ISCSI_BOOT_SYSFS=y
# CONFIG_SCSI_BNX2X_FCOE is not set
# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
@ -199,7 +154,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_3W_SAS is not set
# CONFIG_SCSI_ACARD is not set
@@ -2599,13 +2588,13 @@ CONFIG_SCSI_HISI_SAS_PCI=m
@@ -2641,13 +2645,13 @@ CONFIG_SCSI_HISI_SAS_PCI=m
# CONFIG_SCSI_ESAS2R is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
@ -216,7 +171,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_MYRB is not set
@@ -2655,7 +2644,7 @@ CONFIG_SATA_PMP=y
@@ -2697,7 +2701,7 @@ CONFIG_SATA_PMP=y
#
# Controllers with non-SFF native interface
#
@ -225,7 +180,7 @@ index 65b3647..7ba70c0 100644
CONFIG_SATA_MOBILE_LPM_POLICY=0
CONFIG_SATA_AHCI_PLATFORM=y
# CONFIG_AHCI_BRCM is not set
@@ -2702,7 +2691,7 @@ CONFIG_SATA_RCAR=y
@@ -2744,7 +2748,7 @@ CONFIG_SATA_RCAR=y
# PATA SFF controllers with BMDMA
#
# CONFIG_PATA_ALI is not set
@ -234,7 +189,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_ATP867X is not set
@@ -2717,17 +2706,17 @@ CONFIG_PATA_AMD=m
@@ -2759,17 +2763,17 @@ CONFIG_PATA_AMD=m
# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_JMICRON is not set
@ -255,7 +210,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_PATA_SERVERWORKS is not set
# CONFIG_PATA_SIL680 is not set
# CONFIG_PATA_SIS is not set
@@ -2762,7 +2751,7 @@ CONFIG_MD_RAID0=y
@@ -2806,7 +2810,7 @@ CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_MD_RAID10=y
CONFIG_MD_RAID456=m
@ -264,7 +219,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_BCACHE_DEBUG is not set
# CONFIG_BCACHE_ASYNC_REGISTRATION is not set
CONFIG_BLK_DEV_DM_BUILTIN=y
@@ -2890,7 +2879,7 @@ CONFIG_ATM_DRIVERS=y
@@ -2935,7 +2939,7 @@ CONFIG_ATM_DRIVERS=y
# end of Distributed Switch Architecture drivers
CONFIG_ETHERNET=y
@ -273,7 +228,7 @@ index 65b3647..7ba70c0 100644
CONFIG_NET_VENDOR_3COM=y
# CONFIG_VORTEX is not set
# CONFIG_TYPHOON is not set
@@ -2918,7 +2907,7 @@ CONFIG_AMD_XGBE=y
@@ -2963,7 +2967,7 @@ CONFIG_AMD_XGBE=y
CONFIG_NET_XGENE=y
# CONFIG_NET_XGENE_V2 is not set
CONFIG_NET_VENDOR_AQUANTIA=y
@ -282,7 +237,7 @@ index 65b3647..7ba70c0 100644
CONFIG_NET_VENDOR_ARC=y
# CONFIG_EMAC_ROCKCHIP is not set
CONFIG_NET_VENDOR_ASIX=y
@@ -2932,16 +2921,16 @@ CONFIG_ALX=m
@@ -2977,16 +2981,16 @@ CONFIG_ALX=m
CONFIG_NET_VENDOR_BROADCOM=y
# CONFIG_B44 is not set
CONFIG_BCMGENET=y
@ -303,7 +258,7 @@ index 65b3647..7ba70c0 100644
CONFIG_BNXT_SRIOV=y
CONFIG_BNXT_FLOWER_OFFLOAD=y
# CONFIG_BNXT_DCB is not set
@@ -2957,7 +2946,7 @@ CONFIG_NET_VENDOR_CAVIUM=y
@@ -3002,7 +3006,7 @@ CONFIG_NET_VENDOR_CAVIUM=y
# CONFIG_THUNDER_NIC_VF is not set
# CONFIG_THUNDER_NIC_BGX is not set
# CONFIG_THUNDER_NIC_RGX is not set
@ -312,7 +267,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_LIQUIDIO is not set
# CONFIG_LIQUIDIO_VF is not set
CONFIG_NET_VENDOR_CHELSIO=y
@@ -2970,7 +2959,7 @@ CONFIG_CHELSIO_T4VF=m
@@ -3015,7 +3019,7 @@ CONFIG_CHELSIO_T4VF=m
CONFIG_CHELSIO_INLINE_CRYPTO=y
CONFIG_CHELSIO_IPSEC_INLINE=m
CONFIG_NET_VENDOR_CISCO=y
@ -321,52 +276,7 @@ index 65b3647..7ba70c0 100644
CONFIG_NET_VENDOR_CORTINA=y
# CONFIG_GEMINI_ETHERNET is not set
CONFIG_NET_VENDOR_DAVICOM=y
@@ -3029,30 +3018,29 @@ CONFIG_NET_VENDOR_HUAWEI=y
# CONFIG_HINIC3 is not set
CONFIG_NET_VENDOR_I825XX=y
CONFIG_NET_VENDOR_INTEL=y
-CONFIG_LIBETH=m
-CONFIG_LIBIE=m
-CONFIG_LIBIE_ADMINQ=m
-CONFIG_E100=m
-CONFIG_E1000=m
-CONFIG_E1000E=m
-CONFIG_IGB=m
+CONFIG_LIBETH=y
+CONFIG_LIBIE=y
+CONFIG_E100=y
+CONFIG_E1000=y
+CONFIG_E1000E=y
+CONFIG_IGB=y
CONFIG_IGB_HWMON=y
-CONFIG_IGBVF=m
-CONFIG_IXGBE=m
+CONFIG_IGBVF=y
+CONFIG_IXGBE=y
CONFIG_IXGBE_HWMON=y
# CONFIG_IXGBE_DCB is not set
CONFIG_IXGBE_IPSEC=y
-CONFIG_IXGBEVF=m
+CONFIG_IXGBEVF=y
CONFIG_IXGBEVF_IPSEC=y
-CONFIG_I40E=m
+CONFIG_I40E=y
# CONFIG_I40E_DCB is not set
-CONFIG_IAVF=m
-CONFIG_I40EVF=m
-CONFIG_ICE=m
+CONFIG_IAVF=y
+CONFIG_I40EVF=y
+CONFIG_ICE=y
CONFIG_ICE_HWMON=y
CONFIG_ICE_SWITCHDEV=y
# CONFIG_FM10K is not set
-CONFIG_IGC=m
+CONFIG_IGC=y
# CONFIG_IDPF is not set
# CONFIG_JME is not set
CONFIG_NET_VENDOR_ADI=y
@@ -3066,7 +3054,7 @@ CONFIG_MVPP2=y
@@ -3114,7 +3118,7 @@ CONFIG_MVPP2=y
# CONFIG_MVPP2_PTP is not set
# CONFIG_PXA168_ETH is not set
# CONFIG_SKGE is not set
@ -375,7 +285,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_SKY2_DEBUG is not set
# CONFIG_OCTEONTX2_AF is not set
# CONFIG_OCTEONTX2_PF is not set
@@ -3147,15 +3135,15 @@ CONFIG_NET_VENDOR_PENSANDO=y
@@ -3198,15 +3202,15 @@ CONFIG_NET_VENDOR_PENSANDO=y
# CONFIG_IONIC is not set
CONFIG_NET_VENDOR_QLOGIC=y
# CONFIG_QLA3XXX is not set
@ -394,7 +304,7 @@ index 65b3647..7ba70c0 100644
CONFIG_QED_FCOE=y
CONFIG_NET_VENDOR_BROCADE=y
# CONFIG_BNA is not set
@@ -3167,12 +3155,12 @@ CONFIG_NET_VENDOR_RDC=y
@@ -3219,12 +3223,12 @@ CONFIG_NET_VENDOR_RDC=y
# CONFIG_R6040 is not set
CONFIG_NET_VENDOR_REALTEK=y
# CONFIG_8139CP is not set
@ -409,44 +319,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_RTASE is not set
CONFIG_NET_VENDOR_RENESAS=y
# CONFIG_SH_ETH is not set
@@ -3209,23 +3197,22 @@ CONFIG_SMSC911X=y
CONFIG_NET_VENDOR_SOCIONEXT=y
# CONFIG_SNI_NETSEC is not set
CONFIG_NET_VENDOR_STMICRO=y
-CONFIG_STMMAC_ETH=m
+CONFIG_STMMAC_ETH=y
# CONFIG_STMMAC_SELFTESTS is not set
-CONFIG_STMMAC_PLATFORM=m
-CONFIG_DWMAC_DWC_QOS_ETH=m
-CONFIG_DWMAC_GENERIC=m
-CONFIG_DWMAC_IPQ806X=m
+CONFIG_STMMAC_PLATFORM=y
+CONFIG_DWMAC_DWC_QOS_ETH=y
+CONFIG_DWMAC_GENERIC=y
+CONFIG_DWMAC_IPQ806X=y
# CONFIG_DWMAC_MEDIATEK is not set
-CONFIG_DWMAC_MESON=m
-CONFIG_DWMAC_QCOM_ETHQOS=m
-CONFIG_DWMAC_RENESAS_GBETH=m
-CONFIG_DWMAC_ROCKCHIP=m
-CONFIG_DWMAC_SUNXI=m
-CONFIG_DWMAC_SUN8I=m
-CONFIG_DWMAC_IMX8=m
+CONFIG_DWMAC_MESON=y
+CONFIG_DWMAC_QCOM_ETHQOS=y
+CONFIG_DWMAC_ROCKCHIP=y
+CONFIG_DWMAC_SUNXI=y
+CONFIG_DWMAC_SUN8I=y
+CONFIG_DWMAC_IMX8=y
# CONFIG_DWMAC_INTEL_PLAT is not set
-CONFIG_DWMAC_TEGRA=m
-CONFIG_STMMAC_PCI=m
+CONFIG_DWMAC_TEGRA=y
+CONFIG_STMMAC_PCI=y
CONFIG_NET_VENDOR_SUN=y
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
@@ -3330,7 +3317,7 @@ CONFIG_TERANETICS_PHY=y
@@ -3384,7 +3388,7 @@ CONFIG_TERANETICS_PHY=y
CONFIG_DP83822_PHY=y
CONFIG_DP83TC811_PHY=y
CONFIG_DP83848_PHY=y
@ -455,16 +328,7 @@ index 65b3647..7ba70c0 100644
CONFIG_DP83869_PHY=y
# CONFIG_DP83TD510_PHY is not set
# CONFIG_DP83TG720_PHY is not set
@@ -3370,7 +3357,7 @@ CONFIG_MDIO_BUS_MUX_MMIOREG=y
#
# PCS device drivers
#
-CONFIG_PCS_XPCS=m
+CONFIG_PCS_XPCS=y
# end of PCS device drivers
# CONFIG_PPP is not set
@@ -3380,7 +3367,7 @@ CONFIG_USB_NET_DRIVERS=y
@@ -3433,7 +3437,7 @@ CONFIG_USB_NET_DRIVERS=y
# CONFIG_USB_KAWETH is not set
CONFIG_USB_PEGASUS=y
CONFIG_USB_RTL8150=y
@ -473,7 +337,7 @@ index 65b3647..7ba70c0 100644
CONFIG_USB_LAN78XX=y
CONFIG_USB_USBNET=m
CONFIG_USB_NET_AX8817X=m
@@ -3430,7 +3417,7 @@ CONFIG_USB_RTL8153_ECM=m
@@ -3483,7 +3487,7 @@ CONFIG_USB_RTL8153_ECM=m
# end of Wireless WAN
CONFIG_XEN_NETDEV_FRONTEND=y
@ -482,7 +346,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_FUJITSU_ES is not set
CONFIG_USB4_NET=m
CONFIG_HYPERV_NET=y
@@ -3701,6 +3688,8 @@ CONFIG_HYPERV_KEYBOARD=y
@@ -3756,6 +3760,8 @@ CONFIG_HYPERV_KEYBOARD=y
#
# Character devices
#
@ -491,7 +355,7 @@ index 65b3647..7ba70c0 100644
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
@@ -3793,6 +3782,7 @@ CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
@@ -3848,6 +3854,7 @@ CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
CONFIG_SERIAL_MVEBU_UART=y
CONFIG_SERIAL_MVEBU_CONSOLE=y
# CONFIG_SERIAL_OWL is not set
@ -499,7 +363,7 @@ index 65b3647..7ba70c0 100644
# end of Serial drivers
CONFIG_SERIAL_MCTRL_GPIO=y
@@ -3868,6 +3858,7 @@ CONFIG_TCG_CRB=y
@@ -3923,6 +3930,7 @@ CONFIG_TCG_CRB=y
# CONFIG_TCG_TIS_ST33ZP24_SPI is not set
# CONFIG_XILLYBUS is not set
# CONFIG_XILLYUSB is not set
@ -507,7 +371,7 @@ index 65b3647..7ba70c0 100644
# end of Character devices
#
@@ -3877,7 +3868,7 @@ CONFIG_I2C=y
@@ -3932,7 +3940,7 @@ CONFIG_I2C=y
CONFIG_ACPI_I2C_OPREGION=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
@ -516,7 +380,7 @@ index 65b3647..7ba70c0 100644
#
# Multiplexer I2C Chip support
@@ -3896,7 +3887,7 @@ CONFIG_I2C_MUX=m
@@ -3951,7 +3959,7 @@ CONFIG_I2C_MUX=m
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_SMBUS=y
@ -525,7 +389,7 @@ index 65b3647..7ba70c0 100644
#
# I2C Hardware Bus support
@@ -3906,6 +3897,7 @@ CONFIG_I2C_ALGOBIT=m
@@ -3961,6 +3969,7 @@ CONFIG_I2C_ALGOBIT=m
# PC SMBus host controller drivers
#
CONFIG_I2C_CCGX_UCSI=y
@ -533,7 +397,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
@@ -3913,7 +3905,7 @@ CONFIG_I2C_CCGX_UCSI=y
@@ -3968,7 +3977,7 @@ CONFIG_I2C_CCGX_UCSI=y
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_AMD_MP2 is not set
# CONFIG_I2C_HIX5HD2 is not set
@ -542,7 +406,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
@@ -4029,7 +4021,7 @@ CONFIG_SPI_BCM_QSPI=y
@@ -4085,7 +4094,7 @@ CONFIG_SPI_BCM_QSPI=y
# CONFIG_SPI_HISI_KUNPENG is not set
# CONFIG_SPI_HISI_SFC_V3XX is not set
# CONFIG_SPI_NXP_FLEXSPI is not set
@ -551,7 +415,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_SPI_IMX is not set
# CONFIG_SPI_FSL_SPI is not set
# CONFIG_SPI_FSL_DSPI is not set
@@ -4046,6 +4038,7 @@ CONFIG_SPI_ORION=y
@@ -4101,6 +4110,7 @@ CONFIG_SPI_ORION=y
CONFIG_SPI_PL022=y
CONFIG_SPI_ROCKCHIP=y
# CONFIG_SPI_ROCKCHIP_SFC is not set
@ -559,7 +423,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_SPI_RSPI is not set
# CONFIG_SPI_RZV2H_RSPI is not set
# CONFIG_SPI_RZV2M_CSI is not set
@@ -4142,7 +4135,7 @@ CONFIG_PINCTRL_AXP209=y
@@ -4199,7 +4209,7 @@ CONFIG_PINCTRL_AXP209=y
CONFIG_PINCTRL_BM1880=y
# CONFIG_PINCTRL_CY8C95X0 is not set
CONFIG_PINCTRL_MAX77620=y
@ -568,17 +432,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set
# CONFIG_PINCTRL_OCELOT is not set
CONFIG_PINCTRL_RK805=y
@@ -4152,7 +4145,9 @@ CONFIG_PINCTRL_SINGLE=y
# CONFIG_PINCTRL_STMFX is not set
# CONFIG_PINCTRL_SX150X is not set
CONFIG_PINCTRL_ZYNQMP=y
+CONFIG_PINCTRL_RP1=y
# CONFIG_PINCTRL_OWL is not set
+CONFIG_PINCTRL_BCM2712=y
CONFIG_PINCTRL_BCM2835=y
CONFIG_PINCTRL_IPROC_GPIO=y
CONFIG_PINCTRL_NS2_MUX=y
@@ -4332,6 +4327,7 @@ CONFIG_GPIO_GENERIC=y
@@ -4395,6 +4405,7 @@ CONFIG_GPIO_GENERIC=y
# CONFIG_GPIO_AMDPT is not set
CONFIG_GPIO_RASPBERRYPI_EXP=y
CONFIG_GPIO_BCM_XGS_IPROC=y
@ -586,7 +440,7 @@ index 65b3647..7ba70c0 100644
CONFIG_GPIO_BRCMSTB=y
# CONFIG_GPIO_CADENCE is not set
# CONFIG_GPIO_DAVINCI is not set
@@ -4349,7 +4345,7 @@ CONFIG_GPIO_DWAPB=y
@@ -4412,7 +4423,7 @@ CONFIG_GPIO_DWAPB=y
CONFIG_GPIO_MVEBU=y
CONFIG_GPIO_MXC=y
CONFIG_GPIO_PL061=y
@ -595,7 +449,7 @@ index 65b3647..7ba70c0 100644
CONFIG_GPIO_RCAR=y
CONFIG_GPIO_ROCKCHIP=y
CONFIG_GPIO_RTD=y
@@ -4388,6 +4384,7 @@ CONFIG_GPIO_PCA953X_IRQ=y
@@ -4451,6 +4462,7 @@ CONFIG_GPIO_PCA953X_IRQ=y
#
# MFD GPIO expanders
#
@ -603,7 +457,7 @@ index 65b3647..7ba70c0 100644
CONFIG_GPIO_MAX77620=y
# end of MFD GPIO expanders
@@ -4457,6 +4454,7 @@ CONFIG_POWER_RESET_SYSCON=y
@@ -4520,6 +4532,7 @@ CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
CONFIG_POWER_SUPPLY_HWMON=y
@ -611,7 +465,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_GENERIC_ADC_BATTERY is not set
# CONFIG_IP5XXX_POWER is not set
# CONFIG_TEST_POWER is not set
@@ -4741,7 +4739,7 @@ CONFIG_AMLOGIC_THERMAL=y
@@ -4804,7 +4817,7 @@ CONFIG_AMLOGIC_THERMAL=y
# Broadcom thermal drivers
#
CONFIG_BCM2711_THERMAL=y
@ -620,7 +474,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_BRCMSTB_THERMAL is not set
CONFIG_BCM_NS_THERMAL=y
CONFIG_BCM_SR_THERMAL=y
@@ -4917,6 +4915,7 @@ CONFIG_MFD_MAX77620=y
@@ -4983,6 +4996,7 @@ CONFIG_MFD_MAX77620=y
# CONFIG_MFD_QCOM_RPM is not set
CONFIG_MFD_SPMI_PMIC=y
# CONFIG_MFD_SY7636A is not set
@ -628,15 +482,15 @@ index 65b3647..7ba70c0 100644
# CONFIG_MFD_RDC321X is not set
# CONFIG_MFD_RT4831 is not set
# CONFIG_MFD_RT5033 is not set
@@ -4980,6 +4979,7 @@ CONFIG_MFD_SYSCON=y
# CONFIG_MFD_KHADAS_MCU is not set
# CONFIG_MFD_QCOM_PM8008 is not set
# CONFIG_MFD_INTEL_M10_BMC_SPI is not set
@@ -5001,6 +5015,7 @@ CONFIG_MFD_RK8XX_SPI=y
# CONFIG_MFD_STMPE is not set
CONFIG_MFD_SUN6I_PRCM=y
CONFIG_MFD_SYSCON=y
+CONFIG_MFD_RP1=y
# CONFIG_MFD_RSMU_I2C is not set
# CONFIG_MFD_RSMU_SPI is not set
# end of Multifunction device drivers
@@ -5046,6 +5046,7 @@ CONFIG_REGULATOR_QCOM_SPMI=y
# CONFIG_MFD_TI_AM335X_TSCADC is not set
# CONFIG_MFD_LP3943 is not set
# CONFIG_MFD_LP8788 is not set
@@ -5118,6 +5133,7 @@ CONFIG_REGULATOR_QCOM_SPMI=y
# CONFIG_REGULATOR_RAA215300 is not set
# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set
# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2 is not set
@ -644,7 +498,7 @@ index 65b3647..7ba70c0 100644
CONFIG_REGULATOR_RK808=y
# CONFIG_REGULATOR_RT4801 is not set
# CONFIG_REGULATOR_RT4803 is not set
@@ -5179,6 +5180,7 @@ CONFIG_V4L_MEM2MEM_DRIVERS=y
@@ -5252,6 +5268,7 @@ CONFIG_V4L_MEM2MEM_DRIVERS=y
#
# Atmel media platform drivers
#
@ -652,7 +506,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_VIDEO_BCM2835_UNICAM is not set
#
@@ -5241,6 +5243,7 @@ CONFIG_V4L_MEM2MEM_DRIVERS=y
@@ -5314,6 +5331,7 @@ CONFIG_V4L_MEM2MEM_DRIVERS=y
#
# Raspberry Pi media platform drivers
#
@ -660,7 +514,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_VIDEO_RASPBERRYPI_PISP_BE is not set
# CONFIG_VIDEO_RP1_CFE is not set
@@ -5317,9 +5320,13 @@ CONFIG_VIDEOBUF2_VMALLOC=m
@@ -5390,9 +5408,13 @@ CONFIG_VIDEOBUF2_VMALLOC=m
# CONFIG_VIDEO_THP7312 is not set
# end of Camera ISPs
@ -675,7 +529,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_VIDEO_DW9714 is not set
# CONFIG_VIDEO_DW9719 is not set
# CONFIG_VIDEO_DW9768 is not set
@@ -5388,6 +5395,7 @@ CONFIG_VIDEO_CAMERA_LENS=y
@@ -5461,6 +5483,7 @@ CONFIG_VIDEO_CAMERA_LENS=y
# CONFIG_VIDEO_TW9903 is not set
# CONFIG_VIDEO_TW9906 is not set
# CONFIG_VIDEO_TW9910 is not set
@ -683,7 +537,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_VIDEO_VPX3220 is not set
#
@@ -5510,7 +5518,6 @@ CONFIG_DRM_DISPLAY_HDMI_HELPER=y
@@ -5583,7 +5606,6 @@ CONFIG_DRM_DISPLAY_HDMI_HELPER=y
CONFIG_DRM_DISPLAY_HDMI_STATE_HELPER=y
CONFIG_DRM_TTM=m
CONFIG_DRM_EXEC=m
@ -691,7 +545,7 @@ index 65b3647..7ba70c0 100644
CONFIG_DRM_BUDDY=m
CONFIG_DRM_VRAM_HELPER=m
CONFIG_DRM_TTM_HELPER=m
@@ -5629,6 +5636,7 @@ CONFIG_DRM_PANEL=y
@@ -5702,6 +5724,7 @@ CONFIG_DRM_PANEL=y
# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set
# CONFIG_DRM_PANEL_ILITEK_ILI9805 is not set
# CONFIG_DRM_PANEL_ILITEK_ILI9806E is not set
@ -699,7 +553,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set
# CONFIG_DRM_PANEL_ILITEK_ILI9882T is not set
# CONFIG_DRM_PANEL_INNOLUX_EJ030NA is not set
@@ -5706,6 +5714,7 @@ CONFIG_DRM_PANEL_SIMPLE=y
@@ -5780,6 +5803,7 @@ CONFIG_DRM_PANEL_SIMPLE=y
# CONFIG_DRM_PANEL_SUMMIT is not set
# CONFIG_DRM_PANEL_SYNAPTICS_R63353 is not set
# CONFIG_DRM_PANEL_TDO_TL070WSH30 is not set
@ -707,7 +561,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set
# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set
# CONFIG_DRM_PANEL_TPO_TPG110 is not set
@@ -5715,6 +5724,8 @@ CONFIG_DRM_PANEL_SIMPLE=y
@@ -5789,6 +5813,8 @@ CONFIG_DRM_PANEL_SIMPLE=y
# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set
# CONFIG_DRM_PANEL_VISIONOX_RM692E5 is not set
# CONFIG_DRM_PANEL_VISIONOX_VTDR6130 is not set
@ -716,7 +570,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set
# CONFIG_DRM_PANEL_XINPENG_XPP055C272 is not set
# end of Display Panels
@@ -5817,7 +5828,7 @@ CONFIG_DRM_MESON_DW_MIPI_DSI=y
@@ -5894,7 +5920,7 @@ CONFIG_DRM_MESON_DW_MIPI_DSI=y
# CONFIG_DRM_XEN_FRONTEND is not set
# CONFIG_DRM_LIMA is not set
CONFIG_DRM_PANFROST=m
@ -725,15 +579,15 @@ index 65b3647..7ba70c0 100644
# CONFIG_DRM_TIDSS is not set
# CONFIG_DRM_GUD is not set
# CONFIG_DRM_ST7571_I2C is not set
@@ -5834,6 +5845,7 @@ CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
@@ -5911,6 +5937,7 @@ CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
# Frame buffer Devices
#
CONFIG_FB=y
+CONFIG_FB_BCM2708=y
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_IMX is not set
@@ -5875,6 +5887,7 @@ CONFIG_FB_HYPERV=y
# CONFIG_FB_CYBER2000 is not set
@@ -5951,6 +5978,7 @@ CONFIG_FB_HYPERV=y
CONFIG_FB_SIMPLE=y
# CONFIG_FB_SSD1307 is not set
# CONFIG_FB_SM712 is not set
@ -741,7 +595,7 @@ index 65b3647..7ba70c0 100644
CONFIG_FB_CORE=y
CONFIG_FB_NOTIFY=y
CONFIG_FB_DEVICE=y
@@ -5907,6 +5920,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y
@@ -5983,6 +6011,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_KTD2801 is not set
# CONFIG_BACKLIGHT_KTZ8866 is not set
# CONFIG_BACKLIGHT_PWM is not set
@ -749,7 +603,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_BACKLIGHT_QCOM_WLED is not set
# CONFIG_BACKLIGHT_ADP8860 is not set
# CONFIG_BACKLIGHT_ADP8870 is not set
@@ -5994,7 +6008,55 @@ CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y
@@ -6071,7 +6100,55 @@ CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y
# CONFIG_SND_USB_VARIAX is not set
CONFIG_SND_SOC=m
CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
@ -806,7 +660,7 @@ index 65b3647..7ba70c0 100644
#
# Analog Devices
@@ -6130,15 +6192,17 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
@@ -6207,15 +6284,17 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
# CONFIG_SND_MESON_G12A_TOACODEC is not set
# CONFIG_SND_MESON_G12A_TOHDMITX is not set
# CONFIG_SND_SOC_MESON_T9015 is not set
@ -827,7 +681,7 @@ index 65b3647..7ba70c0 100644
#
# Renesas
#
@@ -6222,6 +6286,8 @@ CONFIG_SND_SOC_I2C_AND_SPI=m
@@ -6299,6 +6378,8 @@ CONFIG_SND_SOC_I2C_AND_SPI=m
# CODEC drivers
#
# CONFIG_SND_SOC_AC97_CODEC is not set
@ -836,7 +690,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_SND_SOC_ADAU1372_I2C is not set
# CONFIG_SND_SOC_ADAU1372_SPI is not set
# CONFIG_SND_SOC_ADAU1373 is not set
@@ -6302,6 +6368,7 @@ CONFIG_SND_SOC_HDMI_CODEC=m
@@ -6380,6 +6461,7 @@ CONFIG_SND_SOC_HDMI_CODEC=m
# CONFIG_SND_SOC_ICS43432 is not set
# CONFIG_SND_SOC_IDT821034 is not set
# CONFIG_SND_SOC_INNO_RK3036 is not set
@ -844,7 +698,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_SND_SOC_MAX98088 is not set
# CONFIG_SND_SOC_MAX98090 is not set
# CONFIG_SND_SOC_MAX98357A is not set
@@ -6432,6 +6499,7 @@ CONFIG_SND_SOC_HDMI_CODEC=m
@@ -6512,6 +6594,7 @@ CONFIG_SND_SOC_HDMI_CODEC=m
# CONFIG_SND_SOC_LPASS_VA_MACRO is not set
# CONFIG_SND_SOC_LPASS_RX_MACRO is not set
# CONFIG_SND_SOC_LPASS_TX_MACRO is not set
@ -852,7 +706,7 @@ index 65b3647..7ba70c0 100644
# end of CODEC drivers
#
@@ -6455,18 +6523,18 @@ CONFIG_HID_GENERIC=y
@@ -6536,18 +6619,18 @@ CONFIG_HID_GENERIC=y
#
# Special HID drivers
#
@ -876,7 +730,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_HID_CORSAIR is not set
# CONFIG_HID_COUGAR is not set
# CONFIG_HID_MACALLY is not set
@@ -6474,14 +6542,14 @@ CONFIG_HID_CHICONY=m
@@ -6555,14 +6638,14 @@ CONFIG_HID_CHICONY=m
# CONFIG_HID_CMEDIA is not set
# CONFIG_HID_CP2112 is not set
# CONFIG_HID_CREATIVE_SB0540 is not set
@ -893,7 +747,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_HID_FT260 is not set
# CONFIG_HID_GEMBIRD is not set
# CONFIG_HID_GFRM is not set
@@ -6499,17 +6567,17 @@ CONFIG_HID_EZKEY=m
@@ -6580,17 +6663,17 @@ CONFIG_HID_EZKEY=m
# CONFIG_HID_VIEWSONIC is not set
# CONFIG_HID_VRC2 is not set
# CONFIG_HID_XIAOMI is not set
@ -915,29 +769,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_HID_LOGITECH_DJ is not set
# CONFIG_HID_LOGITECH_HIDPP is not set
CONFIG_LOGITECH_FF=y
@@ -6521,17 +6589,17 @@ CONFIG_LOGIWHEELS_FF=y
# CONFIG_HID_MAYFLASH is not set
# CONFIG_HID_MEGAWORLD_FF is not set
CONFIG_HID_REDRAGON=y
-CONFIG_HID_MICROSOFT=m
-CONFIG_HID_MONTEREY=m
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
# CONFIG_HID_MULTITOUCH is not set
# CONFIG_HID_NINTENDO is not set
# CONFIG_HID_NTI is not set
# CONFIG_HID_NTRIG is not set
# CONFIG_HID_ORTEK is not set
-CONFIG_HID_PANTHERLORD=m
+CONFIG_HID_PANTHERLORD=y
CONFIG_PANTHERLORD_FF=y
# CONFIG_HID_PENMOUNT is not set
-CONFIG_HID_PETALYNX=m
+CONFIG_HID_PETALYNX=y
# CONFIG_HID_PICOLCD is not set
# CONFIG_HID_PLANTRONICS is not set
# CONFIG_HID_PLAYSTATION is not set
@@ -6541,20 +6609,20 @@ CONFIG_HID_PETALYNX=m
@@ -6622,20 +6705,20 @@ CONFIG_HID_PETALYNX=m
# CONFIG_HID_RETRODE is not set
# CONFIG_HID_ROCCAT is not set
# CONFIG_HID_SAITEK is not set
@ -961,7 +793,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_HID_TOPRE is not set
# CONFIG_HID_THINGM is not set
# CONFIG_HID_THRUSTMASTER is not set
@@ -6653,6 +6721,7 @@ CONFIG_USB_OHCI_HCD_PLATFORM=y
@@ -6734,6 +6817,7 @@ CONFIG_USB_OHCI_HCD_PLATFORM=y
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_RENESAS_USBHS_HCD is not set
@ -969,7 +801,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_USB_HCD_TEST_MODE is not set
# CONFIG_USB_XEN_HCD is not set
CONFIG_USB_RENESAS_USBHS=y
@@ -6761,13 +6830,13 @@ CONFIG_USB_SERIAL_GENERIC=y
@@ -6843,13 +6927,13 @@ CONFIG_USB_SERIAL_GENERIC=y
# CONFIG_USB_SERIAL_AIRCABLE is not set
# CONFIG_USB_SERIAL_ARK3116 is not set
# CONFIG_USB_SERIAL_BELKIN is not set
@ -986,7 +818,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_USB_SERIAL_VISOR is not set
# CONFIG_USB_SERIAL_IPAQ is not set
# CONFIG_USB_SERIAL_IR is not set
@@ -6788,7 +6857,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -6870,7 +6954,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
# CONFIG_USB_SERIAL_MOS7840 is not set
# CONFIG_USB_SERIAL_MXUPORT is not set
# CONFIG_USB_SERIAL_NAVMAN is not set
@ -995,7 +827,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_USB_SERIAL_OTI6858 is not set
# CONFIG_USB_SERIAL_QCAUX is not set
# CONFIG_USB_SERIAL_QUALCOMM is not set
@@ -6992,31 +7061,32 @@ CONFIG_MMC_BLOCK_MINORS=32
@@ -7074,31 +7158,32 @@ CONFIG_MMC_BLOCK_MINORS=32
#
# MMC/SD/SDIO Host Controller Drivers
#
@ -1040,7 +872,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_MMC_MXC is not set
# CONFIG_MMC_TIFM_SD is not set
CONFIG_MMC_SPI=y
@@ -7046,8 +7116,8 @@ CONFIG_MMC_CQHCI=y
@@ -7128,8 +7213,8 @@ CONFIG_MMC_CQHCI=y
# CONFIG_MMC_TOSHIBA_PCI is not set
CONFIG_MMC_BCM2835=y
# CONFIG_MMC_MTK is not set
@ -1051,7 +883,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_MMC_SDHCI_AM654 is not set
# CONFIG_MMC_OWL is not set
# CONFIG_SCSI_UFSHCD is not set
@@ -7140,28 +7210,26 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
@@ -7222,28 +7307,26 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
#
# CONFIG_LEDS_TRIGGER_TRANSIENT is not set
# CONFIG_LEDS_TRIGGER_CAMERA is not set
@ -1084,7 +916,7 @@ index 65b3647..7ba70c0 100644
CONFIG_INFINIBAND_HNS_HIP08=m
CONFIG_INFINIBAND_IRDMA=m
CONFIG_MLX4_INFINIBAND=m
@@ -7219,6 +7287,7 @@ CONFIG_RTC_INTF_DEV=y
@@ -7302,6 +7385,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_ABB5ZES3 is not set
# CONFIG_RTC_DRV_ABEOZ9 is not set
# CONFIG_RTC_DRV_ABX80X is not set
@ -1092,7 +924,7 @@ index 65b3647..7ba70c0 100644
CONFIG_RTC_DRV_BRCMSTB=y
CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_DS1307_CENTURY is not set
@@ -7371,6 +7440,7 @@ CONFIG_PL330_DMA=y
@@ -7454,6 +7538,7 @@ CONFIG_PL330_DMA=y
CONFIG_TEGRA186_GPC_DMA=y
CONFIG_TEGRA20_APB_DMA=y
CONFIG_TEGRA210_ADMA=y
@ -1100,7 +932,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_XGENE_DMA is not set
# CONFIG_XILINX_DMA is not set
# CONFIG_XILINX_XDMA is not set
@@ -7459,17 +7529,17 @@ CONFIG_VMGENID=y
@@ -7543,17 +7628,17 @@ CONFIG_VMGENID=y
# CONFIG_ARM_CCA_GUEST is not set
CONFIG_VIRTIO_ANCHOR=y
CONFIG_VIRTIO=y
@ -1124,16 +956,15 @@ index 65b3647..7ba70c0 100644
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
CONFIG_VIRTIO_DMA_SHARED_BUFFER=y
# CONFIG_VIRTIO_DEBUG is not set
@@ -7563,6 +7633,8 @@ CONFIG_COMMON_CLK=y
# CONFIG_COMMON_CLK_MAX77686 is not set
@@ -7650,6 +7735,7 @@ CONFIG_COMMON_CLK=y
# CONFIG_COMMON_CLK_MAX9485 is not set
CONFIG_COMMON_CLK_RK808=y
+CONFIG_COMMON_CLK_RP1=y
CONFIG_COMMON_CLK_RP1=y
+CONFIG_COMMON_CLK_RP1_SDIO=y
CONFIG_COMMON_CLK_HI655X=y
CONFIG_COMMON_CLK_SCMI=y
CONFIG_COMMON_CLK_SCPI=y
@@ -8065,6 +8137,8 @@ CONFIG_TEGRA_IOMMU_SMMU=y
@@ -8171,6 +8257,8 @@ CONFIG_TEGRA_IOMMU_SMMU=y
# CONFIG_MTK_IOMMU is not set
# CONFIG_VIRTIO_IOMMU is not set
# CONFIG_SPRD_IOMMU is not set
@ -1142,11 +973,10 @@ index 65b3647..7ba70c0 100644
#
# Remoteproc drivers
@@ -8961,13 +9035,13 @@ CONFIG_PWM=y
# CONFIG_PWM_ATMEL_TCB is not set
@@ -9079,8 +9167,9 @@ CONFIG_PWM=y
# CONFIG_PWM_AXI_PWMGEN is not set
CONFIG_PWM_BCM2835=y
-CONFIG_PWM_BCM_IPROC=y
CONFIG_PWM_BCM_IPROC=y
+CONFIG_PWM_PIO_RP1=y
# CONFIG_PWM_BERLIN is not set
-# CONFIG_PWM_BRCMSTB is not set
@ -1154,12 +984,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_PWM_CLK is not set
# CONFIG_PWM_DWC is not set
# CONFIG_PWM_FSL_FTM is not set
-# CONFIG_PWM_GPIO is not set
+CONFIG_PWM_GPIO=y
# CONFIG_PWM_HIBVT is not set
# CONFIG_PWM_IMX1 is not set
# CONFIG_PWM_IMX27 is not set
@@ -8979,7 +9053,8 @@ CONFIG_PWM_MESON=y
@@ -9096,7 +9185,8 @@ CONFIG_PWM_MESON=y
# CONFIG_PWM_OMAP_DMTIMER is not set
# CONFIG_PWM_PCA9685 is not set
CONFIG_PWM_RASPBERRYPI_POE=y
@ -1169,7 +994,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_PWM_RENESAS_TPU is not set
CONFIG_PWM_ROCKCHIP=y
# CONFIG_PWM_SPRD is not set
@@ -9003,7 +9078,7 @@ CONFIG_ARM_GIC_V3_ITS=y
@@ -9120,7 +9210,7 @@ CONFIG_ARM_GIC_V3_ITS=y
CONFIG_ARM_GIC_V5=y
CONFIG_IRQ_MSI_LIB=y
# CONFIG_AL_FIC is not set
@ -1178,7 +1003,7 @@ index 65b3647..7ba70c0 100644
CONFIG_BCM7038_L1_IRQ=y
CONFIG_BCM7120_L2_IRQ=y
CONFIG_BRCMSTB_L2_IRQ=y
@@ -9212,6 +9287,7 @@ CONFIG_ARM64_BRBE=y
@@ -9334,6 +9424,7 @@ CONFIG_ARM64_BRBE=y
# CONFIG_ARM_DMC620_PMU is not set
# CONFIG_MARVELL_CN10K_TAD_PMU is not set
# CONFIG_ALIBABA_UNCORE_DRW_PMU is not set
@ -1186,7 +1011,7 @@ index 65b3647..7ba70c0 100644
CONFIG_HISI_PMU=m
CONFIG_HISI_PCIE_PMU=m
CONFIG_HNS3_PMU=m
@@ -9257,6 +9333,7 @@ CONFIG_NVMEM_LAYOUTS=y
@@ -9379,6 +9470,7 @@ CONFIG_NVMEM_LAYOUTS=y
# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set
# end of Layout Types
@ -1194,7 +1019,7 @@ index 65b3647..7ba70c0 100644
CONFIG_NVMEM_BCM_OCOTP=y
# CONFIG_NVMEM_IMX_IIM is not set
# CONFIG_NVMEM_IMX_OCOTP is not set
@@ -9668,8 +9745,30 @@ CONFIG_INTEGRITY_TRUSTED_KEYRING=y
@@ -9787,8 +9879,30 @@ CONFIG_INTEGRITY_TRUSTED_KEYRING=y
CONFIG_INTEGRITY_PLATFORM_KEYRING=y
CONFIG_LOAD_UEFI_KEYS=y
CONFIG_INTEGRITY_AUDIT=y
@ -1227,7 +1052,7 @@ index 65b3647..7ba70c0 100644
# CONFIG_EVM is not set
# CONFIG_DEFAULT_SECURITY_SELINUX is not set
# CONFIG_DEFAULT_SECURITY_APPARMOR is not set
@@ -9868,7 +9967,7 @@ CONFIG_CRYPTO_LZO=y
@@ -9985,7 +10099,7 @@ CONFIG_CRYPTO_LZO=y
# CONFIG_CRYPTO_842 is not set
# CONFIG_CRYPTO_LZ4 is not set
# CONFIG_CRYPTO_LZ4HC is not set
@ -1236,15 +1061,7 @@ index 65b3647..7ba70c0 100644
# end of Compression
#
@@ -10046,7 +10145,6 @@ CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y
CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y
CONFIG_CRYPTO_LIB_CHACHA=y
CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=y
-CONFIG_CRYPTO_LIB_CURVE25519_INTERNAL=y
CONFIG_CRYPTO_LIB_CURVE25519=y
CONFIG_CRYPTO_LIB_DES=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9
@@ -10123,7 +10221,6 @@ CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
@@ -10238,7 +10352,6 @@ CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED=y
CONFIG_SWIOTLB=y
# CONFIG_SWIOTLB_DYNAMIC is not set
@ -1252,19 +1069,11 @@ index 65b3647..7ba70c0 100644
CONFIG_DMA_NEED_SYNC=y
# CONFIG_DMA_RESTRICTED_POOL is not set
CONFIG_DMA_NONCOHERENT_MMAP=y
@@ -10276,6 +10373,7 @@ CONFIG_UBSAN_BOUNDS_STRICT=y
CONFIG_UBSAN_SHIFT=y
# CONFIG_UBSAN_DIV_ZERO is not set
# CONFIG_UBSAN_UNREACHABLE is not set
+CONFIG_UBSAN_SIGNED_WRAP=y
CONFIG_UBSAN_BOOL=y
CONFIG_UBSAN_ENUM=y
# CONFIG_UBSAN_ALIGNMENT is not set
diff --git a/kernel/build/pkg.yaml b/kernel/build/pkg.yaml
index f797dd4..b44030e 100644
index 40f25d5..b5f96ce 100644
--- a/kernel/build/pkg.yaml
+++ b/kernel/build/pkg.yaml
@@ -27,7 +27,7 @@ steps:
@@ -28,7 +28,7 @@ steps:
{{ else }}
- |
cd /src
@ -1274,11 +1083,11 @@ index f797dd4..b44030e 100644
cd /src
diff --git a/kernel/prepare/pkg.yaml b/kernel/prepare/pkg.yaml
index 6408110..b507e5d 100644
index 6c6e61d..5df67c3 100644
--- a/kernel/prepare/pkg.yaml
+++ b/kernel/prepare/pkg.yaml
@@ -5,8 +5,8 @@ dependencies:
- stage: base
@@ -6,8 +6,8 @@ dependencies:
- image: "{{ .LLVM_IMAGE }}:{{ .TOOLS_REV }}"
steps:
- sources:
- - url: https://cdn.kernel.org/pub/linux/kernel/v{{ regexReplaceAll "(\\d+)(.\\d+)(\\.\\d+)?$" .linux_version "${1}" }}.x/linux-{{ .linux_version }}.tar.xz
@ -1288,7 +1097,7 @@ index 6408110..b507e5d 100644
sha256: "{{ .linux_sha256 }}"
sha512: "{{ .linux_sha512 }}"
- url: https://github.com/a13xp0p0v/kernel-hardening-checker/archive/{{ .kspp_ref }}.tar.gz
@@ -18,7 +18,7 @@ steps:
@@ -19,7 +19,7 @@ steps:
prepare:
- |
mkdir -p /src

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,226 @@
From 6a36399e47baeed36db12deab50e2d9d4a5914ac Mon Sep 17 00:00:00 2001
From: Mathias Beaulieu-Duncan <mathias@svrnty.io>
Date: Mon, 18 May 2026 19:02:29 -0400
Subject: [PATCH] Replace modules-arm64.txt with RPi 6.12.47 module set
The upstream Talos modules-arm64.txt is the list of kernel modules
included in the arm64 initramfs. Its entries are computed against
upstream's mainline kernel build; when Talos is built with the RPi
downstream kernel (6.12.47), several listed modules either don't
exist or are gated by upstream-only Kconfig options, causing the
initramfs install step to fail:
xargs -a modules-arm64.txt -I {} install -D \
usr/lib/modules/${KERNEL_VERSION}/{} ...
-> exit 123 (one or more inputs missing)
Replace the list with the intersection of:
- upstream's "wanted in initramfs" entries
- modules actually produced by our patched RPi 6.12.47 build
Verified by extracting the kernel image's /usr/lib/modules tree and
intersecting it with upstream's file. 155 modules survive, covering
all storage/network/crypto modules needed for headless boot. The 86
dropped modules are SATA/HID/upstream-only crypto helpers irrelevant
on RPi5/CM5.
---
hack/modules-arm64.txt | 86 ------------------------------------------
1 file changed, 86 deletions(-)
diff --git a/hack/modules-arm64.txt b/hack/modules-arm64.txt
index 9888d2b0f..a09360aed 100644
--- a/hack/modules-arm64.txt
+++ b/hack/modules-arm64.txt
@@ -4,21 +4,13 @@ kernel/crypto/async_tx/async_pq.ko
kernel/crypto/async_tx/async_raid6_recov.ko
kernel/crypto/async_tx/async_tx.ko
kernel/crypto/async_tx/async_xor.ko
-kernel/crypto/hkdf.ko
kernel/crypto/xor.ko
kernel/drivers/acpi/video.ko
-kernel/drivers/ata/ahci.ko
-kernel/drivers/ata/pata_amd.ko
-kernel/drivers/ata/pata_marvell.ko
-kernel/drivers/ata/pata_oldpiix.ko
-kernel/drivers/ata/pata_sch.ko
kernel/drivers/block/nbd.ko
kernel/drivers/block/ublk_drv.ko
kernel/drivers/crypto/tegra/tegra-se.ko
kernel/drivers/gpu/drm/drm_buddy.ko
kernel/drivers/gpu/drm/drm_exec.ko
-kernel/drivers/gpu/drm/drm_gpuvm.ko
-kernel/drivers/gpu/drm/drm_panel_backlight_quirks.ko
kernel/drivers/gpu/drm/drm_suballoc_helper.ko
kernel/drivers/gpu/drm/drm_ttm_helper.ko
kernel/drivers/gpu/drm/drm_vram_helper.ko
@@ -27,43 +19,21 @@ kernel/drivers/gpu/drm/scheduler/gpu-sched.ko
kernel/drivers/gpu/drm/tegra/tegra-drm.ko
kernel/drivers/gpu/drm/ttm/ttm.ko
kernel/drivers/gpu/host1x/host1x.ko
-kernel/drivers/hid/hid-a4tech.ko
-kernel/drivers/hid/hid-apple.ko
-kernel/drivers/hid/hid-belkin.ko
-kernel/drivers/hid/hid-cherry.ko
-kernel/drivers/hid/hid-chicony.ko
-kernel/drivers/hid/hid-cypress.ko
-kernel/drivers/hid/hid-ezkey.ko
-kernel/drivers/hid/hid-gyration.ko
-kernel/drivers/hid/hid-ite.ko
-kernel/drivers/hid/hid-kensington.ko
-kernel/drivers/hid/hid-lg-g15.ko
-kernel/drivers/hid/hid-logitech.ko
kernel/drivers/hid/hid-microsoft.ko
kernel/drivers/hid/hid-monterey.ko
kernel/drivers/hid/hid-multitouch.ko
kernel/drivers/hid/hid-petalynx.ko
kernel/drivers/hid/hid-pl.ko
-kernel/drivers/hid/hid-samsung.ko
-kernel/drivers/hid/hid-sunplus.ko
-kernel/drivers/hid/hid-topseed.ko
kernel/drivers/hwmon/i5k_amb.ko
kernel/drivers/i2c/algos/i2c-algo-bit.ko
-kernel/drivers/i2c/busses/i2c-i801.ko
-kernel/drivers/i2c/i2c-mux.ko
-kernel/drivers/infiniband/core/ib_umad.ko
-kernel/drivers/infiniband/core/ib_uverbs.ko
-kernel/drivers/infiniband/core/rdma_ucm.ko
kernel/drivers/infiniband/hw/hns/hns-roce-hw-v2.ko
kernel/drivers/infiniband/hw/irdma/irdma.ko
kernel/drivers/infiniband/hw/mlx4/mlx4_ib.ko
kernel/drivers/infiniband/hw/mlx5/mlx5_ib.ko
kernel/drivers/infiniband/sw/rxe/rdma_rxe.ko
-kernel/drivers/irqchip/irq-bcm2712-mip.ko
kernel/drivers/irqchip/irq-imx-mu-msi.ko
kernel/drivers/leds/led-class-multicolor.ko
kernel/drivers/mailbox/bcm-flexrm-mailbox.ko
-kernel/drivers/md/bcache/bcache.ko
kernel/drivers/md/dm-bio-prison.ko
kernel/drivers/md/dm-cache-smq.ko
kernel/drivers/md/dm-cache.ko
@@ -74,30 +44,8 @@ kernel/drivers/md/dm-round-robin.ko
kernel/drivers/md/dm-thin-pool.ko
kernel/drivers/md/persistent-data/dm-persistent-data.ko
kernel/drivers/md/raid456.ko
-kernel/drivers/misc/hpilo.ko
-kernel/drivers/mmc/host/sdhci_f_sdh30.ko
-kernel/drivers/mmc/host/sdhci-acpi.ko
-kernel/drivers/mmc/host/sdhci-brcmstb.ko
-kernel/drivers/mmc/host/sdhci-cadence.ko
-kernel/drivers/mmc/host/sdhci-iproc.ko
-kernel/drivers/mmc/host/sdhci-msm.ko
-kernel/drivers/mmc/host/sdhci-of-arasan.ko
-kernel/drivers/mmc/host/sdhci-of-dwcmshc.ko
-kernel/drivers/mmc/host/sdhci-of-esdhc.ko
-kernel/drivers/mmc/host/sdhci-pci.ko
-kernel/drivers/mmc/host/sdhci-pltfm.ko
-kernel/drivers/mmc/host/sdhci-tegra.ko
-kernel/drivers/mmc/host/sdhci-uhs2.ko
-kernel/drivers/mmc/host/sdhci-xenon-driver.ko
kernel/drivers/net/ethernet/amazon/ena/ena.ko
-kernel/drivers/net/ethernet/aquantia/atlantic/atlantic.ko
kernel/drivers/net/ethernet/atheros/alx/alx.ko
-kernel/drivers/net/ethernet/broadcom/bnx2.ko
-kernel/drivers/net/ethernet/broadcom/bnx2x/bnx2x.ko
-kernel/drivers/net/ethernet/broadcom/bnxt/bnxt_en.ko
-kernel/drivers/net/ethernet/broadcom/tg3.ko
-kernel/drivers/net/ethernet/cavium/common/cavium_ptp.ko
-kernel/drivers/net/ethernet/cisco/enic/enic.ko
kernel/drivers/net/ethernet/google/gve/gve.ko
kernel/drivers/net/ethernet/hisilicon/hip04_eth.ko
kernel/drivers/net/ethernet/hisilicon/hisi_femac.ko
@@ -123,12 +71,8 @@ kernel/drivers/net/ethernet/intel/igbvf/igbvf.ko
kernel/drivers/net/ethernet/intel/igc/igc.ko
kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko
kernel/drivers/net/ethernet/intel/ixgbevf/ixgbevf.ko
-kernel/drivers/net/ethernet/intel/libeth/libeth_xdp.ko
kernel/drivers/net/ethernet/intel/libeth/libeth.ko
-kernel/drivers/net/ethernet/intel/libie/libie_adminq.ko
-kernel/drivers/net/ethernet/intel/libie/libie_fwlog.ko
kernel/drivers/net/ethernet/intel/libie/libie.ko
-kernel/drivers/net/ethernet/marvell/sky2.ko
kernel/drivers/net/ethernet/mellanox/mlx4/mlx4_core.ko
kernel/drivers/net/ethernet/mellanox/mlx4/mlx4_en.ko
kernel/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko
@@ -138,11 +82,6 @@ kernel/drivers/net/ethernet/mellanox/mlxsw/mlxsw_i2c.ko
kernel/drivers/net/ethernet/mellanox/mlxsw/mlxsw_minimal.ko
kernel/drivers/net/ethernet/mellanox/mlxsw/mlxsw_pci.ko
kernel/drivers/net/ethernet/mellanox/mlxsw/mlxsw_spectrum.ko
-kernel/drivers/net/ethernet/qlogic/qed/qed.ko
-kernel/drivers/net/ethernet/qlogic/qede/qede.ko
-kernel/drivers/net/ethernet/qlogic/qlcnic/qlcnic.ko
-kernel/drivers/net/ethernet/realtek/8139too.ko
-kernel/drivers/net/ethernet/realtek/r8169.ko
kernel/drivers/net/ethernet/sfc/sfc.ko
kernel/drivers/net/ethernet/sfc/siena/sfc-siena.ko
kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.ko
@@ -152,25 +91,17 @@ kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.ko
kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.ko
kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.ko
kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.ko
-kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.ko
kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.ko
-kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-sun55i.ko
kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.ko
kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.ko
kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.ko
kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-pci.ko
kernel/drivers/net/ethernet/stmicro/stmmac/stmmac-platform.ko
kernel/drivers/net/ethernet/stmicro/stmmac/stmmac.ko
-kernel/drivers/net/mdio.ko
kernel/drivers/net/pcs/pcs_xpcs.ko
-kernel/drivers/net/pcs/pcs-rzn1-miic.ko
-kernel/drivers/net/phy/dp83867.ko
-kernel/drivers/net/usb/r8152.ko
-kernel/drivers/net/vmxnet3/vmxnet3.ko
kernel/drivers/net/vrf.ko
kernel/drivers/nvme/common/nvme-auth.ko
kernel/drivers/nvme/host/nvme-rdma.ko
-kernel/drivers/nvme/host/nvme.ko
kernel/drivers/nvme/target/nvme-loop.ko
kernel/drivers/nvme/target/nvmet-fc.ko
kernel/drivers/nvme/target/nvmet-rdma.ko
@@ -191,21 +122,13 @@ kernel/drivers/scsi/hisi_sas/hisi_sas_main.ko
kernel/drivers/scsi/hisi_sas/hisi_sas_v1_hw.ko
kernel/drivers/scsi/hisi_sas/hisi_sas_v2_hw.ko
kernel/drivers/scsi/hisi_sas/hisi_sas_v3_hw.ko
-kernel/drivers/scsi/hpsa.ko
kernel/drivers/scsi/libfc/libfc.ko
kernel/drivers/scsi/lpfc/lpfc.ko
-kernel/drivers/scsi/megaraid/megaraid_sas.ko
kernel/drivers/scsi/mpi3mr/mpi3mr.ko
-kernel/drivers/scsi/mpt3sas/mpt3sas.ko
kernel/drivers/scsi/qedf/qedf.ko
kernel/drivers/scsi/qla2xxx/qla2xxx.ko
-kernel/drivers/scsi/smartpqi/smartpqi.ko
kernel/drivers/uio/uio_pci_generic.ko
kernel/drivers/uio/uio.ko
-kernel/drivers/usb/serial/ch341.ko
-kernel/drivers/usb/serial/cp210x.ko
-kernel/drivers/usb/serial/ftdi_sio.ko
-kernel/drivers/usb/serial/pl2303.ko
kernel/drivers/vdpa/mlx5/mlx5_vdpa.ko
kernel/drivers/vdpa/octeon_ep/octep_vdpa.ko
kernel/drivers/vdpa/solidrun/snet_vdpa.ko
@@ -221,12 +144,6 @@ kernel/drivers/vfio/vfio_iommu_type1.ko
kernel/drivers/vfio/vfio.ko
kernel/drivers/vhost/vhost_vdpa.ko
kernel/drivers/vhost/vringh.ko
-kernel/drivers/virtio/virtio_balloon.ko
-kernel/drivers/virtio/virtio_input.ko
-kernel/drivers/virtio/virtio_mmio.ko
-kernel/drivers/virtio/virtio_pci_legacy_dev.ko
-kernel/drivers/virtio/virtio_pci_modern_dev.ko
-kernel/drivers/virtio/virtio_pci.ko
kernel/drivers/virtio/virtio_vdpa.ko
kernel/drivers/watchdog/sbsa_gwdt.ko
kernel/lib/objagg.ko
@@ -236,6 +153,3 @@ kernel/net/ipv4/ip_gre.ko
kernel/net/ipv6/ip6_gre.ko
kernel/net/openvswitch/vport-gre.ko
kernel/net/tls/tls.ko
-modules.builtin
-modules.builtin.modinfo
-modules.order
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,33 @@
From 2db8797af370535aba7c5694cd291bba8e6c5a67 Mon Sep 17 00:00:00 2001
From: Mathias Beaulieu-Duncan <mathias@svrnty.io>
Date: Fri, 13 Feb 2026 19:08:41 -0500
Subject: [PATCH 2/3] Skip NVRAM writes for GRUB on arm64
On arm64 platforms like RPi5/CM5, the UEFI firmware (U-Boot) does not
support EFI runtime SetVariable, causing grub-install to fail when
efibootmgr tries to create NVRAM boot entries. Since arm64-efi systems
boot by convention (finding BOOTAA64.efi on the ESP), NVRAM boot
entries are unnecessary.
Pass --no-nvram to grub-install on arm64 to allow in-place upgrades
via talosctl upgrade to succeed.
---
.../machined/pkg/runtime/v1alpha1/bootloader/grub/install.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/install.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/install.go
index 6f5c9f8..766374b 100644
--- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/install.go
+++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/install.go
@@ -196,7 +196,7 @@ func (c *Config) install(opts options.InstallOptions) (*options.InstallResult, e
args = append(args, "--efi-directory="+filepath.Join(opts.MountPrefix, constants.EFIMountPoint))
}
- if opts.ImageMode {
+ if opts.ImageMode || opts.Arch == arm64 {
args = append(args, "--no-nvram")
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,74 @@
From 1393b3f013e758f6bb52d14006d3a7e7db348930 Mon Sep 17 00:00:00 2001
From: Mathias Beaulieu-Duncan <mathias@svrnty.io>
Date: Fri, 13 Feb 2026 19:08:58 -0500
Subject: [PATCH 3/3] Force GRUB bootloader on arm64
On arm64 platforms like RPi5/CM5, the UEFI firmware (U-Boot) exposes
/sys/firmware/efi but does not support EFI runtime SetVariable. This
causes sd-boot to fail when trying to write EFI variables during
installation/upgrade.
Force GRUB on arm64 in two places:
- NewAuto(): When no existing bootloader is detected, create a GRUB
config instead of sd-boot. This handles fresh installs.
- Probe(): When an existing GRUB config is not found, skip sd-boot
probing and return a fresh GRUB config. This handles the first
upgrade on SBC images that ship with sd-boot UKI files — the
upgrade transitions from sd-boot to GRUB automatically.
Combined with the --no-nvram patch and the SBC EFI-only layout patch,
this enables reliable in-place upgrades via talosctl upgrade on
RPi5/CM5 hardware, including the first upgrade from a fresh flash.
Ref: https://github.com/siderolabs/talos/issues/10859
Ref: https://github.com/talos-rpi5/talos-builder/issues/21
---
.../machined/pkg/runtime/v1alpha1/bootloader/bootloader.go | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/bootloader.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/bootloader.go
index f084e09..5c388c1 100644
--- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/bootloader.go
+++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/bootloader.go
@@ -8,6 +8,7 @@ package bootloader
import (
"fmt"
"os"
+ goruntime "runtime"
"github.com/siderolabs/go-blockdevice/v2/block"
"github.com/siderolabs/go-blockdevice/v2/partitioning/gpt"
@@ -56,7 +57,17 @@ func Probe(disk string, options options.ProbeOptions) (Bootloader, error) {
return grubBootloader, nil
}
+ // On arm64, sd-boot requires EFI SetVariable runtime service which is
+ // not available on platforms like RPi5/CM5 (U-Boot). Skip sd-boot
+ // probing and return a fresh GRUB config to transition from sd-boot
+ // to GRUB on the first upgrade.
+ if goruntime.GOARCH == "arm64" {
+ options.Logf("arm64: no GRUB config found, creating new GRUB bootloader (sd-boot not supported)")
+
+ return grub.NewConfig(), nil
+ }
+
sdbootBootloader, err := sdboot.Probe(disk, options)
if err != nil {
return nil, err
@@ -73,6 +84,10 @@ func Probe(disk string, options options.ProbeOptions) (Bootloader, error) {
// NewAuto returns a new bootloader based on auto-detection.
func NewAuto() Bootloader {
+ if goruntime.GOARCH == "arm64" {
+ return grub.NewConfig()
+ }
+
if sdboot.IsUEFIBoot() {
return sdboot.New()
}
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,45 @@
From 98366401143dcc31c056a7d96242775f9ba013ca Mon Sep 17 00:00:00 2001
From: Mathias Beaulieu-Duncan <mathias@svrnty.io>
Date: Sat, 14 Feb 2026 14:05:15 -0500
Subject: [PATCH 4/4] Fallback to classic bind mounts on kernels without
open_tree support
The open_tree syscall on anonymous filesystem file descriptors was added
in kernel 6.15.0. Talos previously only checked for this capability when
running in container mode, assuming bare metal always had a sufficiently
new kernel. However, platforms like RPi5/CM5 use the RPi downstream
kernel (6.12.x) which lacks this feature, causing shadow bind mount
failures for /etc files and cascading network initialization failures.
Remove the InContainer() gate so the OpentreeOnAnonymousFS() capability
check runs on all platforms, enabling the classic (OSRoot) fallback when
the kernel does not support the newer mount API.
---
.../pkg/runtime/v1alpha2/v1alpha2_controller.go | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go
index 29b297654..653a45d57 100644
--- a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go
+++ b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go
@@ -113,11 +113,12 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error
networkBindMountTarget = constants.SystemResolvedPath
- // While running in container, we don't have control over kernel version
- // shipped with the machine. If the kernel does not support open_tree syscall
- // on anonymous filesystem file descriptors, we need to fallback to the classic,
- // less secure mode. This capability was added in kernel 6.15.0.
- if ctrl.v1alpha1Runtime.State().Platform().Mode().InContainer() {
+ // If the kernel does not support open_tree syscall on anonymous filesystem
+ // file descriptors, we need to fallback to the classic, less secure mode.
+ // This capability was added in kernel 6.15.0. This check is needed for
+ // containers (where the host kernel is unknown) and for bare metal platforms
+ // running older kernels such as the RPi downstream kernel (6.12.x).
+ {
opentreeOnAnonymous, err := runtime.KernelCapabilities().OpentreeOnAnonymousFS()
if err != nil {
return err
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,296 @@
From cf9dfa043b21b393003ca4c2facebdd8e570f547 Mon Sep 17 00:00:00 2001
From: Mathias Beaulieu-Duncan <mathias@svrnty.io>
Date: Mon, 16 Feb 2026 11:31:08 -0500
Subject: [PATCH] Handle missing BOOT partition for GRUB on SBC layouts
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On SBC platforms like RPi5/CM5, the disk layout has no separate BOOT
(XFS) partition — all boot assets (kernel, initramfs, GRUB config,
EFI bootloader, firmware) reside on a single EFI (VFAT) partition.
The GRUB bootloader probe, install, and revert functions all assumed a
BOOT partition exists, causing talosctl upgrade to fail with "partition
with label BOOT not found" on these layouts.
Fix all three code paths to fall back to mounting the EFI partition at
/boot when the BOOT partition is absent:
- probe.go: Try EFI at /boot as fallback when BOOT is missing, so
the upgrade can detect the existing GRUB installation
- install.go: Probe for BOOT existence before including it in mount
specs; when absent, mount EFI at /boot and adjust --efi-directory
- revert.go: Fall back to EFI at /boot for rollback operations
This enables in-place upgrades via talosctl upgrade on SBC platforms
that use EFI-only disk layouts.
---
.../runtime/v1alpha1/bootloader/grub/grub.go | 2 +
.../v1alpha1/bootloader/grub/install.go | 49 +++++++++--
.../runtime/v1alpha1/bootloader/grub/probe.go | 83 ++++++++++++-------
.../v1alpha1/bootloader/grub/revert.go | 33 ++++++--
4 files changed, 125 insertions(+), 42 deletions(-)
diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/grub.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/grub.go
index 0cb5b1d4d..093ffecd9 100644
--- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/grub.go
+++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/grub.go
@@ -30,6 +30,8 @@ type Config struct {
Fallback BootLabel
Entries map[BootLabel]MenuEntry
AddResetOption bool
+
+ bootFromEFI bool
}
// MenuEntry represents a grub menu entry in the grub config file.
diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/install.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/install.go
index d0af22d98..f1ea13e5a 100644
--- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/install.go
+++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/install.go
@@ -34,12 +34,12 @@ const (
// Install validates the grub configuration and writes it to the disk.
func (c *Config) Install(opts options.InstallOptions) (*options.InstallResult, error) {
- mountSpecs := []mount.Spec{
- {
- PartitionLabel: constants.BootPartitionLabel,
- FilesystemType: partition.FilesystemTypeXFS,
- MountTarget: filepath.Join(opts.MountPrefix, constants.BootMountPoint),
- },
+ var mountSpecs []mount.Spec
+
+ bootMountSpec := mount.Spec{
+ PartitionLabel: constants.BootPartitionLabel,
+ FilesystemType: partition.FilesystemTypeXFS,
+ MountTarget: filepath.Join(opts.MountPrefix, constants.BootMountPoint),
}
efiMountSpec := mount.Spec{
@@ -48,6 +48,23 @@ func (c *Config) Install(opts options.InstallOptions) (*options.InstallResult, e
MountTarget: filepath.Join(opts.MountPrefix, constants.EFIMountPoint),
}
+ // check if the BOOT partition is present (absent on SBC layouts like RPi5/CM5)
+ if err := mount.PartitionOp(
+ opts.BootDisk,
+ []mount.Spec{bootMountSpec},
+ func() error {
+ return nil
+ },
+ []blkid.ProbeOption{
+ blkid.WithSkipLocking(true),
+ },
+ nil,
+ nil,
+ opts.BlkidInfo,
+ ); err == nil {
+ mountSpecs = append(mountSpecs, bootMountSpec)
+ }
+
var efiFound bool
// check if the EFI partition is present
@@ -65,12 +82,21 @@ func (c *Config) Install(opts options.InstallOptions) (*options.InstallResult, e
opts.BlkidInfo,
); err == nil {
efiFound = true
- }
- if efiFound {
+ if len(mountSpecs) == 0 {
+ // No BOOT partition (SBC layout): mount EFI at /boot so GRUB
+ // can find kernel/initramfs/grub.cfg in the expected place.
+ efiMountSpec.MountTarget = filepath.Join(opts.MountPrefix, constants.BootMountPoint)
+ c.bootFromEFI = true
+ }
+
mountSpecs = append(mountSpecs, efiMountSpec)
}
+ if len(mountSpecs) == 0 {
+ return nil, fmt.Errorf("neither BOOT nor EFI partition found on disk %s", opts.BootDisk)
+ }
+
err := mount.PartitionOp(
opts.BootDisk,
mountSpecs,
@@ -318,7 +344,12 @@ func (c *Config) runGrubInstall(ctx context.Context, opts options.InstallOptions
}
if efiMode {
- args = append(args, "--efi-directory="+filepath.Join(opts.MountPrefix, constants.EFIMountPoint))
+ efiDir := constants.EFIMountPoint
+ if c.bootFromEFI {
+ efiDir = constants.BootMountPoint
+ }
+
+ args = append(args, "--efi-directory="+filepath.Join(opts.MountPrefix, efiDir))
}
if opts.ImageMode || opts.Arch == arm64 {
diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/probe.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/probe.go
index f5755592f..771ca2a90 100644
--- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/probe.go
+++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/probe.go
@@ -19,6 +19,31 @@ import (
func ProbeWithCallback(disk string, options options.ProbeOptions, callback func(*Config) error) (*Config, error) {
var grubConf *Config
+ readConfig := func() error {
+ var err error
+
+ grubConf, err = Read(ConfigPath)
+ if err != nil {
+ return err
+ }
+
+ if grubConf != nil && callback != nil {
+ return callback(grubConf)
+ }
+
+ if grubConf == nil {
+ options.Logf("GRUB: config not found")
+ }
+
+ return nil
+ }
+
+ probeOpts := []mountv3.ManagerOption{
+ mountv3.WithSkipIfMounted(),
+ mountv3.WithReadOnly(),
+ }
+
+ // Try BOOT partition first (standard layout)
if err := mount.PartitionOp(
disk,
[]mount.Spec{
@@ -28,40 +53,42 @@ func ProbeWithCallback(disk string, options options.ProbeOptions, callback func(
MountTarget: constants.BootMountPoint,
},
},
- func() error {
- var err error
-
- grubConf, err = Read(ConfigPath)
- if err != nil {
- return err
- }
-
- if grubConf != nil && callback != nil {
- return callback(grubConf)
- }
-
- if grubConf == nil {
- options.Logf("GRUB: config not found")
- }
-
- return nil
- },
+ readConfig,
options.BlockProbeOptions,
- []mountv3.ManagerOption{
- mountv3.WithSkipIfMounted(),
- mountv3.WithReadOnly(),
- },
+ probeOpts,
nil,
nil,
); err != nil {
- if xerrors.TagIs[mount.NotFoundTag](err) {
- // if partitions are not found, it means GRUB is not installed
- options.Logf("GRUB: BOOT partition not found, skipping probing")
-
- return nil, nil
+ if !xerrors.TagIs[mount.NotFoundTag](err) {
+ return nil, err
}
- return nil, err
+ // BOOT not found, try EFI partition mounted at /boot (SBC layout)
+ options.Logf("GRUB: BOOT partition not found, trying EFI partition")
+
+ if err := mount.PartitionOp(
+ disk,
+ []mount.Spec{
+ {
+ PartitionLabel: constants.EFIPartitionLabel,
+ FilesystemType: partition.FilesystemTypeVFAT,
+ MountTarget: constants.BootMountPoint,
+ },
+ },
+ readConfig,
+ options.BlockProbeOptions,
+ probeOpts,
+ nil,
+ nil,
+ ); err != nil {
+ if xerrors.TagIs[mount.NotFoundTag](err) {
+ options.Logf("GRUB: neither BOOT nor EFI partition found, skipping probing")
+
+ return nil, nil
+ }
+
+ return nil, err
+ }
}
return grubConf, nil
diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/revert.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/revert.go
index 3e514d65d..95628193b 100644
--- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/revert.go
+++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/revert.go
@@ -26,6 +26,10 @@ func (c *Config) Revert(disk string) error {
return fmt.Errorf("cannot revert bootloader: %w", bootloaderNotInstalledError{})
}
+ revertOpts := []mountv3.ManagerOption{
+ mountv3.WithSkipIfMounted(),
+ }
+
err := mount.PartitionOp(
disk,
[]mount.Spec{
@@ -37,14 +41,33 @@ func (c *Config) Revert(disk string) error {
},
c.revert,
nil,
- []mountv3.ManagerOption{
- mountv3.WithSkipIfMounted(),
- },
+ revertOpts,
nil,
nil,
)
- if err != nil && !xerrors.TagIs[mount.NotFoundTag](err) {
- return err
+ if err != nil {
+ if !xerrors.TagIs[mount.NotFoundTag](err) {
+ return err
+ }
+
+ // BOOT not found, try EFI partition mounted at /boot (SBC layout)
+ if err := mount.PartitionOp(
+ disk,
+ []mount.Spec{
+ {
+ PartitionLabel: constants.EFIPartitionLabel,
+ FilesystemType: partition.FilesystemTypeVFAT,
+ MountTarget: constants.BootMountPoint,
+ },
+ },
+ c.revert,
+ nil,
+ revertOpts,
+ nil,
+ nil,
+ ); err != nil && !xerrors.TagIs[mount.NotFoundTag](err) {
+ return err
+ }
}
return nil
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,92 @@
From a50511de74db08a0b4426be88bb52ce860a008a4 Mon Sep 17 00:00:00 2001
From: builder <build@svrnty.io>
Date: Fri, 22 May 2026 16:10:42 -0400
Subject: [PATCH] grub: EFI-at-/boot fallback for BOOT-less SBC layout in
Upgrade path
---
.../v1alpha1/bootloader/grub/upgrade.go | 43 +++++++++++++++----
1 file changed, 35 insertions(+), 8 deletions(-)
diff --git a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/upgrade.go b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/upgrade.go
index 9e3f86b84..e99bf2939 100644
--- a/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/upgrade.go
+++ b/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/upgrade.go
@@ -6,6 +6,7 @@ package grub
import (
"context"
+ "fmt"
"path/filepath"
"github.com/siderolabs/go-blockdevice/v2/blkid"
@@ -18,12 +19,12 @@ import (
// Upgrade copies new boot assets and updates grub configuration on an existing installation.
func (c *Config) Upgrade(opts options.InstallOptions) (*options.InstallResult, error) {
- mountSpecs := []mount.Spec{
- {
- PartitionLabel: constants.BootPartitionLabel,
- FilesystemType: partition.FilesystemTypeXFS,
- MountTarget: filepath.Join(opts.MountPrefix, constants.BootMountPoint),
- },
+ var mountSpecs []mount.Spec
+
+ bootMountSpec := mount.Spec{
+ PartitionLabel: constants.BootPartitionLabel,
+ FilesystemType: partition.FilesystemTypeXFS,
+ MountTarget: filepath.Join(opts.MountPrefix, constants.BootMountPoint),
}
efiMountSpec := mount.Spec{
@@ -32,6 +33,23 @@ func (c *Config) Upgrade(opts options.InstallOptions) (*options.InstallResult, e
MountTarget: filepath.Join(opts.MountPrefix, constants.EFIMountPoint),
}
+ // check if the BOOT partition is present (absent on SBC layouts like RPi5/CM5)
+ if err := mount.PartitionOp(
+ opts.BootDisk,
+ []mount.Spec{bootMountSpec},
+ func() error {
+ return nil
+ },
+ []blkid.ProbeOption{
+ blkid.WithSkipLocking(true),
+ },
+ nil,
+ nil,
+ opts.BlkidInfo,
+ ); err == nil {
+ mountSpecs = append(mountSpecs, bootMountSpec)
+ }
+
var efiFound bool
// check if the EFI partition is present
@@ -49,12 +67,21 @@ func (c *Config) Upgrade(opts options.InstallOptions) (*options.InstallResult, e
opts.BlkidInfo,
); err == nil {
efiFound = true
- }
- if efiFound {
+ if len(mountSpecs) == 0 {
+ // No BOOT partition (SBC layout): mount EFI at /boot so GRUB
+ // can find kernel/initramfs/grub.cfg in the expected place.
+ efiMountSpec.MountTarget = filepath.Join(opts.MountPrefix, constants.BootMountPoint)
+ c.bootFromEFI = true
+ }
+
mountSpecs = append(mountSpecs, efiMountSpec)
}
+ if len(mountSpecs) == 0 {
+ return nil, fmt.Errorf("neither BOOT nor EFI partition found on disk %s", opts.BootDisk)
+ }
+
err := mount.PartitionOp(
opts.BootDisk,
mountSpecs,
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,114 @@
From 27501076fcb1e183e68313ef0e14092d7f403063 Mon Sep 17 00:00:00 2001
From: Mathias Beaulieu-Duncan <mathias@svrnty.io>
Date: Mon, 25 May 2026 17:10:13 -0400
Subject: [PATCH] Wait for STATE volume on slow-init disks in config acquire
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On slow-init storage (notably RPi CM5 eMMC, which takes ~2 minutes 13
seconds from kernel boot to mmc0/CQE-enabled), the config acquire state
machine's stateDisk step sees STATE in phase=missing during the early
boot window and immediately transitions to stateEmbedded. With no
embedded config either, the node falls through to maintenance mode and
stays there even after the STATE volume later reaches phase=ready —
the state machine is one-way and never re-enters stateDisk.
Result: in-place upgrades to v1.13.2 on CM5 hardware leave the node in
maintenance with its on-disk config.yaml intact but unread, until a
human runs `talosctl apply-config --insecure` to re-feed the same file
that's already on the STATE filesystem.
This patch makes stateDisk tolerate transient phase=missing for up to
5 minutes (stateMissingDiskTimeout) before falling through. The outer
Run loop gets a 5-second ticker so the timeout can fire even when no
further volume-status events arrive (e.g. truly missing STATE on a
fresh install). Fast-init hardware sees no change — STATE reaches ready
within seconds and the existing path runs.
Tested on RPi CM5 (eMMC, 6.12.47 RPi-downstream kernel) — boot path
that previously dropped to maintenance now waits ~2m15s, sees STATE
reach ready, and continues to stateDone with the persisted config.
---
.../pkg/controllers/config/acquire.go | 37 ++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/internal/app/machined/pkg/controllers/config/acquire.go b/internal/app/machined/pkg/controllers/config/acquire.go
index a70fddb..7a3758f 100644
--- a/internal/app/machined/pkg/controllers/config/acquire.go
+++ b/internal/app/machined/pkg/controllers/config/acquire.go
@@ -18,6 +18,7 @@ import (
"path/filepath"
"slices"
"strings"
+ "time"
"github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/safe"
@@ -86,8 +87,16 @@ type AcquireController struct {
diskConfig config.Provider
storedEmbeddedConfig []byte
skipMaskingEmbeddedConfig bool
+ firstSeenStateMissing time.Time
}
+// stateMissingDiskTimeout is how long stateDisk will wait for the STATE volume
+// to leave the "missing" phase before falling through to embedded/maintenance.
+// On slow-init storage (e.g. RPi CM5 eMMC) the volume can take ~2-3 minutes to
+// appear after kernel boot; transitioning to embedded too eagerly leaves the
+// node permanently in maintenance even though the on-disk config is intact.
+const stateMissingDiskTimeout = 5 * time.Minute
+
// Name implements controller.Controller interface.
func (ctrl *AcquireController) Name() string {
return "config.AcquireController"
@@ -177,11 +186,17 @@ func (ctrl *AcquireController) Run(ctx context.Context, r controller.Runtime, lo
// initialize with empty sources
ctrl.configSourcesUsed = []string{}
+ // periodic wake-up so stateDisk can re-check slow-init volumes and trip
+ // its timeout even when no resource events fire.
+ tick := time.NewTicker(5 * time.Second)
+ defer tick.Stop()
+
for {
select {
case <-ctx.Done():
return nil
case <-r.EventCh():
+ case <-tick.C:
}
// check the spec first
@@ -262,7 +277,27 @@ func (ctrl *AcquireController) stateDisk(ctx context.Context, r controller.Runti
// wait for the status to be available
return nil, nil, nil
case stateVolumeStatus.TypedSpec().Phase == block.VolumePhaseMissing:
- // STATE is missing, proceed to stateEmbedded
+ // STATE is reported missing. On slow-init storage (e.g. RPi CM5 eMMC)
+ // the volume can take a couple of minutes to appear after kernel boot,
+ // so wait up to stateMissingDiskTimeout for it to reach ready before
+ // falling through to embedded/maintenance.
+ if ctrl.firstSeenStateMissing.IsZero() {
+ ctrl.firstSeenStateMissing = time.Now()
+ }
+
+ if time.Since(ctrl.firstSeenStateMissing) < stateMissingDiskTimeout {
+ logger.Info("STATE volume not yet available, waiting",
+ zap.Duration("elapsed", time.Since(ctrl.firstSeenStateMissing)),
+ zap.Duration("timeout", stateMissingDiskTimeout),
+ )
+
+ return nil, nil, nil
+ }
+
+ logger.Warn("STATE volume still missing after timeout, proceeding to embedded",
+ zap.Duration("waited", time.Since(ctrl.firstSeenStateMissing)),
+ )
+
return ctrl.stateEmbedded, nil, nil
case stateVolumeStatus.TypedSpec().Phase == block.VolumePhaseReady:
// STATE is ready, proceed to to the action
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,42 @@
From e2bacf8336c63a4d11a54f3978fc15e8bf4362ce Mon Sep 17 00:00:00 2001
From: Mathias Beaulieu-Duncan <mathias@svrnty.io>
Date: Mon, 25 May 2026 17:20:32 -0400
Subject: [PATCH] imager: respect --insecure for Overlay and OverlayInstaller
assets
The --insecure flag on talosctl imager (and the imager docker image) only
applied to BaseInstaller, ImageCache, and SystemExtensions assets.
Overlay.Image and Input.OverlayInstaller never received ForceInsecure,
so pulling overlay images from an insecure (HTTP) registry failed with
'http: server gave HTTP response to HTTPS client' even when --insecure
was passed.
Set ForceInsecure on both overlay-related ContainerAsset references
when the flag is present, matching how the other inputs are handled.
---
cmd/installer/cmd/imager/root.go | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/cmd/installer/cmd/imager/root.go b/cmd/installer/cmd/imager/root.go
index d65b56089..ea16a45b3 100644
--- a/cmd/installer/cmd/imager/root.go
+++ b/cmd/installer/cmd/imager/root.go
@@ -120,12 +120,14 @@ var rootCmd = &cobra.Command{
prof.Overlay = &profile.OverlayOptions{
Name: cmdFlags.OverlayName,
Image: profile.ContainerAsset{
- ImageRef: cmdFlags.OverlayImage,
+ ImageRef: cmdFlags.OverlayImage,
+ ForceInsecure: cmdFlags.Insecure,
},
ExtraOptions: extraOverlayOptions,
}
prof.Input.OverlayInstaller.ImageRef = cmdFlags.OverlayImage
+ prof.Input.OverlayInstaller.ForceInsecure = cmdFlags.Insecure
}
prof.Input.SystemExtensions = xslices.Map(
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,38 @@
From 69f14c84e9e458dcff24905145cac8557c0e2965 Mon Sep 17 00:00:00 2001
From: Mathias Beaulieu-Duncan <mathias@svrnty.io>
Date: Fri, 13 Feb 2026 15:25:26 -0500
Subject: [PATCH] Bump Go toolchain to 1.24.13 to fix stdlib CVEs
---
go.work | 4 +++-
installers/rpi5/src/go.mod | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/go.work b/go.work
index f4dafe7..798ea43 100644
--- a/go.work
+++ b/go.work
@@ -1,3 +1,5 @@
-go 1.24.0
+go 1.24.13
+
+toolchain go1.24.13
use ./installers/rpi5/src
diff --git a/installers/rpi5/src/go.mod b/installers/rpi5/src/go.mod
index 50b72d5..af5f5f8 100644
--- a/installers/rpi5/src/go.mod
+++ b/installers/rpi5/src/go.mod
@@ -1,6 +1,8 @@
module rpi_generic
-go 1.24.0
+go 1.24.13
+
+toolchain go1.24.13
require (
github.com/siderolabs/go-copy v0.1.0
--
2.50.1 (Apple Git-155)

View File

@ -0,0 +1,77 @@
From 5cdfe8ddb717e8de4e9d1c9e3000614ad8a1b5bb Mon Sep 17 00:00:00 2001
From: Mathias Beaulieu-Duncan <mathias@openharbor.io>
Date: Wed, 25 Feb 2026 12:41:51 -0500
Subject: [PATCH] Fix SBC overlay upgrade: detect EFI mount path for SBC
layouts
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On SBC platforms (RPi5/CM5), the disk layout has no separate BOOT
partition. During upgrades, the GRUB install code mounts the EFI
partition at /boot instead of /boot/EFI. The overlay installer was
always writing to /boot/EFI, causing config.txt and firmware files
to end up in the wrong subdirectory — invisible to the firmware.
Detect the SBC layout by checking if config.txt already exists at
/boot/ (indicating EFI is mounted there), and write files to the
correct location.
---
installers/rpi5/src/config.txt | 3 ++-
installers/rpi5/src/main.go | 18 +++++++++++++-----
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/installers/rpi5/src/config.txt b/installers/rpi5/src/config.txt
index 1445d0e..e38291b 100644
--- a/installers/rpi5/src/config.txt
+++ b/installers/rpi5/src/config.txt
@@ -11,7 +11,8 @@ kernel=u-boot.bin
arm_64bit=1
# Run as fast as firmware / board allows.
arm_boost=1
-# Enable the primary/console UART.
+# Enable UART0 on GPIO 14/15 (Pi5/CM5 requires explicit dt overlay).
+dtoverlay=uart0-pi5
enable_uart=1
# Disable Bluetooth.
dtoverlay=disable-bt
diff --git a/installers/rpi5/src/main.go b/installers/rpi5/src/main.go
index 38cd824..155a86b 100644
--- a/installers/rpi5/src/main.go
+++ b/installers/rpi5/src/main.go
@@ -41,13 +41,21 @@ func (i *RpiInstaller) GetOptions(extra rpiOptions) (overlay.Options, error) {
}
func (i *RpiInstaller) Install(options overlay.InstallOptions[rpiOptions]) error {
- err := copy.Dir(filepath.Join(options.ArtifactsPath, "arm64/firmware/boot"), filepath.Join(options.MountPrefix, "/boot/EFI"))
- if err != nil {
+ // Determine where the EFI partition is mounted.
+ // Standard layout: BOOT (XFS) at /boot, EFI (VFAT) at /boot/EFI
+ // SBC layout: no BOOT partition, EFI (VFAT) at /boot
+ efiDir := filepath.Join(options.MountPrefix, "/boot/EFI")
+
+ if _, err := os.Stat(filepath.Join(options.MountPrefix, "/boot/config.txt")); err == nil {
+ // config.txt exists at /boot — EFI partition is mounted at /boot (SBC layout).
+ efiDir = filepath.Join(options.MountPrefix, "/boot")
+ }
+
+ if err := copy.Dir(filepath.Join(options.ArtifactsPath, "arm64/firmware/boot"), efiDir); err != nil {
return err
}
- err = copy.File(filepath.Join(options.ArtifactsPath, "arm64/u-boot/rpi5/u-boot.bin"), filepath.Join(options.MountPrefix, "/boot/EFI/u-boot.bin"))
- if err != nil {
+ if err := copy.File(filepath.Join(options.ArtifactsPath, "arm64/u-boot/rpi5/u-boot.bin"), filepath.Join(efiDir, "u-boot.bin")); err != nil {
return err
}
@@ -57,5 +65,5 @@ func (i *RpiInstaller) Install(options overlay.InstallOptions[rpiOptions]) error
configTxt = append(configTxt, []byte("\n"+options.ExtraOptions.ConfigTxtAppend)...)
- return os.WriteFile(filepath.Join(options.MountPrefix, "/boot/EFI/config.txt"), configTxt, 0o644)
+ return os.WriteFile(filepath.Join(efiDir, "config.txt"), configTxt, 0o644)
}
--
2.50.1 (Apple Git-155)

125
scripts/auto-update.sh Executable file
View File

@ -0,0 +1,125 @@
#!/usr/bin/env bash
# Auto-update upstream versions, verify patches, and generate a release tag
#
# Expects environment variables from check-upstream.sh:
# TALOS_UPDATE, RPI_UPDATE, LATEST_TALOS, LATEST_RPI_TAG
#
# Outputs (for GitHub Actions):
# patch_failed=true — if patches fail to apply (caller should create issue)
# new_tag=<tag> — the computed release tag (e.g. v1.12.3-k6.12.47-1)
#
# Usage:
# TALOS_UPDATE=true LATEST_TALOS=v1.13.0 ./scripts/auto-update.sh >> "$GITHUB_OUTPUT"
set -euo pipefail
TALOS_UPDATE=${TALOS_UPDATE:-false}
RPI_UPDATE=${RPI_UPDATE:-false}
LATEST_TALOS=${LATEST_TALOS:-}
LATEST_RPI_TAG=${LATEST_RPI_TAG:-}
MAKEFILE="Makefile"
PATCH_FILE="patches/siderolabs/pkgs/0001-Patched-for-Raspberry-Pi-5.patch"
# Helper: extract kernel semver (e.g. 6.12.47) from the RPi repo Makefile
get_kernel_version() {
local tag="$1"
curl -sf "https://raw.githubusercontent.com/raspberrypi/linux/${tag}/Makefile" \
| awk '
/^VERSION/ { version=$3 }
/^PATCHLEVEL/ { patchlevel=$3 }
/^SUBLEVEL/ { sublevel=$3 }
END { print version "." patchlevel "." sublevel }
'
}
# ── RPi kernel update ───────────────────────────────────────────────
if [ "$RPI_UPDATE" = "true" ] && [ -n "$LATEST_RPI_TAG" ]; then
echo "Updating RPi kernel to $LATEST_RPI_TAG ..." >&2
# Download tarball and compute checksums
TARBALL_URL="https://github.com/raspberrypi/linux/archive/refs/tags/${LATEST_RPI_TAG}.tar.gz"
TMP=$(mktemp)
curl -sL "$TARBALL_URL" -o "$TMP"
NEW_SHA256=$(shasum -a 256 "$TMP" | awk '{print $1}')
NEW_SHA512=$(shasum -a 512 "$TMP" | awk '{print $1}')
rm -f "$TMP"
echo " SHA256: $NEW_SHA256" >&2
echo " SHA512: $NEW_SHA512" >&2
# Get actual kernel version for the config header
KERNEL_VERSION=$(get_kernel_version "$LATEST_RPI_TAG")
echo " Kernel version: $KERNEL_VERSION" >&2
# Update patch file
sed -i "s/+ linux_version: .*/+ linux_version: ${LATEST_RPI_TAG}/" "$PATCH_FILE"
sed -i "s/+ linux_sha256: .*/+ linux_sha256: ${NEW_SHA256}/" "$PATCH_FILE"
sed -i "s/+ linux_sha512: .*/+ linux_sha512: ${NEW_SHA512}/" "$PATCH_FILE"
sed -i "s|+# Linux/arm64 .* Kernel Configuration|+# Linux/arm64 ${KERNEL_VERSION} Kernel Configuration|" "$PATCH_FILE"
fi
# ── Talos update ────────────────────────────────────────────────────
if [ "$TALOS_UPDATE" = "true" ] && [ -n "$LATEST_TALOS" ]; then
echo "Updating Talos to $LATEST_TALOS ..." >&2
# Update TALOS_VERSION in Makefile
sed -i "s/^TALOS_VERSION = .*/TALOS_VERSION = ${LATEST_TALOS}/" "$MAKEFILE"
# Derive matching PKG_VERSION (same major.minor as Talos)
PKG_MINOR=$(echo "$LATEST_TALOS" | sed -E 's/^(v[0-9]+\.[0-9]+)\..*/\1/')
LATEST_PKG=$(curl -sf "https://api.github.com/repos/siderolabs/pkgs/tags?per_page=20" \
| jq -r "[.[] | select(.name | startswith(\"${PKG_MINOR}\"))][0].name")
if [ -n "$LATEST_PKG" ] && [ "$LATEST_PKG" != "null" ]; then
echo " Updating PKG_VERSION to $LATEST_PKG" >&2
sed -i "s/^PKG_VERSION = .*/PKG_VERSION = ${LATEST_PKG}/" "$MAKEFILE"
else
echo " WARNING: No matching pkgs tag for $PKG_MINOR — keeping current PKG_VERSION" >&2
fi
fi
# ── Smoke test — verify patches apply ───────────────────────────────
echo "Running patch smoke test ..." >&2
if ! gmake checkouts patches; then
echo "Patches failed to apply!" >&2
gmake checkouts-clean >/dev/null 2>&1 || true
echo "patch_failed=true"
exit 0
fi
gmake checkouts-clean >/dev/null 2>&1
# ── Generate tag ────────────────────────────────────────────────────
TALOS_VER=$(grep '^TALOS_VERSION' "$MAKEFILE" | awk '{print $NF}')
RPI_TAG=$(grep '+ linux_version:' "$PATCH_FILE" | awk '{print $NF}')
KERNEL_VER=$(get_kernel_version "$RPI_TAG")
# Find next build number for this component combination
TAG_PREFIX="${TALOS_VER}-k${KERNEL_VER}"
LAST_BUILD=$(git tag -l "${TAG_PREFIX}-*" \
| sed "s|${TAG_PREFIX}-||" \
| sort -n \
| tail -1)
NEXT_BUILD=$(( ${LAST_BUILD:-0} + 1 ))
NEW_TAG="${TAG_PREFIX}-${NEXT_BUILD}"
# ── Update README badges and examples ───────────────────────────────
README="README.md"
if [ -f "$README" ]; then
OLD_TALOS=$(sed -n 's/.*talos-v\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p' "$README" | head -1)
OLD_KERNEL=$(sed -n 's/.*kernel-\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p' "$README" | head -1)
OLD_TAG=$(sed -n 's/.*\(v[0-9]*\.[0-9]*\.[0-9]*-k[0-9]*\.[0-9]*\.[0-9]*-[0-9]*\).*/\1/p' "$README" | head -1)
echo "Updating README: talos v${OLD_TALOS} → v${TALOS_VER}, kernel ${OLD_KERNEL}${KERNEL_VER}, tag ${OLD_TAG}${NEW_TAG}" >&2
sed -i "s/talos-v${OLD_TALOS}/talos-${TALOS_VER}/g" "$README"
sed -i "s/kernel-${OLD_KERNEL}/kernel-${KERNEL_VER}/g" "$README"
sed -i "s/\`v${OLD_TALOS}\`/\`${TALOS_VER}\`/g" "$README"
sed -i "s/\`k${OLD_KERNEL}\`/\`k${KERNEL_VER}\`/g" "$README"
if [ -n "$OLD_TAG" ]; then
sed -i "s/${OLD_TAG}/${NEW_TAG}/g" "$README"
fi
fi
echo "Generated tag: $NEW_TAG" >&2
echo "new_tag=$NEW_TAG"

View File

@ -1,54 +1,57 @@
#!/usr/bin/env bash
# Check for upstream Talos and RPi kernel updates
#
# Compares current versions in Makefile against the latest GitHub releases.
# Outputs GitHub Actions-compatible variables for use in CI workflows.
# Compares current versions (from Makefile + pkgs patch) against the
# latest GitHub releases/tags. Outputs GitHub Actions-compatible variables.
#
# Usage:
# ./scripts/check-upstream.sh # Print results
# ./scripts/check-upstream.sh # Print results to stdout/stderr
# ./scripts/check-upstream.sh >> "$GITHUB_OUTPUT" # For CI
set -euo pipefail
MAKEFILE="${MAKEFILE:-Makefile}"
PATCH_FILE="${PATCH_FILE:-patches/siderolabs/pkgs/0001-Patched-for-Raspberry-Pi-5.patch}"
# Extract current versions from Makefile
CURRENT_TALOS=$(grep '^TALOS_VERSION' "$MAKEFILE" | head -1 | awk '{print $NF}')
CURRENT_PKG=$(grep '^PKG_VERSION' "$MAKEFILE" | head -1 | awk '{print $NF}')
# ── Current versions ────────────────────────────────────────────────
CURRENT_TALOS=$(grep '^TALOS_VERSION' "$MAKEFILE" | awk '{print $NF}')
CURRENT_RPI_TAG=$(grep '+ linux_version:' "$PATCH_FILE" | awk '{print $NF}')
echo "Current Talos version: $CURRENT_TALOS"
echo "Current PKG version: $CURRENT_PKG"
echo "Current Talos version: $CURRENT_TALOS" >&2
echo "Current RPi kernel tag: $CURRENT_RPI_TAG" >&2
# Check latest Talos stable release
# ── Latest versions from GitHub API ─────────────────────────────────
LATEST_TALOS=$(curl -sf "https://api.github.com/repos/siderolabs/talos/releases/latest" \
| grep '"tag_name"' | sed -E 's/.*"tag_name": *"([^"]+)".*/\1/')
| jq -r '.tag_name')
echo "Latest Talos release: $LATEST_TALOS"
LATEST_RPI_TAG=$(curl -sf "https://api.github.com/repos/raspberrypi/linux/tags?per_page=20" \
| jq -r '[.[] | select(.name | startswith("stable_"))][0].name')
# Check latest RPi kernel stable tag (format: stable_YYYYMMDD)
LATEST_RPI_KERNEL=$(curl -sf "https://api.github.com/repos/raspberrypi/linux/tags?per_page=10" \
| grep '"name"' | grep 'stable_' | head -1 | sed -E 's/.*"name": *"([^"]+)".*/\1/')
echo "Latest Talos release: $LATEST_TALOS" >&2
echo "Latest RPi kernel tag: $LATEST_RPI_TAG" >&2
echo "Latest RPi kernel tag: $LATEST_RPI_KERNEL"
# Output for GitHub Actions
echo "talos_current=$CURRENT_TALOS"
echo "talos_latest=$LATEST_TALOS"
# ── Determine what needs updating ───────────────────────────────────
TALOS_UPDATE=false
RPI_UPDATE=false
if [ "$CURRENT_TALOS" != "$LATEST_TALOS" ]; then
echo "talos_update=true"
TALOS_UPDATE=true
echo ">> Talos update available: $CURRENT_TALOS -> $LATEST_TALOS" >&2
else
echo "talos_update=false"
echo ">> Talos is up to date" >&2
fi
# For RPi kernel, we output what we found — the actual version tracking
# depends on the pkgs patch content which references a specific kernel tag
echo "rpi_current=check-patch"
echo "rpi_latest=$LATEST_RPI_KERNEL"
if [ "$CURRENT_RPI_TAG" != "$LATEST_RPI_TAG" ]; then
RPI_UPDATE=true
echo ">> RPi kernel update available: $CURRENT_RPI_TAG -> $LATEST_RPI_TAG" >&2
else
echo ">> RPi kernel is up to date" >&2
fi
# We always flag RPi kernel for review since we can't easily parse the
# patch to extract the exact pinned version
echo "rpi_update=true"
echo ">> RPi kernel latest stable: $LATEST_RPI_KERNEL (review patch manually)" >&2
# ── Output for GitHub Actions ───────────────────────────────────────
echo "talos_current=$CURRENT_TALOS"
echo "talos_latest=$LATEST_TALOS"
echo "talos_update=$TALOS_UPDATE"
echo "rpi_current=$CURRENT_RPI_TAG"
echo "rpi_latest=$LATEST_RPI_TAG"
echo "rpi_update=$RPI_UPDATE"