#!/bin/zsh # vim: set ft=sh sw=4 ts=4 sts=4 et : set -eu function copy_firmware() { local dev="$1" local efi_part local mountpoint=/run/media/coreos-efi if [ ! -d RPi4boot ]; then download_firmware fi printf 'Waiting for device to settle ...' >&2 until [ -n "${efi_part-}" ]; do printf '.' efi_part=$( lsblk -o LABEL,PATH "${dev}" \ | awk '$1=="EFI-SYSTEM"{print $2}' ) sleep 0.25 done printf '\n' mkdir -p "${mountpoint}" mount "${efi_part}" "${mountpoint}" rsync -rtiOh --ignore-existing RPi4boot/boot/efi/ "${mountpoint}" sync; sync; sync umount "${mountpoint}" rmdir "${mountpoint}" } function download_firmware() { local rpm echo 'Downloading Raspberry Pi Firmware blobs ...' mkdir RPi4boot podman run --rm -it \ -v $(PWD)/RPi4boot:/RPi4boot:rw,z \ registry.fedoraproject.org/fedora:38 \ dnf install -y \ --downloadonly \ --forcearch=aarch64 \ --destdir=/RPi4boot \ uboot-images-armv8 \ bcm283x-firmware \ bcm283x-overlays -- for rpm in RPi4boot/*.rpm; do rpm2cpio "${rpm}" | cpio -idv -D RPi4boot/ done cp RPi4boot/usr/share/uboot/rpi_3/u-boot.bin RPi4boot/boot/efi/rpi3-u-boot.bin cp RPi4boot/usr/share/uboot/rpi_4/u-boot.bin RPi4boot/boot/efi/rpi4-u-boot.bin cp RPi4boot/usr/share/uboot/rpi_arm64/u-boot.bin RPi4boot/boot/efi/rpi-u-boot.bin } function hybridize_gpt() { local dev="$1" echo 'Creating Hybrid MBR partition table ...' sgdisk -h 2:EE "${dev}" echo type=0c,bootable | sfdisk -Y mbr -N 1 "${dev}" } function install_coreos() { local ignition="$1" local dev="$2" local url="$3" if [ -z "${url}" ]; then set -- -a aarch64 -s stable else set -- --image-url "${url}" fi coreos-installer install "$@" \ -i "${ignition}" \ --console ttyS0,115200n8 \ "${dev}" sync; sync; sync } function parse_args() { pi=4 image_url= while [ $# -gt 0 ]; do case "$1" in --pi) shift pi=${1} ;; --pi=*) pi=${1#--pi=} ;; --image-url) shift image_url=${1} ;; --image-url=*) image_url=${1#--image-url=} ;; *) if [ -z "${ignition-}" ]; then ignition="${1}" elif [ -z "${dev-}" ]; then dev="${1}" else usage >&2 exit 2 fi ;; esac shift done if [ -z "${ignition-}" ]; then usage >&2 exit 2 fi if [ -z "${dev-}" ]; then dev=/dev/disk/by-id/usb-Generic_STORAGE_DEVICE_000000001206-0:0 fi } function usage() { printf 'usage: %s [--pi PI] ignition [device]\n' "${0##*/}" } parse_args "$@" case "${pi}" in 0*|1) printf 'Raspberry Pi model %s is not supported\n' "${pi}" >&2 exit 1 ;; esac if [ $(id -u) -ne 0 ]; then exec sudo "$0" "$@" fi install_coreos "${ignition}" "${dev}" "${image_url}" case "${pi}" in 2|3) hybridize_gpt "${dev}" ;; esac copy_firmware "${dev}"