From c7da7bf4f7ee824ac55cf1bb2ea55e3652cf2347 Mon Sep 17 00:00:00 2001 From: w1n5t0n Date: Thu, 16 Apr 2026 00:52:39 +0900 Subject: [PATCH] Improve UF2 bootloader detection --- .beads/interactions.jsonl | 2 + scripts/firmware-common.sh | 93 ++++++++++++++++++++++++++++++++++++++ scripts/flash-firmware.sh | 6 +-- 3 files changed, 98 insertions(+), 3 deletions(-) diff --git a/.beads/interactions.jsonl b/.beads/interactions.jsonl index a4c5b17..7c0783a 100644 --- a/.beads/interactions.jsonl +++ b/.beads/interactions.jsonl @@ -6,3 +6,5 @@ {"id":"int-fd7690f3","kind":"field_change","created_at":"2026-04-15T15:44:48.605669713Z","actor":"w1n5t0n","issue_id":"meml-zbbs","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Prompt variant selection now uses /dev/tty so interactive shells are detected correctly"}} {"id":"int-672df751","kind":"field_change","created_at":"2026-04-15T15:45:23.772401653Z","actor":"w1n5t0n","issue_id":"meml-oq1q","extra":{"field":"status","new_value":"in_progress","old_value":"open"}} {"id":"int-d96e5dc8","kind":"field_change","created_at":"2026-04-15T15:46:03.317834458Z","actor":"w1n5t0n","issue_id":"meml-oq1q","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Preserved canonical firmware variant capitalization in prompts and docs"}} +{"id":"int-24228f3d","kind":"field_change","created_at":"2026-04-15T15:51:08.349410622Z","actor":"w1n5t0n","issue_id":"meml-9hla","extra":{"field":"status","new_value":"in_progress","old_value":"open"}} +{"id":"int-ea04e4b0","kind":"field_change","created_at":"2026-04-15T15:52:36.360908976Z","actor":"w1n5t0n","issue_id":"meml-9hla","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Expanded UF2 detection to find labeled block devices and resolve mounted boot volumes reliably"}} diff --git a/scripts/firmware-common.sh b/scripts/firmware-common.sh index 01e8ca3..099676f 100755 --- a/scripts/firmware-common.sh +++ b/scripts/firmware-common.sh @@ -11,6 +11,7 @@ UF2_PATH_DEFAULT="${MEMLNAUT_FIRMWARE_UF2:-$BUILD_DIR/${SKETCH_NAME}.uf2}" FQBN="${MEMLNAUT_FIRMWARE_FQBN:-rp2040:rp2040:solderparty_rp2350_stamp_xl:opt=Optimize3}" CXX20_BUILD_PROPERTY="${MEMLNAUT_FIRMWARE_CXX20_PROPERTY:-compiler.cpp.extra_flags=-std=gnu++20}" +UF2_LABEL_CANDIDATES=("${MEMLNAUT_FIRMWARE_UF2_LABEL_1:-RP2350}" "${MEMLNAUT_FIRMWARE_UF2_LABEL_2:-RPI-RP2}" "${MEMLNAUT_FIRMWARE_UF2_LABEL_3:-RP2040}") FIRMWARE_VARIANTS=() ACTIVE_FIRMWARE_VARIANT="" @@ -82,6 +83,98 @@ find_boot_mount() { return 1 } +is_known_uf2_label() { + local label="$1" + local candidate + + for candidate in "${UF2_LABEL_CANDIDATES[@]}"; do + if [[ -n "$candidate" && "$label" == "$candidate" ]]; then + return 0 + fi + done + + return 1 +} + +find_boot_block_device() { + local line + local dev_path="" + local dev_fstype="" + local dev_label="" + local dev_mountpoints="" + + while IFS= read -r line; do + dev_path="" + dev_fstype="" + dev_label="" + dev_mountpoints="" + eval "$( + sed -E \ + -e 's/(^|[[:space:]])PATH=/\1dev_path=/' \ + -e 's/(^|[[:space:]])FSTYPE=/\1dev_fstype=/' \ + -e 's/(^|[[:space:]])LABEL=/\1dev_label=/' \ + -e 's/(^|[[:space:]])MOUNTPOINTS=/\1dev_mountpoints=/' \ + <<<"$line" + )" + + [[ -n "$dev_path" ]] || continue + [[ "$dev_fstype" == "vfat" || "$dev_fstype" == "msdos" || "$dev_fstype" == "fat" ]] || continue + is_known_uf2_label "$dev_label" || continue + + printf '%s\n' "$dev_path" + return 0 + done < <(lsblk -P -o PATH,FSTYPE,LABEL,MOUNTPOINTS 2>/dev/null || true) + + return 1 +} + +mount_boot_block_device() { + local device_path="$1" + local mount_output="" + local mounted_path="" + + if command -v udisksctl >/dev/null 2>&1; then + mount_output="$(udisksctl mount -b "$device_path" 2>/dev/null || true)" + mounted_path="$(sed -nE "s#.* at (.+)\.?#\1#p" <<<"$mount_output" | tail -n 1)" + if [[ -n "$mounted_path" && -d "$mounted_path" ]]; then + printf '%s\n' "$mounted_path" + return 0 + fi + fi + + return 1 +} + +ensure_boot_mount() { + local mountpoint="" + local device_path="" + + mountpoint="$(find_boot_mount || true)" + if [[ -n "$mountpoint" ]]; then + printf '%s\n' "$mountpoint" + return 0 + fi + + device_path="$(find_boot_block_device || true)" + if [[ -z "$device_path" ]]; then + return 1 + fi + + mountpoint="$(mount_boot_block_device "$device_path" || true)" + if [[ -n "$mountpoint" ]]; then + printf '%s\n' "$mountpoint" + return 0 + fi + + mountpoint="$(find_boot_mount || true)" + if [[ -n "$mountpoint" ]]; then + printf '%s\n' "$mountpoint" + return 0 + fi + + return 1 +} + assert_boot_mount() { local mountpoint="$1" diff --git a/scripts/flash-firmware.sh b/scripts/flash-firmware.sh index b614417..5289c2b 100755 --- a/scripts/flash-firmware.sh +++ b/scripts/flash-firmware.sh @@ -54,12 +54,12 @@ if [[ ! -f "$uf2_path" ]]; then fi if [[ -z "$mountpoint" ]]; then - mountpoint="$(find_boot_mount || true)" + mountpoint="$(ensure_boot_mount || true)" fi if [[ -z "$mountpoint" ]]; then - echo "error: could not find a mounted UF2 bootloader volume" >&2 - echo "put the board in bootloader mode or pass the mountpoint explicitly" >&2 + echo "error: could not find or mount a UF2 bootloader volume" >&2 + echo "put the board in bootloader mode, or pass the mountpoint explicitly" >&2 exit 1 fi