-
Notifications
You must be signed in to change notification settings - Fork 7
/
update.sh
259 lines (205 loc) · 5.23 KB
/
update.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
#!/bin/bash
if [ "$#" -ne "3" ]; then
echo -e "Usage:\n\t$0 <dtb> <kernel> <rootfs>"
exit 1
fi
if [ ! -f "$1" ]; then
echo "$1 doesn't exist!"
exit 1
fi
if [ ! -f "$2" ]; then
echo "$2 doesn't exist!"
exit 1
fi
if [ ! -f "$3" ]; then
echo "$3 doesn't exist!"
exit 1
fi
DTB_FILE="$1"
KERNEL_FILE="$2"
IMAGE="$3"
IMAGE="$(readlink -f "$IMAGE")"
case "$IMAGE" in
'')
echo "Image file not found." >&2
exit 1
;;
/tmp/*) ;;
*)
echo "Image not in /tmp, copying..."
cp -f "$IMAGE" /tmp/$ROOTFS_FILENAME
IMAGE=/tmp/$ROOTFS_FILENAME
;;
esac
if [ ! -s $DTB_FILE ]; then
echo "$DTB_FILE is empty! Cannot proceed"
exit 1
fi
if [ ! -s $KERNEL_FILE ]; then
echo "$KERNEL_FILE is empty! Cannot proceed"
exit 1
fi
RAM_ROOT=/tmp/root
OLD_ROOT=/old-root
ROOTFS_FILENAME=rootfs.squashfs
LUMI_FILENAME=sysupgrade.tgz
kill_remaining() { # [ <signal> [ <loop> ] ]
local loop_limit=10
local sig="${1:-TERM}"
local loop="${2:-0}"
local run=true
local stat
local proc_ppid=$(cut -d' ' -f4 /proc/$$/stat)
echo -n "Sending $sig to remaining processes ... "
while $run; do
run=false
for stat in /proc/[0-9]*/stat; do
[ -f "$stat" ] || continue
echo $stat
local pid name state ppid rest
read pid name state ppid rest < $stat
name="${name#(}"; name="${name%)}"
[ "$name" = "getty" ] && continue
echo "my pid $pid $name $proc_ppid $$"
# Skip PID1, our parent, ourself and our children
[ $pid -ne 1 -a $pid -ne $proc_ppid -a $pid -ne $$ -a $ppid -ne $$ ] || continue
local cmdline=$(cat /proc/$pid/cmdline)
# read cmdline < /proc/$pid/cmdline
echo "cmdline $cmdline"
# Skip kernel threads
[ -n "$cmdline" ] || continue
echo -n "$name "
kill -$sig $pid 2>/dev/null
[ $loop -eq 1 ] && run=true
done
let loop_limit--
[ $loop_limit -eq 0 ] && {
echo
echo "Failed to kill all processes."
return 0
#exit 1
}
done
echo
}
supivot() { # <new_root> <old_root>
echo "Replacing root with new root in tmpfs..."
mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp &&
mount -t proc proc $1/proc
pivot_root $1 $1$2 || {
return 1
}
/bin/mount -o noatime,move $2/sys /sys
/bin/mount -o noatime,move $2/dev /dev
/bin/mount -o noatime,move $2/tmp /tmp
return 0
}
switch_to_ramfs() {
echo "Switching to ramfs..."
mkdir -p $RAM_ROOT
$(umount $RAM_ROOT 2>/dev/null) || true
mount -t tmpfs tmpfs $RAM_ROOT
mkdir -p $RAM_ROOT/etc
mkdir -p $RAM_ROOT/bin
mkdir -p $RAM_ROOT/mnt
mkdir -p $RAM_ROOT/sbin
mkdir -p $RAM_ROOT/lib
# executables
cd $RAM_ROOT
cp /bin/busybox $RAM_ROOT/bin/
cp /bin/sh $RAM_ROOT/bin/
cp /bin/sync.coreutils $RAM_ROOT/bin/
cp /bin/sync $RAM_ROOT/bin/
cp /usr/sbin/ubi* $RAM_ROOT/bin/
cp /usr/bin/killall $RAM_ROOT/bin/
cp /sbin/init $RAM_ROOT/sbin/
cp /sbin/telinit $RAM_ROOT/sbin
cp /sbin/getty $RAM_ROOT/sbin/
cp /bin/start_getty $RAM_ROOT/bin/
# libraries
cp /lib/libm.so.6 $RAM_ROOT/lib/
cp /lib/libc.so.6 $RAM_ROOT/lib/
cp /lib/ld-linux-armhf.so.3 $RAM_ROOT/lib/
cp /lib/libtinfo.so.5 $RAM_ROOT/lib/ # sh
cp /lib/libdl.so.2 $RAM_ROOT/lib/ # sh
# inittab
echo > $RAM_ROOT/etc/inittab
# busybox symlinks
cd $RAM_ROOT/bin &&
ln -sf busybox ln &&
ln -sf busybox cp &&
ln -sf busybox ls &&
ln -sf busybox mkdir &&
ln -sf busybox mount &&
ln -sf busybox umount &&
ln -sf busybox reboot &&
ln -sf busybox cat &&
ln -sf busybox wc &&
ln -sf busybox chmod &&
ln -sf busybox sleep &&
ln -sf busybox tar
umount /proc || true
umount /run || true
umount /var/volatile || true
sync
supivot $RAM_ROOT $OLD_ROOT || {
echo "Failed to switch over to ramfs. Please reboot."
exit 1
}
/bin/mount -o remount,ro $OLD_ROOT
}
write_image() {
cd /
rootfs_length=$( (cat $1 | wc -c) 2>/dev/null)
cat > /reS <<- EOF
#!/bin/sh
set -x
cd /
sync
telinit u
killall getty
echo 'Unmounting old root...'
umount -f $OLD_ROOT
echo 'Writing rootfs...'
ubirmvol /dev/ubi0 -N rootfs
ubimkvol /dev/ubi0 -Nrootfs -s $rootfs_length
ubimkvol /dev/ubi0 -Nrootfs_data -m
sync
ubiupdatevol /dev/ubi0_0 $1
sync
echo "Copying Lumi backup..."
mount -t ubifs ubi0:rootfs_data /mnt
cp /tmp/$LUMI_FILENAME /mnt/
sync
umount /mnt
echo 'Flashing complete!'
reboot -f
EOF
chmod +x /reS
exec /bin/sh /reS >/dev/ttymxc0 2>&1
}
echo "echo 0 -->> dev/watchdog"
killall key_rgb || true
sleep 1
echo 0 > /dev/watchdog
echo -n V > /dev/watchdog
echo "Writing DTB..."
flash_erase /dev/mtd2 0 0
nandwrite -p /dev/mtd2 -p $DTB_FILE
echo "Writing Kernel..."
flash_erase /dev/mtd1 0 0
nandwrite -p /dev/mtd1 -p $KERNEL_FILE
echo "Backing up Lumi..."
mkdir -p /tmp/lumibackup/etc/lumi/
mkdir -p /tmp/lumibackup/lib/upgrade/keep.d/
echo /etc/lumi/ > /tmp/lumibackup/lib/upgrade/keep.d/lumi
cp -aPrv /lumi/conf /tmp/lumibackup/etc/lumi/
tar -C /tmp/lumibackup -zcvf /tmp/$LUMI_FILENAME .
echo "Sending TERM..."
kill_remaining TERM
sleep 1
echo "Sending KILL..."
kill_remaining KILL 1
sleep 1
switch_to_ramfs
write_image $IMAGE