-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathwrite2emmc.sh
More file actions
executable file
·211 lines (180 loc) · 6.34 KB
/
write2emmc.sh
File metadata and controls
executable file
·211 lines (180 loc) · 6.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#!/bin/bash
set -e
IMAGE_DIR="images"
# Check if the script is running as root
if [ "$(id -u)" -ne 0 ]; then
# Not running as root, prompt for root password and rerun the script
echo "This script needs to run with root privileges."
sudo "$0" "$@"
exit $?
fi
# Check if whiptail is installed
if ! command -v whiptail &> /dev/null; then
echo "whiptail is not installed."
# Check if apt is available
if command -v apt &> /dev/null; then
echo "Attempting to install whiptail using apt..."
apt update && apt install -y whiptail
# Verify if whiptail installed successfully
if command -v whiptail &> /dev/null; then
echo "whiptail installed successfully."
else
echo "Failed to install whiptail."
exit 1
fi
else
echo "apt is not available on this system. Cannot install whiptail automatically."
exit 1
fi
fi
# Check if a command-line argument was provided
if [ $# -gt 0 ]; then
# Check if the argument ends with .zip
if [[ "$1" =~ \.zip$ ]]; then
# Check if $IMAGE_DIR directory exists
if [ -d "$IMAGE_DIR" ]; then
IMAGE_FILE="$1"
IMAGE_FILE=${IMAGE_FILE#$IMAGE_DIR/}
# Check if the file exists in $IMAGE_DIR directory
if [ -f "$IMAGE_DIR/$IMAGE_FILE" ]; then
IMAGE_FILE="$IMAGE_DIR/$IMAGE_FILE"
fi
else
echo "Directory '$IMAGE_DIR' does not exist"
fi
else
echo "Argument must be a filename ending in .zip"
fi
else
# No argument provided, use whiptail menu
if [ -d "$IMAGE_DIR" ]; then
# Create array of .zip files
mapfile -t img_array < <(ls $IMAGE_DIR/*.zip 2>/dev/null)
# Check if array has any elements
if [ ${#img_array[@]} -gt 0 ]; then
# Build whiptail menu options
MENU_OPTIONS=()
for i in "${!img_array[@]}"; do
MENU_OPTIONS+=("$i" "${img_array[$i]}")
done
# Display menu and store selection
CHOICE=$(whiptail --title "Select Image File" \
--menu "Choose an .zip file:" \
15 80 6 \
"${MENU_OPTIONS[@]}" \
3>&1 1>&2 2>&3)
# Check if user made a selection
if [ $? -eq 0 ]; then
IMAGE_FILE="${img_array[$CHOICE]}"
echo "Selected image file: $IMAGE_FILE"
else
echo "No file selected"
fi
else
echo "No .zip files found in $IMAGE_DIR directory"
fi
else
echo "Directory '$IMAGE_DIR' does not exist"
fi
fi
# Check if the image file exists
if [ ! -f "$IMAGE_FILE" ]; then
echo "Image file not found: $IMAGE_FILE"
echo "write2sd.sh"
echo "write2sd.sh [image file]"
exit 1
fi
# Check if the image file is mounted
if mount | grep -q "$IMAGE_FILE"; then
echo "The image file is mounted! - Exiting."
exit 1
fi
while true; do
# Get the list of removable devices with size > 0 and store it in a variable
DEVICE_LIST=$(lsblk -d -n -p -o NAME,SIZE,RM | awk '$3=="1" && $2 != "0B" {print $1, "("$2")"}')
DEVICE_LIST_ARRAY=($DEVICE_LIST "rescan" "(rescan devices)")
# Use whiptail to show a menu to select the SD card, including a rescan option
SD_CARD_DEVICE=$(whiptail --title "Select SD Card" --menu "Choose the SD Card to use or Rescan" 20 60 10 "${DEVICE_LIST_ARRAY[@]}" 3>&2 2>&1 1>&3)
# Check if a device was selected
if [ -z "$SD_CARD_DEVICE" ]; then
echo "No device selected."
exit 1
elif [ "$SD_CARD_DEVICE" = "rescan" ]; then
continue # Go back to the start of the loop to rescan
else
echo "Selected device: $SD_CARD_DEVICE"
break # Exit loop if a device other than rescan is selected
fi
done
# Confirm before proceeding
if ! whiptail --yesno "Are you sure you want to write to $SD_CARD_DEVICE?" 10 60; then
echo "Operation cancelled."
exit 1
fi
# Check if the SD card is mounted before unmounting
if mount | grep -q "^$SD_CARD_DEVICE"; then
echo "Unmounting $SD_CARD_DEVICE..."
umount ${SD_CARD_DEVICE}* 2> /dev/null
# Check again to ensure unmount succeeded
if mount | grep -q "^$SD_CARD_DEVICE"; then
echo "Error: Failed to unmount $SD_CARD_DEVICE partitions. Please ensure no partitions are in use."
exit 1
fi
fi
set -e
# Check SD card size
IMAGE_SIZE=$(stat -c %s "$IMAGE_FILE")
SD_SIZE=$(blockdev --getsize64 "$SD_CARD_DEVICE")
if [ "$IMAGE_SIZE" -gt "$SD_SIZE" ]; then
echo "Error: SD card ($SD_SIZE bytes) is smaller than image ($IMAGE_SIZE bytes)."
exit 1
fi
# Format the SD card to FAT32
echo "Formatting $SD_CARD_DEVICE to FAT32..."
mkfs.vfat -I -F 32 "$SD_CARD_DEVICE"
if [ $? -ne 0 ]; then
echo "Error: Failed to format $SD_CARD_DEVICE."
exit 1
fi
# Define a cleanup function
cleanup() {
# Check if MOUNT_POINT is a mount point and unmount it if so
if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
umount "$MOUNT_POINT"
fi
# Remove the directory if it still exists
if [ -d "$MOUNT_POINT" ]; then
rmdir "$MOUNT_POINT"
fi
}
# Set the trap to call cleanup on script exit
trap cleanup EXIT
# Create a temporary mount point
MOUNT_POINT=$(mktemp -d)
echo "Mounting $SD_CARD_DEVICE to $MOUNT_POINT..."
mount "$SD_CARD_DEVICE" "$MOUNT_POINT"
if [ $? -ne 0 ]; then
echo "Error: Failed to mount $SD_CARD_DEVICE."
rmdir "$MOUNT_POINT"
exit 1
fi
# Unzip the image file onto the SD card with progress
echo "Unzipping $IMAGE_FILE to $SD_CARD_DEVICE (mounted at $MOUNT_POINT)..."
unzip -o "$IMAGE_FILE" -d "$MOUNT_POINT"
if [ $? -ne 0 ]; then
echo "Error: Failed to unzip $IMAGE_FILE."
umount "$MOUNT_POINT"
rmdir "$MOUNT_POINT"
exit 1
fi
# Sync to ensure all data is written
echo "Syncing data..."
sync
# Unmount and clean up
echo "Unmounting $SD_CARD_DEVICE..."
umount "$MOUNT_POINT"
rmdir "$MOUNT_POINT"
echo "Done! SD card is formatted and $IMAGE_FILE has been extracted."
echo "Ejecting the SD card..."
eject "$SD_CARD_DEVICE"
whiptail --title "SD Card Update Instructions" --msgbox "1. Insert the SD card into the device\n2. Switch on\n3. Wait until all data is copied\n4. Switch off, Remove SD card. Switch on." 12 50