fix: make RPi partition 1 self-sufficient boot fallback
Some checks failed
CI / Go Tests (push) Has been cancelled
CI / Build Go Binaries (amd64, linux, linux-amd64) (push) Has been cancelled
CI / Build Go Binaries (arm64, linux, linux-arm64) (push) Has been cancelled
CI / Shellcheck (push) Has been cancelled
Release / Test (push) Has been cancelled
Release / Build Binaries (amd64, linux, linux-amd64) (push) Has been cancelled
Release / Build Binaries (arm64, linux, linux-arm64) (push) Has been cancelled
Release / Build ISO (amd64) (push) Has been cancelled
Release / Create Release (push) Has been cancelled
Some checks failed
CI / Go Tests (push) Has been cancelled
CI / Build Go Binaries (amd64, linux, linux-amd64) (push) Has been cancelled
CI / Build Go Binaries (arm64, linux, linux-arm64) (push) Has been cancelled
CI / Shellcheck (push) Has been cancelled
Release / Test (push) Has been cancelled
Release / Build Binaries (amd64, linux, linux-amd64) (push) Has been cancelled
Release / Build Binaries (arm64, linux, linux-arm64) (push) Has been cancelled
Release / Build ISO (amd64) (push) Has been cancelled
Release / Create Release (push) Has been cancelled
The autoboot.txt A/B redirect requires newer RPi EEPROM firmware. On older EEPROMs, autoboot.txt is silently ignored and the firmware tries to boot from partition 1 directly — failing with a rainbow screen because partition 1 had no kernel or initramfs. Changes: - Increase partition 1 from 32 MB to 384 MB - Populate partition 1 with full boot files (kernel, initramfs, config.txt with kernel= directive, DTBs, overlays) - Keep autoboot.txt for A/B redirect on supported EEPROMs - When autoboot.txt works: boots from partition 2 (A/B scheme) - When autoboot.txt is unsupported: boots from partition 1 (fallback) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,14 +2,14 @@
|
||||
# create-rpi-image.sh — Create a raw disk image for Raspberry Pi SD card
|
||||
#
|
||||
# Partition layout (MBR):
|
||||
# Part 1: Boot Control (32 MB, FAT32, label KSOLOCTL) — firmware + autoboot.txt
|
||||
# Part 1: Boot/Control (384 MB, FAT32, label KSOLOCTL) — firmware + kernel + initramfs + autoboot.txt
|
||||
# Part 2: Boot A (256 MB, FAT32, label KSOLOA) — kernel + DTBs + initramfs
|
||||
# Part 3: Boot B (256 MB, FAT32, label KSOLOB) — same as Boot A (initially identical)
|
||||
# Part 4: Data (remaining of 2GB, ext4, label KSOLODATA)
|
||||
#
|
||||
# The RPi EEPROM loads start4.elf from partition 1 (KSOLOCTL).
|
||||
# autoboot.txt on partition 1 redirects boot_partition to 2 (Boot A) or 3 (Boot B).
|
||||
# The firmware then loads config.txt, kernel, and initramfs from the selected partition.
|
||||
# The RPi EEPROM loads start4.elf from partition 1.
|
||||
# If autoboot.txt is supported (newer EEPROM), firmware redirects to partition 2/3 for A/B boot.
|
||||
# If autoboot.txt is NOT supported (older EEPROM), partition 1 has full boot files as fallback.
|
||||
#
|
||||
# MBR is required — GPT + autoboot.txt is not reliably supported on Pi 4.
|
||||
#
|
||||
@@ -69,15 +69,16 @@ dd if=/dev/zero of="$IMG_OUTPUT" bs=1M count=0 seek="$IMG_SIZE_MB" 2>/dev/null
|
||||
# --- Partition table (MBR) ---
|
||||
# MBR is required for reliable RPi boot with autoboot.txt.
|
||||
# GPT + autoboot.txt fails on many Pi 4 EEPROM versions.
|
||||
# Part 1: Boot Control 32 MB FAT32 (firmware + autoboot.txt)
|
||||
# Part 1: Boot/Control 384 MB FAT32 (firmware + kernel + initramfs + autoboot.txt)
|
||||
# Part 2: Boot A 256 MB FAT32 (kernel + initramfs + DTBs)
|
||||
# Part 3: Boot B 256 MB FAT32 (kernel + initramfs + DTBs)
|
||||
# Part 4: Data remaining ext4
|
||||
sfdisk "$IMG_OUTPUT" << EOF
|
||||
label: dos
|
||||
|
||||
# Boot Control partition: 32 MB, FAT32 (type 0c = W95 FAT32 LBA)
|
||||
start=2048, size=65536, type=c, bootable
|
||||
# Boot/Control partition: 384 MB, FAT32 (type 0c = W95 FAT32 LBA)
|
||||
# Contains firmware + autoboot.txt for A/B redirect, PLUS full boot files as fallback
|
||||
start=2048, size=786432, type=c, bootable
|
||||
# Boot A partition: 256 MB, FAT32
|
||||
size=524288, type=c
|
||||
# Boot B partition: 256 MB, FAT32
|
||||
@@ -149,46 +150,6 @@ mount "$P2" "$MNT_BOOTA"
|
||||
mount "$P3" "$MNT_BOOTB"
|
||||
mount "$P4" "$MNT_DATA"
|
||||
|
||||
# --- Boot Control Partition (KSOLOCTL) ---
|
||||
# The RPi EEPROM loads start4.elf from partition 1.
|
||||
# autoboot.txt tells the firmware which partition has config.txt + kernel.
|
||||
echo " Writing autoboot.txt + firmware to boot control partition..."
|
||||
cat > "$MNT_CTL/autoboot.txt" << 'AUTOBOOT'
|
||||
[all]
|
||||
tryboot_a_b=1
|
||||
boot_partition=2
|
||||
[tryboot]
|
||||
boot_partition=3
|
||||
AUTOBOOT
|
||||
|
||||
# Minimal config.txt on partition 1 — firmware reads this BEFORE autoboot.txt
|
||||
# to determine arm_64bit mode and GPU settings. Without arm_64bit=1 here,
|
||||
# the firmware defaults to 32-bit and can't load our 64-bit kernel.
|
||||
cat > "$MNT_CTL/config.txt" << 'CFGTXT'
|
||||
arm_64bit=1
|
||||
enable_uart=1
|
||||
gpu_mem=16
|
||||
CFGTXT
|
||||
|
||||
# Copy firmware blobs — REQUIRED on partition 1 for EEPROM to boot
|
||||
if ls "$RPI_FIRMWARE_DIR"/start*.elf 1>/dev/null 2>&1; then
|
||||
cp "$RPI_FIRMWARE_DIR"/start*.elf "$MNT_CTL/"
|
||||
fi
|
||||
if ls "$RPI_FIRMWARE_DIR"/fixup*.dat 1>/dev/null 2>&1; then
|
||||
cp "$RPI_FIRMWARE_DIR"/fixup*.dat "$MNT_CTL/"
|
||||
fi
|
||||
if [ -f "$RPI_FIRMWARE_DIR/bootcode.bin" ]; then
|
||||
cp "$RPI_FIRMWARE_DIR/bootcode.bin" "$MNT_CTL/"
|
||||
fi
|
||||
|
||||
# Copy DTBs to partition 1 — firmware may need them before redirecting
|
||||
if ls "$RPI_FIRMWARE_DIR"/bcm27*.dtb 1>/dev/null 2>&1; then
|
||||
cp "$RPI_FIRMWARE_DIR"/bcm27*.dtb "$MNT_CTL/"
|
||||
fi
|
||||
if [ -d "$RPI_FIRMWARE_DIR/overlays" ]; then
|
||||
cp -r "$RPI_FIRMWARE_DIR/overlays" "$MNT_CTL/"
|
||||
fi
|
||||
|
||||
# --- Helper: populate a boot partition ---
|
||||
populate_boot_partition() {
|
||||
local MNT="$1"
|
||||
@@ -231,6 +192,39 @@ CFGTXT
|
||||
echo "$VERSION" > "$MNT/version.txt"
|
||||
}
|
||||
|
||||
# --- Boot Control Partition (KSOLOCTL) ---
|
||||
# Partition 1 serves dual purpose:
|
||||
# 1. Contains firmware + autoboot.txt for A/B redirect (if EEPROM supports it)
|
||||
# 2. Contains full boot files (kernel + initramfs) as fallback if autoboot.txt isn't supported
|
||||
echo " Writing firmware + autoboot.txt + boot files to partition 1..."
|
||||
|
||||
# autoboot.txt — tells firmware which partition to boot from (A/B switching)
|
||||
# If the EEPROM doesn't support this, it's silently ignored and the firmware
|
||||
# falls back to booting from partition 1 using config.txt below.
|
||||
cat > "$MNT_CTL/autoboot.txt" << 'AUTOBOOT'
|
||||
[all]
|
||||
tryboot_a_b=1
|
||||
boot_partition=2
|
||||
[tryboot]
|
||||
boot_partition=3
|
||||
AUTOBOOT
|
||||
|
||||
# Copy firmware blobs — REQUIRED on partition 1 for EEPROM to boot
|
||||
if ls "$RPI_FIRMWARE_DIR"/start*.elf 1>/dev/null 2>&1; then
|
||||
cp "$RPI_FIRMWARE_DIR"/start*.elf "$MNT_CTL/"
|
||||
fi
|
||||
if ls "$RPI_FIRMWARE_DIR"/fixup*.dat 1>/dev/null 2>&1; then
|
||||
cp "$RPI_FIRMWARE_DIR"/fixup*.dat "$MNT_CTL/"
|
||||
fi
|
||||
if [ -f "$RPI_FIRMWARE_DIR/bootcode.bin" ]; then
|
||||
cp "$RPI_FIRMWARE_DIR/bootcode.bin" "$MNT_CTL/"
|
||||
fi
|
||||
|
||||
# Full boot files on partition 1 — fallback if autoboot.txt redirect doesn't work.
|
||||
# When autoboot.txt works, firmware switches to partition 2 and reads config.txt there.
|
||||
# When autoboot.txt is unsupported, firmware reads THIS config.txt and boots from here.
|
||||
populate_boot_partition "$MNT_CTL" "Boot Control (KSOLOCTL)"
|
||||
|
||||
# --- Boot A Partition (KSOLOA) ---
|
||||
populate_boot_partition "$MNT_BOOTA" "Boot A (KSOLOA)"
|
||||
|
||||
@@ -248,7 +242,7 @@ sync
|
||||
echo ""
|
||||
echo "==> Raspberry Pi disk image created: $IMG_OUTPUT"
|
||||
echo " Size: $(du -h "$IMG_OUTPUT" | cut -f1)"
|
||||
echo " Part 1 (KSOLOCTL): Firmware + autoboot.txt (boot control)"
|
||||
echo " Part 1 (KSOLOCTL): Firmware + kernel + initramfs + autoboot.txt (boot/control)"
|
||||
echo " Part 2 (KSOLOA): Boot A — kernel + initramfs + DTBs"
|
||||
echo " Part 3 (KSOLOB): Boot B — kernel + initramfs + DTBs"
|
||||
echo " Part 4 (KSOLODATA): Persistent K8s state"
|
||||
|
||||
Reference in New Issue
Block a user