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>
219 lines
8.0 KiB
Makefile
219 lines
8.0 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="configTxt=$$(cat $(PWD)/config/config.txt)" \
|
|
$(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 && \
|
|
git am "$(PATCHES_DIRECTORY)/talos-rpi5/sbc-raspberrypi5/0003-"*.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
|