1#!/bin/sh 2 3echo update: "$@" 4 5echoerr() { 6 echo 1>&2 "ERROR: $*" 7} 8 9cd / 10if ! test -r /proc/mounts || ! test -f /proc/mounts 11then 12 mkdir -p /proc 13 mount -t proc proc proc 14fi 15if ! test -d /sys/class 16then 17 mkdir -p /sys 18 mount -t sysfs sys sys 19fi 20if ! test -c /dev/null 21then 22 mkdir -p /dev 23 mount -t devtmpfs dev dev 24fi 25 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). 28mtdismounted() { 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 34 n=$(cat "/sys/class/mtd/mtd$m/name") 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. 44childmtds() { 45 for m in "/sys/class/mtd/$1/mtd"* 46 do 47 m=${m##*/} 48 if test "${m%ro}" = "${m#mtdblock}" 49 then 50 echo "$m" 51 fi 52 done 53} 54 55toobig() { 56 if test "$(stat -L -c "%s" "$1")" -gt "$(cat "/sys/class/mtd/$2/size")" 57 then 58 return 0 59 fi 60 return 1 61} 62 63findmtd() { 64 m=$(grep -xl "$1" /sys/class/mtd/*/name) 65 m=${m%/name} 66 m=${m##*/} 67 echo "$m" 68} 69 70blkid_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". 76 blkid "$1" | sed -e 's/^.*TYPE="//' -e 's/".*$//' 77} 78 79probe_fs_type() { 80 fst=$(blkid_fs_type "$1") 81 echo "${fst:=jffs2}" 82} 83 84rwfs=$(findmtd rwfs) 85 86rwdev=/dev/mtdblock${rwfs#mtd} 87rwopts=rw 88rorwopts=ro${rwopts#rw} 89 90rwdir=/run/initramfs/rw 91upper=$rwdir/cow 92save=/run/save/${upper##*/} 93 94mounted= 95doflash=y 96doclean= 97dosave=y 98dorestore=y 99toram= 100checksize=y 101checkmount=y 102 103whitelist=/run/initramfs/whitelist 104image=/run/initramfs/image- 105imglist= 106 107while test "$1" != "${1#-}" 108do 109 case "$1" in 110 --help) 111 cat <<HERE 112Usage: $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 124HERE 125 126 exit 0 ;; 127 128 --no-clean-saved-files) 129 doclean= 130 shift ;; 131 --clean-saved-files) 132 doclean=y 133 shift ;; 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 ;; 146 --no-flash) 147 doflash= 148 shift ;; 149 --ignore-size) 150 checksize= 151 shift ;; 152 --ignore-mount) 153 checkmount= 154 doflash= 155 shift ;; 156 --copy-files) 157 toram=y 158 shift ;; 159 *) 160 echoerr "Unknown option $1. Try $0 --help." 161 exit 1 ;; 162 esac 163done 164 165if test "$dosave" = "y" 166then 167 if test ! -d $upper -a -n "$rwfs" 168 then 169 mkdir -p $rwdir 170 mount "$rwdev" $rwdir -t "$(probe_fs_type "$rwdev")" -o "$rorwopts" 171 mounted=$rwdir 172 fi 173 174 while read -r f 175 do 176 if ! test -e "$upper/$f" 177 then 178 continue 179 fi 180 d="$save/$f" 181 mkdir -p "${d%/*}" 182 cp -rp "$upper/$f" "${d%/*}/" 183 done < $whitelist 184 185 if test -n "$mounted" 186 then 187 umount $mounted 188 fi 189fi 190 191imglist=$(echo $image*) 192if test "$imglist" = "$image*" -a ! -e "$imglist" 193then 194 # shell didn't expand the wildcard, so no files exist 195 echo "No images found to update." 196 imglist= 197fi 198 199for f in $imglist 200do 201 m=$(findmtd "${f#"$image"}") 202 if test -z "$m" 203 then 204 echoerr "Unable to find mtd partition for ${f##*/}." 205 exit 1 206 fi 207 if test -n "$checksize" && toobig "$f" "$m" 208 then 209 echoerr "Image ${f##*/} too big for $m." 210 exit 1 211 fi 212 for s in $m $(childmtds "$m") 213 do 214 if test -n "$checkmount" && mtdismounted "$s" 215 then 216 echoerr "Device $s is mounted, ${f##*/} is busy." 217 exit 1 218 fi 219 done 220done 221 222if test -n "$doflash" 223then 224 for f in $imglist 225 do 226 if test ! -s "$f" 227 then 228 echo "Skipping empty update of ${f#"$image"}." 229 rm "$f" 230 continue 231 fi 232 m=$(findmtd "${f#"$image"}") 233 echo "Updating ${f#"$image"}..." 234 flashcp -v "$f" "/dev/$m" && rm "$f" 235 done 236fi 237 238if test -d "$save" -a "$toram" = "y" 239then 240 mkdir -p $upper 241 cp -rp "$save/." "$upper/" 242fi 243 244if test -d "$save" -a "$dorestore" = "y" 245then 246 odir=$rwdir 247 rwdir=/run/rw 248 upper=$rwdir${upper#"$odir"} 249 250 mkdir -p $rwdir 251 mount "$rwdev" $rwdir -t "$(probe_fs_type "$rwdev")" -o $rwopts 252 mkdir -p "$upper" 253 cp -rp "$save/." "$upper/" 254 umount $rwdir 255 rmdir $rwdir 256fi 257 258if test "$doclean" = "y" 259then 260 rm -rf "$save" 261fi 262 263exit 264