Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 1 | #!/bin/sh |
2 | |||||
3 | echo update: "$@" | ||||
4 | |||||
Milton Miller | d16a7b0 | 2016-06-15 18:47:38 -0500 | [diff] [blame] | 5 | echoerr() { |
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 6 | echo 1>&2 "ERROR: $*" |
Milton Miller | d16a7b0 | 2016-06-15 18:47:38 -0500 | [diff] [blame] | 7 | } |
8 | |||||
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 9 | cd / |
10 | if ! test -r /proc/mounts || ! test -f /proc/mounts | ||||
11 | then | ||||
12 | mkdir -p /proc | ||||
13 | mount -t proc proc proc | ||||
14 | fi | ||||
15 | if ! test -d /sys/class | ||||
16 | then | ||||
17 | mkdir -p /sys | ||||
18 | mount -t sysfs sys sys | ||||
19 | fi | ||||
20 | if ! test -c /dev/null | ||||
21 | then | ||||
22 | mkdir -p /dev | ||||
23 | mount -t devtmpfs dev dev | ||||
24 | fi | ||||
Milton Miller | e1cbebe | 2016-05-23 16:00:19 -0500 | [diff] [blame] | 25 | |
Milton Miller | 810dc70 | 2016-05-23 19:17:55 -0500 | [diff] [blame] | 26 | # mtd number N with mtd name Name can be mounted via mtdN, or mtd:Name |
27 | # (with a mtd aware fs) or by /dev/mtdblockN (with a mtd or block fs). | ||||
28 | mtdismounted() { | ||||
29 | m=${1##mtd} | ||||
30 | if grep -s "mtdblock$m " /proc/mounts || grep -s "mtd$m " /proc/mounts | ||||
31 | then | ||||
32 | return 0 | ||||
33 | fi | ||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 34 | n=$(cat "/sys/class/mtd/mtd$m/name") |
Milton Miller | 810dc70 | 2016-05-23 19:17:55 -0500 | [diff] [blame] | 35 | if test -n "$n" && grep -s "mtd:$n " /proc/mounts |
36 | then | ||||
37 | return 0 | ||||
38 | fi | ||||
39 | return 1 | ||||
40 | } | ||||
41 | |||||
42 | # Detect child partitions when the whole flash is to be updated. | ||||
43 | # Ignore mtdNro and mtdblockN names in the class subsystem directory. | ||||
44 | childmtds() { | ||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 45 | for m in "/sys/class/mtd/$1/mtd"* |
Milton Miller | 810dc70 | 2016-05-23 19:17:55 -0500 | [diff] [blame] | 46 | do |
47 | m=${m##*/} | ||||
48 | if test "${m%ro}" = "${m#mtdblock}" | ||||
49 | then | ||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 50 | echo "$m" |
Milton Miller | 810dc70 | 2016-05-23 19:17:55 -0500 | [diff] [blame] | 51 | fi |
52 | done | ||||
53 | } | ||||
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 54 | |
Milton Miller | 1944aac | 2016-05-23 18:22:11 -0500 | [diff] [blame] | 55 | toobig() { |
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 56 | if test "$(stat -L -c "%s" "$1")" -gt "$(cat "/sys/class/mtd/$2/size")" |
Milton Miller | 1944aac | 2016-05-23 18:22:11 -0500 | [diff] [blame] | 57 | then |
58 | return 0 | ||||
59 | fi | ||||
60 | return 1 | ||||
61 | } | ||||
62 | |||||
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 63 | findmtd() { |
64 | m=$(grep -xl "$1" /sys/class/mtd/*/name) | ||||
65 | m=${m%/name} | ||||
66 | m=${m##*/} | ||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 67 | echo "$m" |
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 68 | } |
69 | |||||
Andrew Jeffery | 25a5022 | 2016-02-23 23:47:23 +1030 | [diff] [blame] | 70 | blkid_fs_type() { |
71 | # Emulate util-linux's `blkid -s TYPE -o value $1` | ||||
72 | # Example busybox blkid output: | ||||
73 | # # blkid /dev/mtdblock5 | ||||
74 | # /dev/mtdblock5: TYPE="squashfs" | ||||
75 | # Process output to extract TYPE value "squashfs". | ||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 76 | blkid "$1" | sed -e 's/^.*TYPE="//' -e 's/".*$//' |
Andrew Jeffery | 25a5022 | 2016-02-23 23:47:23 +1030 | [diff] [blame] | 77 | } |
78 | |||||
79 | probe_fs_type() { | ||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 80 | fst=$(blkid_fs_type "$1") |
81 | echo "${fst:=jffs2}" | ||||
Andrew Jeffery | 25a5022 | 2016-02-23 23:47:23 +1030 | [diff] [blame] | 82 | } |
83 | |||||
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 84 | rwfs=$(findmtd rwfs) |
85 | |||||
Milton Miller | ba65b7b | 2016-02-05 12:07:53 -0600 | [diff] [blame] | 86 | rwdev=/dev/mtdblock${rwfs#mtd} |
Milton Miller | ba65b7b | 2016-02-05 12:07:53 -0600 | [diff] [blame] | 87 | rwopts=rw |
88 | rorwopts=ro${rwopts#rw} | ||||
89 | |||||
Milton D. Miller II | c3697de | 2016-02-28 16:07:46 -0600 | [diff] [blame] | 90 | rwdir=/run/initramfs/rw |
Milton Miller | ba65b7b | 2016-02-05 12:07:53 -0600 | [diff] [blame] | 91 | upper=$rwdir/cow |
Milton D. Miller II | fa8316d | 2016-02-29 10:32:58 -0600 | [diff] [blame] | 92 | save=/run/save/${upper##*/} |
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 93 | |
Milton D. Miller II | a987d62 | 2016-02-29 21:34:43 -0600 | [diff] [blame] | 94 | mounted= |
Milton Miller | 4015b7a | 2016-05-23 17:41:34 -0500 | [diff] [blame] | 95 | doflash=y |
Milton D. Miller II | d0b0c6a | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 96 | doclean= |
Milton D. Miller II | ecf68d5 | 2016-02-29 23:11:27 -0600 | [diff] [blame] | 97 | dosave=y |
98 | dorestore=y | ||||
Milton D. Miller II | 7141eb0 | 2016-02-29 21:44:22 -0600 | [diff] [blame] | 99 | toram= |
Milton Miller | 1944aac | 2016-05-23 18:22:11 -0500 | [diff] [blame] | 100 | checksize=y |
Milton Miller | 810dc70 | 2016-05-23 19:17:55 -0500 | [diff] [blame] | 101 | checkmount=y |
Milton D. Miller II | d0b0c6a | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 102 | |
Milton D. Miller II | ee91f8d | 2016-02-29 11:39:11 -0600 | [diff] [blame] | 103 | whitelist=/run/initramfs/whitelist |
104 | image=/run/initramfs/image- | ||||
Milton Miller | 4e87861 | 2016-06-16 16:44:12 -0500 | [diff] [blame] | 105 | imglist= |
Milton D. Miller II | ee91f8d | 2016-02-29 11:39:11 -0600 | [diff] [blame] | 106 | |
Milton D. Miller II | d0b0c6a | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 107 | while test "$1" != "${1#-}" |
108 | do | ||||
109 | case "$1" in | ||||
Milton Miller | 30137fa | 2016-06-15 16:02:23 -0500 | [diff] [blame] | 110 | --help) |
111 | cat <<HERE | ||||
112 | Usage: $0 [options] -- Write images in /run/initramfs to flash (/dev/mtd*) | ||||
113 | --help Show this message | ||||
114 | --no-flash Don't attempt to write images to flash | ||||
115 | --ignore-size Don't compare image size to mtd device size | ||||
116 | --ignore-mount Don't check if destination is mounted | ||||
117 | --save-files Copy whitelisted files to save directory in RAM | ||||
118 | --no-save-files Don't copy whitelisted files to save directory | ||||
119 | --copy-files Copy files from save directory to rwfs mountpoint | ||||
120 | --restore-files Restore files from save directory to rwfs layer | ||||
121 | --no-restore-files Don't restore saved files from ram to rwfs layer | ||||
122 | --clean-saved-files Delete saved whitelisted files from RAM | ||||
123 | --no-clean-saved-files Retain saved whitelisted files in RAM | ||||
124 | HERE | ||||
125 | |||||
126 | exit 0 ;; | ||||
127 | |||||
Milton D. Miller II | d0b0c6a | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 128 | --no-clean-saved-files) |
129 | doclean= | ||||
130 | shift ;; | ||||
131 | --clean-saved-files) | ||||
132 | doclean=y | ||||
133 | shift ;; | ||||
Milton D. Miller II | ecf68d5 | 2016-02-29 23:11:27 -0600 | [diff] [blame] | 134 | --no-save-files) |
135 | dosave= | ||||
136 | shift ;; | ||||
137 | --save-files) | ||||
138 | dosave=y | ||||
139 | shift ;; | ||||
140 | --no-restore-files) | ||||
141 | dorestore= | ||||
142 | shift ;; | ||||
143 | --restore-files) | ||||
144 | dorestore=y | ||||
145 | shift ;; | ||||
Milton Miller | 4015b7a | 2016-05-23 17:41:34 -0500 | [diff] [blame] | 146 | --no-flash) |
147 | doflash= | ||||
148 | shift ;; | ||||
Milton Miller | 1944aac | 2016-05-23 18:22:11 -0500 | [diff] [blame] | 149 | --ignore-size) |
150 | checksize= | ||||
151 | shift ;; | ||||
Milton Miller | 810dc70 | 2016-05-23 19:17:55 -0500 | [diff] [blame] | 152 | --ignore-mount) |
153 | checkmount= | ||||
154 | doflash= | ||||
155 | shift ;; | ||||
Milton D. Miller II | 7141eb0 | 2016-02-29 21:44:22 -0600 | [diff] [blame] | 156 | --copy-files) |
157 | toram=y | ||||
158 | shift ;; | ||||
Milton D. Miller II | d0b0c6a | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 159 | *) |
Milton Miller | 30137fa | 2016-06-15 16:02:23 -0500 | [diff] [blame] | 160 | echoerr "Unknown option $1. Try $0 --help." |
Milton D. Miller II | d0b0c6a | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 161 | exit 1 ;; |
162 | esac | ||||
163 | done | ||||
164 | |||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 165 | if test "$dosave" = "y" |
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 166 | then |
Milton D. Miller II | a987d62 | 2016-02-29 21:34:43 -0600 | [diff] [blame] | 167 | if test ! -d $upper -a -n "$rwfs" |
168 | then | ||||
169 | mkdir -p $rwdir | ||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 170 | mount "$rwdev" $rwdir -t "$(probe_fs_type "$rwdev")" -o "$rorwopts" |
Milton D. Miller II | a987d62 | 2016-02-29 21:34:43 -0600 | [diff] [blame] | 171 | mounted=$rwdir |
172 | fi | ||||
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 173 | |
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 174 | while read -r f |
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 175 | do |
Milton Miller | adeceff | 2016-06-16 16:58:21 -0500 | [diff] [blame] | 176 | # Entries shall start with /, no trailing /.. or embedded /../ |
177 | if test "/${f#/}" != "$f" -o "${f%/..}" != "${f#*/../}" | ||||
178 | then | ||||
179 | echo 1>&2 "WARNING: Skipping bad whitelist entry $f." | ||||
180 | continue | ||||
181 | fi | ||||
182 | if ! test -e "$upper/$f" | ||||
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 183 | then |
184 | continue | ||||
185 | fi | ||||
Milton Miller | ba65b7b | 2016-02-05 12:07:53 -0600 | [diff] [blame] | 186 | d="$save/$f" |
Milton Miller | adeceff | 2016-06-16 16:58:21 -0500 | [diff] [blame] | 187 | while test "${d%/}" != "${d%/.}" |
188 | do | ||||
189 | d="${d%/.}" | ||||
190 | d="${d%/}" | ||||
191 | done | ||||
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 192 | mkdir -p "${d%/*}" |
Milton Miller | adeceff | 2016-06-16 16:58:21 -0500 | [diff] [blame] | 193 | cp -rp "$upper/$f" "${d%/*}/" |
Milton D. Miller II | ee91f8d | 2016-02-29 11:39:11 -0600 | [diff] [blame] | 194 | done < $whitelist |
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 195 | |
Milton D. Miller II | a987d62 | 2016-02-29 21:34:43 -0600 | [diff] [blame] | 196 | if test -n "$mounted" |
197 | then | ||||
198 | umount $mounted | ||||
199 | fi | ||||
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 200 | fi |
201 | |||||
Milton Miller | 4e87861 | 2016-06-16 16:44:12 -0500 | [diff] [blame] | 202 | imglist=$(echo $image*) |
203 | if test "$imglist" = "$image*" -a ! -e "$imglist" | ||||
204 | then | ||||
205 | # shell didn't expand the wildcard, so no files exist | ||||
206 | echo "No images found to update." | ||||
207 | imglist= | ||||
208 | fi | ||||
209 | |||||
210 | for f in $imglist | ||||
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 211 | do |
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 212 | m=$(findmtd "${f#"$image"}") |
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 213 | if test -z "$m" |
214 | then | ||||
Gunnar Mills | 2a85f60 | 2017-10-25 21:25:57 -0500 | [diff] [blame] | 215 | echoerr "Unable to find mtd partition for ${f##*/}." |
Milton Miller | e1cbebe | 2016-05-23 16:00:19 -0500 | [diff] [blame] | 216 | exit 1 |
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 217 | fi |
Milton Miller | 1944aac | 2016-05-23 18:22:11 -0500 | [diff] [blame] | 218 | if test -n "$checksize" && toobig "$f" "$m" |
219 | then | ||||
220 | echoerr "Image ${f##*/} too big for $m." | ||||
221 | exit 1 | ||||
222 | fi | ||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 223 | for s in $m $(childmtds "$m") |
Milton Miller | 810dc70 | 2016-05-23 19:17:55 -0500 | [diff] [blame] | 224 | do |
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 225 | if test -n "$checkmount" && mtdismounted "$s" |
Milton Miller | 810dc70 | 2016-05-23 19:17:55 -0500 | [diff] [blame] | 226 | then |
227 | echoerr "Device $s is mounted, ${f##*/} is busy." | ||||
228 | exit 1 | ||||
229 | fi | ||||
230 | done | ||||
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 231 | done |
232 | |||||
Milton Miller | 4015b7a | 2016-05-23 17:41:34 -0500 | [diff] [blame] | 233 | if test -n "$doflash" |
234 | then | ||||
Milton Miller | 4e87861 | 2016-06-16 16:44:12 -0500 | [diff] [blame] | 235 | for f in $imglist |
Milton Miller | 4015b7a | 2016-05-23 17:41:34 -0500 | [diff] [blame] | 236 | do |
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 237 | if test ! -s "$f" |
Milton Miller | 4015b7a | 2016-05-23 17:41:34 -0500 | [diff] [blame] | 238 | then |
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 239 | echo "Skipping empty update of ${f#"$image"}." |
240 | rm "$f" | ||||
Milton Miller | 4015b7a | 2016-05-23 17:41:34 -0500 | [diff] [blame] | 241 | continue |
242 | fi | ||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 243 | m=$(findmtd "${f#"$image"}") |
244 | echo "Updating ${f#"$image"}..." | ||||
245 | flashcp -v "$f" "/dev/$m" && rm "$f" | ||||
Milton Miller | 4015b7a | 2016-05-23 17:41:34 -0500 | [diff] [blame] | 246 | done |
247 | fi | ||||
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 248 | |
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 249 | if test -d "$save" -a "$toram" = "y" |
Milton D. Miller II | 7141eb0 | 2016-02-29 21:44:22 -0600 | [diff] [blame] | 250 | then |
251 | mkdir -p $upper | ||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 252 | cp -rp "$save/." "$upper/" |
Milton D. Miller II | 7141eb0 | 2016-02-29 21:44:22 -0600 | [diff] [blame] | 253 | fi |
254 | |||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 255 | if test -d "$save" -a "$dorestore" = "y" |
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 256 | then |
Milton D. Miller II | facb718 | 2016-02-28 16:20:19 -0600 | [diff] [blame] | 257 | odir=$rwdir |
258 | rwdir=/run/rw | ||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 259 | upper=$rwdir${upper#"$odir"} |
Milton D. Miller II | facb718 | 2016-02-28 16:20:19 -0600 | [diff] [blame] | 260 | |
261 | mkdir -p $rwdir | ||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 262 | mount "$rwdev" $rwdir -t "$(probe_fs_type "$rwdev")" -o $rwopts |
263 | mkdir -p "$upper" | ||||
264 | cp -rp "$save/." "$upper/" | ||||
Milton Miller | ba65b7b | 2016-02-05 12:07:53 -0600 | [diff] [blame] | 265 | umount $rwdir |
Milton D. Miller II | facb718 | 2016-02-28 16:20:19 -0600 | [diff] [blame] | 266 | rmdir $rwdir |
Milton D. Miller II | 0e77514 | 2016-01-20 14:57:54 -0600 | [diff] [blame] | 267 | fi |
268 | |||||
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 269 | if test "$doclean" = "y" |
Milton D. Miller II | d0b0c6a | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 270 | then |
Patrick Williams | 51d6af4 | 2023-04-14 14:19:55 -0500 | [diff] [blame] | 271 | rm -rf "$save" |
Milton D. Miller II | d0b0c6a | 2016-02-28 16:32:14 -0600 | [diff] [blame] | 272 | fi |
273 | |||||
Milton Miller | dbacf10 | 2016-02-05 13:56:18 -0600 | [diff] [blame] | 274 | exit |