195 lines
5.7 KiB
Bash
Executable File
195 lines
5.7 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Script to flash the Auracaster System image to an SD card
|
|
# This script must be run with sudo privileges
|
|
|
|
set -e
|
|
|
|
# Configuration
|
|
BUILDROOT_DIR="../buildroot"
|
|
IMAGE_FILE="$BUILDROOT_DIR/output/images/sdcard.img"
|
|
AUTO_YES=false
|
|
|
|
# Parse command line arguments
|
|
while getopts "y" opt; do
|
|
case $opt in
|
|
y)
|
|
AUTO_YES=true
|
|
;;
|
|
\?)
|
|
echo "Invalid option: -$OPTARG" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Check if script is run as root
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
echo "Error: This script must be run as root (sudo)."
|
|
exit 1
|
|
fi
|
|
|
|
# Check if image exists
|
|
if [ ! -f "$IMAGE_FILE" ]; then
|
|
echo "Error: Image file not found at $IMAGE_FILE"
|
|
echo "You need to build the project first."
|
|
exit 1
|
|
fi
|
|
|
|
# Find SD cards (both removable devices and mmcblk devices)
|
|
echo "Looking for SD cards..."
|
|
echo
|
|
|
|
# Get list of potential SD cards (both removable devices and mmcblk devices)
|
|
SD_CARDS=$(lsblk -d -o NAME,SIZE,MODEL,VENDOR,TRAN,RM | grep -v "loop" | grep -E '(1$|mmcblk)' | awk '{print $1}')
|
|
SD_CARD_COUNT=$(echo "$SD_CARDS" | grep -v "^$" | wc -l)
|
|
|
|
if [ "$SD_CARD_COUNT" -eq 0 ]; then
|
|
echo "No SD cards found. Please insert an SD card and try again."
|
|
exit 1
|
|
fi
|
|
|
|
# Display available SD cards
|
|
echo "Available SD cards:"
|
|
echo
|
|
lsblk -d -o NAME,SIZE,MODEL,VENDOR,TRAN,RM | head -n 1
|
|
lsblk -d -o NAME,SIZE,MODEL,VENDOR,TRAN,RM | grep -v "loop" | grep -E '(1$|mmcblk)'
|
|
echo
|
|
|
|
# Safety check - get list of internal disks to avoid (exclude mmcblk devices from this check)
|
|
INTERNAL_DISKS=$(lsblk -d -o NAME,RM | grep -E '0$' | grep -v "mmcblk" | awk '{print $1}')
|
|
|
|
# Select SD card
|
|
DEVICE=""
|
|
if [ "$SD_CARD_COUNT" -eq 1 ]; then
|
|
DEVICE=$(echo "$SD_CARDS" | tr -d '[:space:]')
|
|
echo "Found single SD card: /dev/$DEVICE"
|
|
else
|
|
echo "Multiple SD cards found. Please select which one to use:"
|
|
select DEVICE in $SD_CARDS; do
|
|
if [ -n "$DEVICE" ]; then
|
|
break
|
|
else
|
|
echo "Invalid selection. Please try again."
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Safety check - ensure we're not flashing to an internal disk
|
|
if echo "$INTERNAL_DISKS" | grep -q "$DEVICE"; then
|
|
echo "ERROR: Selected device /dev/$DEVICE appears to be an internal disk!"
|
|
echo "This script will only flash to removable devices or mmcblk devices for safety."
|
|
exit 1
|
|
fi
|
|
|
|
# Validate device exists
|
|
if [[ "$DEVICE" == mmcblk* ]]; then
|
|
DEV_PATH="/dev/$DEVICE"
|
|
else
|
|
DEV_PATH="/dev/$DEVICE"
|
|
fi
|
|
|
|
if [ ! -b "$DEV_PATH" ]; then
|
|
echo "Error: Device $DEV_PATH does not exist or is not a block device."
|
|
exit 1
|
|
fi
|
|
|
|
# Double-check with clear warning
|
|
echo
|
|
echo "You are about to erase ALL DATA on $DEV_PATH and write the Auracaster System image to it."
|
|
echo "This operation cannot be undone."
|
|
echo
|
|
|
|
# Check if pv is available for better progress display
|
|
if command -v pv >/dev/null 2>&1; then
|
|
# Get image size for pv
|
|
IMAGE_SIZE=$(stat -c %s "$IMAGE_FILE")
|
|
|
|
# Show the command that will be executed with pv
|
|
FLASH_COMMAND="pv -s $IMAGE_SIZE \"$IMAGE_FILE\" | dd of=\"$DEV_PATH\" bs=4M conv=fsync oflag=direct"
|
|
echo "The following command will be executed (with progress bar):"
|
|
echo "$FLASH_COMMAND"
|
|
else
|
|
# Fallback to dd with status=progress
|
|
FLASH_COMMAND="dd if=\"$IMAGE_FILE\" of=\"$DEV_PATH\" bs=4M status=progress conv=fsync oflag=direct"
|
|
echo "The following command will be executed:"
|
|
echo "$FLASH_COMMAND"
|
|
echo "For better progress visualization, consider installing 'pv' (Pipe Viewer)."
|
|
fi
|
|
echo
|
|
|
|
if [ "$AUTO_YES" = true ]; then
|
|
CONFIRM="y"
|
|
echo "Auto-confirming with -y flag"
|
|
else
|
|
read -p "Are you ABSOLUTELY SURE you want to continue? (y/n): " CONFIRM
|
|
|
|
if [ "$CONFIRM" != "y" ]; then
|
|
echo "Operation cancelled."
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
# Unmount any partitions on the device, reporting failures
|
|
echo "Unmounting any mounted partitions on $DEV_PATH..."
|
|
UNMOUNT_FAILED=0
|
|
if [[ "$DEVICE" == mmcblk* ]]; then
|
|
for partition in $(lsblk -n -o NAME | grep "^$DEVICE"); do
|
|
if [ "$partition" != "$DEVICE" ]; then
|
|
if mount | grep -q "/dev/$partition"; then
|
|
umount "/dev/$partition" 2>/dev/null || {
|
|
echo "Warning: Failed to unmount /dev/$partition" >&2
|
|
UNMOUNT_FAILED=1
|
|
}
|
|
fi
|
|
fi
|
|
done
|
|
else
|
|
for partition in $(lsblk -n -o NAME /dev/$DEVICE | grep -v "^$DEVICE$"); do
|
|
if mount | grep -q "/dev/$partition"; then
|
|
umount "/dev/$partition" 2>/dev/null || {
|
|
echo "Warning: Failed to unmount /dev/$partition" >&2
|
|
UNMOUNT_FAILED=1
|
|
}
|
|
fi
|
|
done
|
|
fi
|
|
if [ $UNMOUNT_FAILED -eq 1 ]; then
|
|
echo "Some partitions could not be unmounted. Please close any open files or applications using the SD card and try again." >&2
|
|
exit 1
|
|
fi
|
|
# Check for open files on the device
|
|
if lsof | grep -q "/dev/$DEVICE"; then
|
|
echo "Warning: Open files detected on /dev/$DEVICE. Please close them before flashing to avoid corruption." >&2
|
|
lsof | grep "/dev/$DEVICE"
|
|
exit 1
|
|
fi
|
|
|
|
# Flash the image
|
|
echo "Flashing image to $DEV_PATH..."
|
|
echo "This may take several minutes. Please wait..."
|
|
echo
|
|
|
|
# Execute the flashing command
|
|
eval "$FLASH_COMMAND"
|
|
|
|
# Sync to ensure all writes are complete
|
|
sync
|
|
|
|
# Remind user to eject the card safely
|
|
echo "Flash complete!"
|
|
echo
|
|
# Re-read the partition table to ensure the system recognizes the new layout
|
|
echo "Running partprobe to re-read the partition table on $DEV_PATH..."
|
|
if partprobe "$DEV_PATH"; then
|
|
echo "Partition table re-read successfully. The SD card is ready for use."
|
|
else
|
|
echo "Warning: partprobe failed. If partitions do not show up, try reinserting the SD card."
|
|
fi
|
|
echo
|
|
# Instructions for next steps
|
|
echo "1. Insert the SD card into your Raspberry Pi 3"
|
|
echo "2. Power on the device"
|
|
echo
|
|
|
|
exit 0 |