Produces a UEFI-bootable raw disk image for generic ARM64 hosts (QEMU virt, Ampere/Graviton cloud, ARM64 SBCs with UEFI). Reuses the existing 4-partition A/B layout from x86 (EFI 256 MB FAT32 + System A 512 MB ext4 + System B 512 MB ext4 + Data ext4 remainder). Changes: - build/scripts/create-disk-image.sh: TARGET_ARCH env var (amd64 default, arm64). Selects kernel source path, grub-mkimage target (x86_64-efi vs arm64-efi), EFI binary name (bootx64.efi vs BOOTAA64.EFI), grub.cfg variant, and whether to also install BIOS GRUB (x86 only). - build/grub/grub-arm64.cfg: ARM64 variant of grub.cfg. Identical A/B logic; console=ttyAMA0+ttyS0 to cover QEMU virt PL011, Ampere PL011, and Graviton 16550-compat. - build/Dockerfile.builder: add grub-efi-amd64-bin, grub-efi-arm64-bin, grub-pc-bin, grub-common, grub2-common so the builder container can produce EFI images for both architectures. - hack/dev-vm-arm64.sh: split into kernel mode (direct -kernel/-initrd, fast iteration) and --disk mode (UEFI firmware + GRUB + disk image, full integration test). Probes common UEFI firmware paths on Ubuntu/Fedora/macOS. Default kernel path now points at kernel-arm64-generic/Image with fallback to the renamed custom-kernel-rpi/Image. - test/qemu/test-boot-arm64-disk.sh: new CI test for the full UEFI -> GRUB -> kernel -> stage-90 boot chain. Uses a scratch copy of the disk so grubenv writes don't mutate the source artifact. - Makefile: new disk-image-arm64 target (depends on rootfs-arm64 + kernel-arm64), new test-boot-arm64-disk target, .PHONY + help updates. Phase 3 scaffold is in place. First real end-to-end ARM64 build runs in the next step on the Odroid runner — that's where we find out what's actually broken. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
87 lines
2.7 KiB
INI
87 lines
2.7 KiB
INI
# KubeSolo OS — GRUB Configuration (ARM64)
|
|
# A/B partition boot with automatic rollback.
|
|
#
|
|
# Same A/B logic as build/grub/grub.cfg; only the console parameters differ
|
|
# (ARM64 PL011 / 16550-compat UART rather than x86 ttyS0).
|
|
#
|
|
# Partition layout:
|
|
# (hd0,gpt1) — EFI/Boot (256 MB, FAT32) — contains GRUB + grubenv
|
|
# (hd0,gpt2) — System A (512 MB, ext4) — vmlinuz + kubesolo-os.gz
|
|
# (hd0,gpt3) — System B (512 MB, ext4) — vmlinuz + kubesolo-os.gz
|
|
# (hd0,gpt4) — Data (remaining, ext4) — persistent K8s state
|
|
|
|
set default=0
|
|
set timeout=3
|
|
|
|
load_env
|
|
|
|
# --- A/B Rollback Logic (identical to amd64 grub.cfg) ---
|
|
|
|
if [ "${boot_success}" != "1" ]; then
|
|
if [ "${boot_counter}" = "0" ]; then
|
|
if [ "${active_slot}" = "A" ]; then
|
|
set active_slot=B
|
|
else
|
|
set active_slot=A
|
|
fi
|
|
save_env active_slot
|
|
set boot_counter=3
|
|
save_env boot_counter
|
|
else
|
|
if [ "${boot_counter}" = "3" ]; then
|
|
set boot_counter=2
|
|
elif [ "${boot_counter}" = "2" ]; then
|
|
set boot_counter=1
|
|
elif [ "${boot_counter}" = "1" ]; then
|
|
set boot_counter=0
|
|
fi
|
|
save_env boot_counter
|
|
fi
|
|
fi
|
|
|
|
set boot_success=0
|
|
save_env boot_success
|
|
|
|
if [ "${active_slot}" = "A" ]; then
|
|
set root='(hd0,gpt2)'
|
|
set slot_label="System A"
|
|
else
|
|
set root='(hd0,gpt3)'
|
|
set slot_label="System B"
|
|
fi
|
|
|
|
# --- ARM64 console string ---
|
|
# Covers QEMU virt (ttyAMA0), Ampere/RPi-equivalent PL011 (ttyAMA0), and
|
|
# Graviton/16550-compat (ttyS0). Last `console=` becomes the system console.
|
|
|
|
menuentry "KubeSolo OS (${slot_label})" {
|
|
echo "Booting KubeSolo OS from ${slot_label}..."
|
|
echo "Boot counter: ${boot_counter}, Boot success: ${boot_success}"
|
|
linux /vmlinuz kubesolo.data=LABEL=KSOLODATA console=ttyAMA0,115200 console=ttyS0,115200 quiet
|
|
initrd /kubesolo-os.gz
|
|
}
|
|
|
|
menuentry "KubeSolo OS (${slot_label}) — Debug Mode" {
|
|
echo "Booting KubeSolo OS (debug) from ${slot_label}..."
|
|
linux /vmlinuz kubesolo.data=LABEL=KSOLODATA kubesolo.debug console=ttyAMA0,115200 console=ttyS0,115200
|
|
initrd /kubesolo-os.gz
|
|
}
|
|
|
|
menuentry "KubeSolo OS — Emergency Shell" {
|
|
echo "Booting to emergency shell..."
|
|
linux /vmlinuz kubesolo.shell console=ttyAMA0,115200 console=ttyS0,115200
|
|
initrd /kubesolo-os.gz
|
|
}
|
|
|
|
menuentry "KubeSolo OS — Boot Other Slot" {
|
|
if [ "${active_slot}" = "A" ]; then
|
|
set root='(hd0,gpt3)'
|
|
echo "Booting from System B (passive)..."
|
|
else
|
|
set root='(hd0,gpt2)'
|
|
echo "Booting from System A (passive)..."
|
|
fi
|
|
linux /vmlinuz kubesolo.data=LABEL=KSOLODATA kubesolo.debug console=ttyAMA0,115200 console=ttyS0,115200
|
|
initrd /kubesolo-os.gz
|
|
}
|