talos-rpi5/Makefile
Mathias Beaulieu-Duncan 5152b6cb44
All checks were successful
Build Talos CM5 Image / build (push) Successful in 2m41s
Check Upstream Updates / check-and-build (push) Successful in 5s
Simplify config: use configTxtAppend, drop SBC overlay patch
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

218 lines
7.9 KiB
Makefile

# Talos CM5 Builder — Custom Talos Linux images for Raspberry Pi CM5
#
# Forked from https://github.com/talos-rpi5/talos-builder
# Builds Talos with the RPi downstream kernel (CM5/RP1 support)
#
# Usage:
# make checkouts patches # Clone and patch upstream sources
# make kernel # Build RPi kernel (~15-30 min on ARM64)
# make overlay # Build U-Boot + firmware + DTBs
# make installer # Build installer image + raw disk image
# make release # Tag and push release images
# make clean # Remove checkouts and build artifacts
PKG_VERSION = v1.12.0
TALOS_VERSION = v1.12.4
SBCOVERLAY_VERSION = main
# Prefer GNU coreutils (macOS: brew install gnu-sed coreutils)
export PATH := /opt/homebrew/opt/gnu-sed/libexec/gnubin:$(PATH)
REGISTRY ?= docker.io
REGISTRY_USERNAME ?= svrnty
TAG ?= $(shell git describe --tags --exact-match 2>/dev/null || echo dev)
# Docker Hub image names (project-specific)
KERNEL_IMAGE = $(REGISTRY)/$(REGISTRY_USERNAME)/talos-rpi5-kernel
OVERLAY_IMAGE = $(REGISTRY)/$(REGISTRY_USERNAME)/talos-rpi5-overlay
IMAGER_IMAGE = $(REGISTRY)/$(REGISTRY_USERNAME)/talos-rpi5-imager
INSTALLER_IMAGE = $(REGISTRY)/$(REGISTRY_USERNAME)/talos-rpi5-installer
# Public image name on Docker Hub (used by talosctl upgrade)
IMAGE_NAME ?= talos-rpi5
# System extensions baked into the image
EXTENSIONS ?= ghcr.io/siderolabs/iscsi-tools:v0.1.6 ghcr.io/siderolabs/util-linux-tools:2.40.4
# Upstream repositories
PKG_REPOSITORY = https://github.com/siderolabs/pkgs.git
TALOS_REPOSITORY = https://github.com/siderolabs/talos.git
SBCOVERLAY_REPOSITORY = https://github.com/talos-rpi5/sbc-raspberrypi5.git
CHECKOUTS_DIRECTORY := $(PWD)/checkouts
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)-$(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" \
--overlay-image="$(OVERLAY_IMAGE):$(SBCOVERLAY_TAG)" \
--overlay-option="configTxtAppend=$$(cat $(PWD)/config/config.txt.append)" \
$(EXTENSION_FLAGS)
#
# Help
#
.PHONY: help
help:
@echo "Talos CM5 Builder"
@echo ""
@echo "Targets:"
@echo " checkouts — Clone upstream repositories"
@echo " patches — Apply RPi kernel + CM5 patches"
@echo " kernel — Build RPi downstream kernel"
@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 " clean — Remove checkouts and build artifacts"
@echo ""
@echo "Variables:"
@echo " TALOS_VERSION = $(TALOS_VERSION)"
@echo " PKG_VERSION = $(PKG_VERSION)"
@echo " REGISTRY = $(REGISTRY)"
@echo " REGISTRY_USERNAME = $(REGISTRY_USERNAME)"
@echo ""
@echo "Images:"
@echo " KERNEL_IMAGE = $(KERNEL_IMAGE)"
@echo " OVERLAY_IMAGE = $(OVERLAY_IMAGE)"
@echo " IMAGER_IMAGE = $(IMAGER_IMAGE)"
@echo " INSTALLER_IMAGE = $(INSTALLER_IMAGE)"
#
# Checkouts
#
.PHONY: checkouts checkouts-clean
checkouts:
git clone -c advice.detachedHead=false --branch "$(PKG_VERSION)" "$(PKG_REPOSITORY)" "$(CHECKOUTS_DIRECTORY)/pkgs"
git clone -c advice.detachedHead=false --branch "$(TALOS_VERSION)" "$(TALOS_REPOSITORY)" "$(CHECKOUTS_DIRECTORY)/talos"
git clone -c advice.detachedHead=false --branch "$(SBCOVERLAY_VERSION)" "$(SBCOVERLAY_REPOSITORY)" "$(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5"
checkouts-clean:
rm -rf "$(CHECKOUTS_DIRECTORY)/pkgs"
rm -rf "$(CHECKOUTS_DIRECTORY)/talos"
rm -rf "$(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5"
#
# Patches
#
.PHONY: patches-pkgs patches-talos patches-overlay patches
patches-pkgs:
cd "$(CHECKOUTS_DIRECTORY)/pkgs" && \
git am "$(PATCHES_DIRECTORY)/siderolabs/pkgs/"*.patch
patches-talos:
cd "$(CHECKOUTS_DIRECTORY)/talos" && \
git am "$(PATCHES_DIRECTORY)/siderolabs/talos/"*.patch
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
#
.PHONY: kernel
kernel:
cd "$(CHECKOUTS_DIRECTORY)/pkgs" && \
$(MAKE) docker-kernel \
TARGET_ARGS="--tag=$(KERNEL_IMAGE):$(PKGS_TAG) --push=true $(ATTESTATION_ARGS)" \
PLATFORM=linux/arm64
#
# Overlay — build U-Boot + firmware + DTBs
#
# The overlay's pkg.yaml references the kernel as PKGS_PREFIX/kernel:PKGS.
# We rewrite it to point to our project-specific kernel image name.
#
.PHONY: overlay
overlay:
@echo "SBCOVERLAY_TAG = $(SBCOVERLAY_TAG)"
@sed -i.bak 's|{{ .BUILD_ARG_PKGS_PREFIX }}/kernel:{{ .BUILD_ARG_PKGS }}|$(KERNEL_IMAGE):$(PKGS_TAG)|' \
"$(CHECKOUTS_DIRECTORY)/sbc-raspberrypi5/internal/base/pkg.yaml" && \
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 $(ATTESTATION_ARGS)" \
INSTALLER_ARCH=arm64 PLATFORM=linux/arm64
#
# Installer / Disk Image
#
# Builds the imager, installer-base, and installer images step by step,
# pushing each to our project-specific Docker Hub repos.
#
.PHONY: installer
installer:
cd "$(CHECKOUTS_DIRECTORY)/talos" && \
$(MAKE) \
REGISTRY=$(REGISTRY) USERNAME=$(REGISTRY_USERNAME) \
PKG_KERNEL=$(KERNEL_IMAGE):$(PKGS_TAG) \
INSTALLER_ARCH=arm64 PLATFORM=linux/arm64 \
kernel initramfs && \
$(MAKE) \
REGISTRY=$(REGISTRY) USERNAME=$(REGISTRY_USERNAME) \
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 $(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 $(ATTESTATION_ARGS)" && \
docker pull $(IMAGER_IMAGE):$(TALOS_TAG) && \
docker run --rm -t -v ./_out:/out --privileged --network=host \
$(IMAGER_IMAGE):$(TALOS_TAG) \
installer --arch arm64 \
--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 \
$(IMAGER_IMAGE):$(TALOS_TAG) \
metal --arch arm64 \
--base-installer-image="$(INSTALLER_IMAGE):$(TALOS_TAG)" \
$(IMAGER_COMMON_FLAGS)
#
# Release — tag images with the Git tag for stable references
#
.PHONY: release
release:
docker buildx imagetools create \
-t $(REGISTRY)/$(REGISTRY_USERNAME)/$(IMAGE_NAME):$(TAG) \
$(INSTALLER_IMAGE):$(TALOS_TAG)
#
# Clean
#
.PHONY: clean
clean: checkouts-clean
rm -rf _out
rm -rf checkouts/_out