summaryrefslogtreecommitdiff
path: root/f3s/pi-netbsd/flash/95netbsdflash/flash.sh
diff options
context:
space:
mode:
Diffstat (limited to 'f3s/pi-netbsd/flash/95netbsdflash/flash.sh')
-rwxr-xr-xf3s/pi-netbsd/flash/95netbsdflash/flash.sh82
1 files changed, 82 insertions, 0 deletions
diff --git a/f3s/pi-netbsd/flash/95netbsdflash/flash.sh b/f3s/pi-netbsd/flash/95netbsdflash/flash.sh
new file mode 100755
index 0000000..c15bb71
--- /dev/null
+++ b/f3s/pi-netbsd/flash/95netbsdflash/flash.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+# dracut pre-mount hook (SOURCED by dracut init — must not call exit/return at
+# top level in a way that aborts init; we keep all action inside an `if`).
+#
+# Trigger: a file `netbsd-flash-mode` (contents "dryrun" or "real") on the FAT
+# /boot partition. If absent, this hook does nothing and normal boot continues.
+#
+# SAFETY: the very first thing we do once triggered is DISARM — delete
+# config.txt and the trigger from the FAT partition — so that if anything later
+# fails, a power-cycle boots normally back into Rocky (config.txt gone => the Pi
+# firmware loads no initramfs).
+
+FATDEV=/dev/mmcblk0p1
+ROOTDEV=/dev/mmcblk0p3
+DISK=/dev/mmcblk0
+
+nf_log() { echo "netbsdflash: $*"; echo "netbsdflash: $*" > /dev/kmsg 2>/dev/null; }
+nf_reboot() { sync; sleep 2; reboot -f 2>/dev/null; sleep 2; echo b > /proc/sysrq-trigger 2>/dev/null; sleep 15; }
+
+mkdir -p /nf_fat /nf_root /nf_ram 2>/dev/null
+NF_MODE=""
+if mount -t vfat "$FATDEV" /nf_fat 2>/dev/null; then
+ [ -f /nf_fat/netbsd-flash-mode ] && NF_MODE=$(tr -d ' \r\n' < /nf_fat/netbsd-flash-mode 2>/dev/null)
+fi
+
+if [ -n "$NF_MODE" ]; then
+ nf_log "TRIGGERED mode=$NF_MODE"
+ # --- DISARM FIRST (self-heal on any later failure) ---
+ rm -f /nf_fat/config.txt /nf_fat/netbsd-flash-mode 2>/dev/null
+ sync
+ echo "FLASHER-RAN mode=$NF_MODE up=$(cat /proc/uptime 2>/dev/null)" > /nf_fat/flash-evidence.txt 2>/dev/null
+ sync
+ nf_log "disarmed; evidence written"
+
+ # --- stage golden image from ext4 root into RAM ---
+ NF_OK=1
+ if ! mount -t ext4 -o ro "$ROOTDEV" /nf_root 2>/dev/null; then
+ nf_log "FATAL mount root"; echo "FATAL mount-root" >> /nf_fat/flash-evidence.txt; NF_OK=0
+ fi
+ GZ=""
+ for cand in /nf_root/home/paul/netbsd-*-golden.img.gz /nf_root/root/netbsd-*-golden.img.gz; do
+ [ -f "$cand" ] && { GZ="$cand"; break; }
+ done
+ if [ "$NF_OK" = 1 ] && [ -z "$GZ" ]; then
+ nf_log "FATAL image-missing"; echo "FATAL image-missing" >> /nf_fat/flash-evidence.txt; NF_OK=0
+ fi
+ if [ "$NF_OK" = 1 ]; then
+ mount -t tmpfs -o size=550m tmpfs /nf_ram 2>/dev/null
+ if cp "$GZ" /nf_ram/g.gz 2>/dev/null; then
+ nf_log "staged $(wc -c < /nf_ram/g.gz 2>/dev/null) bytes in RAM"
+ else
+ nf_log "FATAL copy-to-RAM"; echo "FATAL copy-RAM" >> /nf_fat/flash-evidence.txt; NF_OK=0
+ fi
+ fi
+ umount /nf_root 2>/dev/null
+ sync
+
+ if [ "$NF_OK" = 1 ] && [ "$NF_MODE" = dryrun ]; then
+ bytes=$(gzip -dc /nf_ram/g.gz 2>/dev/null | wc -c); rc=$?
+ nf_log "DRYRUN bytes=$bytes rc=$rc"
+ echo "DRYRUN-RESULT bytes=$bytes rc=$rc" >> /nf_fat/flash-evidence.txt
+ sync; umount /nf_fat 2>/dev/null
+ nf_log "DRYRUN done; rebooting to Rocky"
+ nf_reboot
+ elif [ "$NF_OK" = 1 ]; then
+ echo "REAL-START up=$(cat /proc/uptime 2>/dev/null)" >> /nf_fat/flash-evidence.txt
+ sync; umount /nf_fat 2>/dev/null
+ nf_log "REAL: writing image onto $DISK"
+ gzip -dc /nf_ram/g.gz 2>/dev/null | dd of="$DISK" bs=4M conv=fsync 2>&1 | tail -2 | while read -r l; do nf_log "dd: $l"; done
+ sync
+ nf_log "REAL flash complete; rebooting into NetBSD"
+ nf_reboot
+ else
+ # a FATAL occurred; config.txt already removed, so reboot -> Rocky
+ sync; umount /nf_fat 2>/dev/null
+ nf_log "aborted; rebooting to Rocky"
+ nf_reboot
+ fi
+else
+ # not triggered: clean up and let the normal boot proceed
+ umount /nf_fat 2>/dev/null
+fi