-
Notifications
You must be signed in to change notification settings - Fork 15
/
flash-it.sh
executable file
·342 lines (302 loc) · 10.8 KB
/
flash-it.sh
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
#!/bin/bash
VERSION="0.4.0"
BRANCH=master
CUSTOM=""
ROOTFS_PINEPHONE_1_0_JOB=pinephone-1.0-rootfs
ROOTFS_PINEPHONE_1_1_JOB=pinephone-1.1-rootfs
ROOTFS_PINETAB_JOB=pinetab-rootfs
ROOTFS_PINETABDEV_JOB=pinetab-rootfs
ROOTFS_PINEPHONEPRO_JOB=pinephonepro-rootfs
ROOTFS_PINETAB2_JOB=pinetab2-rootfs
ROOTFS_PINEPHONE_1_0_DIR=pinephone-1.0
ROOTFS_PINEPHONE_1_1_DIR=pinephone-1.1
ROOTFS_PINETAB_DIR=pinetab
ROOTFS_PINETABDEV_DIR=pinetab
ROOTFS_PINEPHONEPRO_DIR=pinephonepro
ROOTFS_PINETAB2_DIR=pinetab2
UBOOT_PINEPHONE_1_0_FILE=boot.pinephone10.scr
UBOOT_PINEPHONE_1_1_FILE=boot.pinephone11.scr
UBOOT_PINETAB_FILE=boot.pinetab.scr
UBOOT_PINETABDEV_FILE=boot.pinetabdev.scr
UBOOT_PINEPHONEPRO_FILE=boot.pinephonepro.scr
UBOOT_PINETAB2_FILE=boot.pinetab2.scr
MOUNT_ROOT=./root
MOUNT_BOOT=./boot
# Parse arguments
# https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash
POSITIONAL=()
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-b|--branch)
BRANCH="$2"
shift
shift
;;
-h|--help)
echo "Sailfish OS flashing script for Pine64 devices"
echo ""
printf '%s\n' \
"This script will download the latest Sailfish OS image for the Pine" \
"Phone, Pine Phone dev kit, or Pine Tab. It requires that you have a" \
"micro SD card inserted into the computer." \
"" \
"usage: flash-it.sh [-b BRANCH]" \
"" \
"Options:" \
"" \
" -c, --custom Install from custom dir. Just put you rootfs.tar.bz2" \
" and u-boot-sunxi-with-spl.bin into dir and system will "\
" istalled from it" \
" -b, --branch BRANCH Download images from a specific Git branch." \
" -h, --help Print this help and exit." \
"" \
"This command requires: parted, sudo, wget, tar, unzip, lsblk," \
"mkfs.ext4." \
""\
"Some distros do not have parted on the PATH. If necessary, add" \
"parted to the PATH before running the script."
exit 0
shift
;;
-c|--custom)
CUSTOM="$2"
shift
shift
;;
*) # unknown argument
POSITIONAL+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters
# Helper functions
# Error out if the given command is not found on the PATH.
function check_dependency {
dependency=$1
command -v $dependency >/dev/null 2>&1 || {
echo >&2 "${dependency} not found. Please make sure it is installed and on your PATH."; exit 1;
}
}
# Add sbin to the PATH to check for commands available to sudo
function check_sudo_dependency {
dependency=$1
local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin
check_dependency $dependency
}
# Determine if wget supports the --show-progress option (introduced in
# 1.16). If so, make use of that instead of spewing out redirects and
# loads of info into the terminal.
function wget_cmd {
wget --show-progress > /dev/null 2>&1
status=$?
# Exit code 2 means command parsing error (i.e. option does not
# exist).
if [ "$status" == "2" ]; then
echo "wget -O"
else
echo "wget -q --show-progress -O"
fi
}
# Check dependencies
check_dependency "sudo"
check_dependency "wget"
check_dependency "tar"
check_dependency "unzip"
check_dependency "lsblk"
check_dependency "jq"
check_sudo_dependency "parted"
check_sudo_dependency "mkfs.ext4"
check_sudo_dependency "losetup"
check_sudo_dependency "sfdisk"
# If use custom dir check it
if [ "$CUSTOM" != "" ]; then
if ! [ -d "$CUSTOM" ]; then
echo -e "\e[1m\e[97m!!! Directory ${CUSTOM} not exist !!!\e[0m"
exit 2;
fi
if ! [ -f "$CUSTOM/rootfs.tar.bz2" ]; then
echo -e "\e[1m\e[97m!!! rootfs ${CUSTOM}/rootfs.tar.bz2 not found !!!\e[0m"
exit 2;
fi
if ! [ -f "$CUSTOM/boot.scr" ]; then
echo -e "\e[1m\e[97m!!! uboot config ${CUSTOM}/boot.scr not found !!!\e[0m"
exit 2;
fi
else
# Different branch for some reason?
if [ "${BRANCH}" != "master" ]; then
echo -e "\e[1m\e[97m!!! Will flash image from ${BRANCH} branch !!!\e[0m"
fi
# Header
echo -e "\e[1m\e[91mSailfish OS Pine64 device flasher V$VERSION\e[0m"
echo "========================================"
echo ""
echo "NOTE: Before continuing installation, please ensure you have TowBoot installed on your device"
echo "See https://tow-boot.org/devices/index.html for guidance on installation"
echo "This script has been tested with Towboot installed on the Pinephone EMMC and PinephonePro SPI"
echo ""
# Image selection
echo -e "\e[1mWhich image do you want to flash?\e[0m"
select OPTION in "PinePhone 1.0 (Development) device" "PinePhone 1.1 (Brave Heart) or 1.2 (Community Editions) device" "PineTab device" "PineTab Dev device" "Pinephone Pro" "Pinetab 2"; do
case $OPTION in
"PinePhone 1.0 (Development) device" ) ROOTFS_JOB=$ROOTFS_PINEPHONE_1_0_JOB; ROOTFS_DIR=$ROOTFS_PINEPHONE_1_0_DIR; UBOOT_FILE=$UBOOT_PINEPHONE_1_0_FILE; break;;
"PinePhone 1.1 (Brave Heart) or 1.2 (Community Editions) device" ) ROOTFS_JOB=$ROOTFS_PINEPHONE_1_1_JOB; ROOTFS_DIR=$ROOTFS_PINEPHONE_1_1_DIR; UBOOT_FILE=$UBOOT_PINEPHONE_1_1_FILE; break;;
"PineTab device" ) ROOTFS_JOB=$ROOTFS_PINETAB_JOB; ROOTFS_DIR=$ROOTFS_PINETAB_DIR; UBOOT_FILE=$UBOOT_PINETAB_FILE; break;;
"PineTab Dev device" ) ROOTFS_JOB=$ROOTFS_PINETABDEV_JOB; ROOTFS_DIR=$ROOTFS_PINETABDEV_DIR; UBOOT_FILE=$UBOOT_PINETABDEV_FILE; break;;
"Pinephone Pro" ) ROOTFS_JOB=$ROOTFS_PINEPHONEPRO_JOB; ROOTFS_DIR=$ROOTFS_PINEPHONEPRO_DIR; UBOOT_FILE=$UBOOT_PINEPHONEPRO_FILE; break;;
"Pinetab 2" ) ROOTFS_JOB=$ROOTFS_PINETAB2_JOB; ROOTFS_DIR=$ROOTFS_PINETAB2_DIR; UBOOT_FILE=$UBOOT_PINETAB2_FILE; break;;
esac
done
# Downloading images
echo -e "\e[1mDownloading images...\e[0m"
WGET=$(wget_cmd)
ROOTFS_DOWNLOAD="https://gitlab.com/sailfishos-porters-ci/dont_be_evil-ci/-/jobs/artifacts/$BRANCH/download?job=$ROOTFS_JOB"
echo $ROOTFS_DOWNLOAD
if [ -f "${ROOTFS_JOB}.zip" ]; then
read -p "${ROOTFS_JOB}.zip exists. Do you want to keep it? " yn
case $yn in
[Nn]* ) rm "${ROOTFS_JOB}.zip";
esac
fi
if [ ! -f "${ROOTFS_JOB}.zip" ]; then
$WGET "${ROOTFS_JOB}.zip" "${ROOTFS_DOWNLOAD}" || {
echo >&2 "Root filesystem image download failed. Aborting."
exit 2
}
fi
fi
# Select flash target
echo -e "\e[1mWhich SD card do you want to flash?\e[0m"
lsblk
echo "raw"
read -p "Device node (/dev/sdX): " DEVICE_NODE
echo "Flashing image to: $DEVICE_NODE"
echo "WARNING: All data will be erased! You have been warned!"
echo "Some commands require root permissions, you might be asked to enter your sudo password."
#create loop file for raw.img
if [ $DEVICE_NODE == "raw" ]; then
sudo dd if=/dev/zero of=${ROOTFS_JOB}.img bs=1 count=0 seek=16G
DEVICE_NODE="./${ROOTFS_JOB}.img"
fi
# Creating EXT4 file system
echo -e "\e[1mCreating EXT4 file system...\e[0m"
for PARTITION in $(ls ${DEVICE_NODE}*)
do
echo "Unmounting $PARTITION"
sudo umount $PARTITION
done
#Delete all partitions
sudo sfdisk --delete $DEVICE_NODE
#Create partitions
sudo parted $DEVICE_NODE mklabel msdos --script
sudo parted $DEVICE_NODE mkpart primary ext4 32MB 256MB --script
sudo parted $DEVICE_NODE mkpart primary ext4 256MB 8192MB --script
#Create a 3rd partition for home. Community encryption will format it.
sudo parted $DEVICE_NODE mkpart primary ext4 8192MB 100% --script
if [ $DEVICE_NODE == "./${ROOTFS_JOB}.img" ]; then
echo "Prepare loop file"
sudo losetup -D
sudo losetup -Pf ${ROOTFS_JOB}.img
LOOP_NODE=$(ls /dev/loop?p1 | cut -c10-10)
DEVICE_NODE="/dev/loop$LOOP_NODE"
fi
# use p1, p2 extentions instead of 1, 2 when using sd drives
if [ $(echo $DEVICE_NODE | grep mmcblk || echo $DEVICE_NODE | grep loop) ]; then
BOOTPART="${DEVICE_NODE}p1"
ROOTPART="${DEVICE_NODE}p2"
HOMEPART="${DEVICE_NODE}p3"
else
BOOTPART="${DEVICE_NODE}1"
ROOTPART="${DEVICE_NODE}2"
HOMEPART="${DEVICE_NODE}3"
fi
sudo mkfs.ext4 -F -L boot $BOOTPART # 1st partition = boot
sudo mkfs.ext4 -F -L root $ROOTPART # 2nd partition = root
sudo mkfs.ext4 -F -L home $HOMEPART # 3rd partition = home
# Flashing rootFS
echo -e "\e[1mFlashing rootFS...\e[0m"
mkdir "$MOUNT_ROOT"
if [ "$CUSTOM" != "" ]; then
TEMP="${CUSTOM}/rootfs.tar.bz2"
else
unzip "${ROOTFS_JOB}.zip"
TEMP=$(ls $ROOTFS_DIR/*/*.tar.bz2)
echo "$TEMP"
fi
sudo mount $ROOTPART "$MOUNT_ROOT" # Mount root partition
sudo tar -xpf "$TEMP" -C "$MOUNT_ROOT"
# TODO: pinephone 1.0: tar (child): lbzip2: Cannot exec: No such file or directory
sync
# Copying kernel to boot partition
echo -e "\e[1mCopying kernel to boot partition...\e[0m"
mkdir "$MOUNT_BOOT"
sudo mount $BOOTPART "$MOUNT_BOOT" # Mount boot partition
echo "Boot partition mount: $MOUNT_BOOT"
sudo sh -c "cp -r $MOUNT_ROOT/boot/* $MOUNT_BOOT"
#Only copy boot script if not Pinetab2
if [ "$OPTION" != "Pinetab 2" ]; then
echo $(ls $MOUNT_BOOT)
echo -e "\e[1mCopying UBoot script to boot partition...\e[0m"
if [ "$CUSTOM" != "" ]; then
sudo sh -c "cp '${CUSTOM}/boot.scr' '$MOUNT_BOOT/boot.scr'"
else
sudo sh -c "cp '$MOUNT_BOOT/$UBOOT_FILE' '$MOUNT_BOOT/boot.scr'"
fi
sync
else
#Flash the uboot supplied with the release
if [ -f "$MOUNT_BOOT/u-boot-rockchip.bin" ]; then
read -p "Do you want to flash uboot? " yn
case $yn in
[Yy]* ) sudo dd if="$MOUNT_BOOT/u-boot-rockchip.bin" of="${DEVICE_NODE}" oflag=direct seek=64
esac
fi
#Rewrite the boot config
PARTUUID=$(sudo blkid $ROOTPART -s PARTUUID -o value)
sed "s/ROOTUUID/$PARTUUID/" $MOUNT_BOOT/extlinux/extlinux.conf.in | sudo tee $MOUNT_BOOT/extlinux/extlinux.conf > /dev/null;
fi
#Rewrite the home config
read -p "Are you installing to an SD card? " yn
if [ "$OPTION" == "Pinephone Pro" ]; then
DEVICESD="mmcblk1"
DEVICEEMMC="mmcblk2"
elif [ "$OPTION" == "Pinetab 2" ]; then
DEVICESD="mmcblk0"
DEVICEEMMC="mmcblk1"
else
DEVICESD="mmcblk0"
DEVICEEMMC="mmcblk2"
fi
case $yn in
[Yy]* ) sudo sed -i "s/$DEVICEEMMC/$DEVICESD/" $MOUNT_ROOT/etc/sailfish-device-encryption-community/devices.ini;
esac
read -p "Clear root password? " yn
case $yn in
[Yy]* ) sudo sed -i '0,/:!:/{s/:!:/::/}' $MOUNT_ROOT/etc/shadow;
esac
# Clean up files
echo -e "\e[1mCleaning up!\e[0m"
for PARTITION in $(ls ${DEVICE_NODE}*)
do
echo "Unmounting $PARTITION"
sudo umount $PARTITION
done
sudo losetup -D
if [ "$CUSTOM" == "" ]; then
read -p "Do you want to keep ${ROOTFS_JOB}.zip? " yn
case $yn in
[Yy]* ) CUSTOM=true; rm -r "$ROOTFS_DIR";
esac
fi
if [ "$CUSTOM" == "" ]; then
rm "${ROOTFS_JOB}.zip"
rm -r "$ROOTFS_DIR"
fi
sudo rm -rf "$MOUNT_ROOT"
sudo rm -rf "$MOUNT_BOOT"
# Done :)
echo -e "\e[1mFlashing $DEVICE_NODE OK!\e[0m"
echo "You may now remove the SD card and insert it in your Pine64 device!"