fix: RPi image uses MBR and firmware on boot partition
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
- Switch from GPT to MBR (dos) partition table — GPT + autoboot.txt fails on many Pi 4 EEPROM versions - Copy firmware blobs (start*.elf, fixup*.dat) to partition 1 (KSOLOCTL) so the EEPROM can find and load them - Increase boot control partition from 16 MB to 32 MB to fit firmware - Mark partition 1 as bootable Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,15 +1,17 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# create-rpi-image.sh — Create a raw disk image for Raspberry Pi SD card
|
# create-rpi-image.sh — Create a raw disk image for Raspberry Pi SD card
|
||||||
#
|
#
|
||||||
# Partition layout (GPT):
|
# Partition layout (MBR):
|
||||||
# Part 1: Boot Control (16 MB, FAT32, label KSOLOCTL) — autoboot.txt only
|
# Part 1: Boot Control (32 MB, FAT32, label KSOLOCTL) — firmware + autoboot.txt
|
||||||
# Part 2: Boot A (256 MB, FAT32, label KSOLOA) — firmware + kernel + DTBs + initramfs
|
# 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 3: Boot B (256 MB, FAT32, label KSOLOB) — same as Boot A (initially identical)
|
||||||
# Part 4: Data (remaining of 2GB, ext4, label KSOLODATA)
|
# Part 4: Data (remaining of 2GB, ext4, label KSOLODATA)
|
||||||
#
|
#
|
||||||
# The RPi uses autoboot.txt in the control partition to implement A/B boot
|
# The RPi EEPROM loads start4.elf from partition 1 (KSOLOCTL).
|
||||||
# via the tryboot mechanism (tryboot_a_b=1). Normal boot → partition 2 (Boot A),
|
# autoboot.txt on partition 1 redirects boot_partition to 2 (Boot A) or 3 (Boot B).
|
||||||
# tryboot → partition 3 (Boot B).
|
# The firmware then loads config.txt, kernel, and initramfs from the selected partition.
|
||||||
|
#
|
||||||
|
# MBR is required — GPT + autoboot.txt is not reliably supported on Pi 4.
|
||||||
#
|
#
|
||||||
# Usage: build/scripts/create-rpi-image.sh
|
# Usage: build/scripts/create-rpi-image.sh
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
@@ -64,22 +66,24 @@ mkdir -p "$OUTPUT_DIR"
|
|||||||
# --- Create sparse image ---
|
# --- Create sparse image ---
|
||||||
dd if=/dev/zero of="$IMG_OUTPUT" bs=1M count=0 seek="$IMG_SIZE_MB" 2>/dev/null
|
dd if=/dev/zero of="$IMG_OUTPUT" bs=1M count=0 seek="$IMG_SIZE_MB" 2>/dev/null
|
||||||
|
|
||||||
# --- Partition table (GPT) ---
|
# --- Partition table (MBR) ---
|
||||||
# Part 1: Boot Control 16 MB FAT32
|
# MBR is required for reliable RPi boot with autoboot.txt.
|
||||||
# Part 2: Boot A 256 MB FAT32
|
# GPT + autoboot.txt fails on many Pi 4 EEPROM versions.
|
||||||
# Part 3: Boot B 256 MB FAT32
|
# Part 1: Boot Control 32 MB FAT32 (firmware + 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
|
# Part 4: Data remaining ext4
|
||||||
sfdisk "$IMG_OUTPUT" << EOF
|
sfdisk "$IMG_OUTPUT" << EOF
|
||||||
label: gpt
|
label: dos
|
||||||
|
|
||||||
# Boot Control partition: 16 MB
|
# Boot Control partition: 32 MB, FAT32 (type 0c = W95 FAT32 LBA)
|
||||||
start=2048, size=32768, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, name="BootCtl"
|
start=2048, size=65536, type=c, bootable
|
||||||
# Boot A partition: 256 MB
|
# Boot A partition: 256 MB, FAT32
|
||||||
size=524288, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, name="BootA"
|
size=524288, type=c
|
||||||
# Boot B partition: 256 MB
|
# Boot B partition: 256 MB, FAT32
|
||||||
size=524288, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, name="BootB"
|
size=524288, type=c
|
||||||
# Data partition: remaining
|
# Data partition: remaining, Linux
|
||||||
type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="Data"
|
type=83
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# --- Set up loop device ---
|
# --- Set up loop device ---
|
||||||
@@ -146,7 +150,9 @@ mount "$P3" "$MNT_BOOTB"
|
|||||||
mount "$P4" "$MNT_DATA"
|
mount "$P4" "$MNT_DATA"
|
||||||
|
|
||||||
# --- Boot Control Partition (KSOLOCTL) ---
|
# --- Boot Control Partition (KSOLOCTL) ---
|
||||||
echo " Writing autoboot.txt..."
|
# 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'
|
cat > "$MNT_CTL/autoboot.txt" << 'AUTOBOOT'
|
||||||
[all]
|
[all]
|
||||||
tryboot_a_b=1
|
tryboot_a_b=1
|
||||||
@@ -155,6 +161,17 @@ boot_partition=2
|
|||||||
boot_partition=3
|
boot_partition=3
|
||||||
AUTOBOOT
|
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
|
||||||
|
|
||||||
# --- Helper: populate a boot partition ---
|
# --- Helper: populate a boot partition ---
|
||||||
populate_boot_partition() {
|
populate_boot_partition() {
|
||||||
local MNT="$1"
|
local MNT="$1"
|
||||||
@@ -183,17 +200,6 @@ CFGTXT
|
|||||||
# Copy initramfs
|
# Copy initramfs
|
||||||
cp "$INITRAMFS" "$MNT/kubesolo-os.gz"
|
cp "$INITRAMFS" "$MNT/kubesolo-os.gz"
|
||||||
|
|
||||||
# Copy firmware blobs (start*.elf, fixup*.dat)
|
|
||||||
if ls "$RPI_FIRMWARE_DIR"/start*.elf 1>/dev/null 2>&1; then
|
|
||||||
cp "$RPI_FIRMWARE_DIR"/start*.elf "$MNT/"
|
|
||||||
fi
|
|
||||||
if ls "$RPI_FIRMWARE_DIR"/fixup*.dat 1>/dev/null 2>&1; then
|
|
||||||
cp "$RPI_FIRMWARE_DIR"/fixup*.dat "$MNT/"
|
|
||||||
fi
|
|
||||||
if [ -f "$RPI_FIRMWARE_DIR/bootcode.bin" ]; then
|
|
||||||
cp "$RPI_FIRMWARE_DIR/bootcode.bin" "$MNT/"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Copy DTB overlays
|
# Copy DTB overlays
|
||||||
if [ -d "$RPI_FIRMWARE_DIR/overlays" ]; then
|
if [ -d "$RPI_FIRMWARE_DIR/overlays" ]; then
|
||||||
cp -r "$RPI_FIRMWARE_DIR/overlays" "$MNT/"
|
cp -r "$RPI_FIRMWARE_DIR/overlays" "$MNT/"
|
||||||
@@ -225,9 +231,9 @@ sync
|
|||||||
echo ""
|
echo ""
|
||||||
echo "==> Raspberry Pi disk image created: $IMG_OUTPUT"
|
echo "==> Raspberry Pi disk image created: $IMG_OUTPUT"
|
||||||
echo " Size: $(du -h "$IMG_OUTPUT" | cut -f1)"
|
echo " Size: $(du -h "$IMG_OUTPUT" | cut -f1)"
|
||||||
echo " Part 1 (KSOLOCTL): Boot control (autoboot.txt)"
|
echo " Part 1 (KSOLOCTL): Firmware + autoboot.txt (boot control)"
|
||||||
echo " Part 2 (KSOLOA): Boot A — firmware + kernel + initramfs"
|
echo " Part 2 (KSOLOA): Boot A — kernel + initramfs + DTBs"
|
||||||
echo " Part 3 (KSOLOB): Boot B — firmware + kernel + initramfs"
|
echo " Part 3 (KSOLOB): Boot B — kernel + initramfs + DTBs"
|
||||||
echo " Part 4 (KSOLODATA): Persistent K8s state"
|
echo " Part 4 (KSOLODATA): Persistent K8s state"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Write to SD card with:"
|
echo "Write to SD card with:"
|
||||||
|
|||||||
Reference in New Issue
Block a user