#!/bin/sh echo update: "$@" echoerr() { echo 1>&2 "ERROR: $@" } cd / if ! test -r /proc/mounts || ! test -f /proc/mounts then mkdir -p /proc mount -t proc proc proc fi if ! test -d /sys/class then mkdir -p /sys mount -t sysfs sys sys fi if ! test -c /dev/null then mkdir -p /dev mount -t devtmpfs dev dev fi # mtd number N with mtd name Name can be mounted via mtdN, or mtd:Name # (with a mtd aware fs) or by /dev/mtdblockN (with a mtd or block fs). mtdismounted() { m=${1##mtd} if grep -s "mtdblock$m " /proc/mounts || grep -s "mtd$m " /proc/mounts then return 0 fi n=$(cat /sys/class/mtd/mtd$m/name) if test -n "$n" && grep -s "mtd:$n " /proc/mounts then return 0 fi return 1 } # Detect child partitions when the whole flash is to be updated. # Ignore mtdNro and mtdblockN names in the class subsystem directory. childmtds() { for m in /sys/class/mtd/$1/mtd* do m=${m##*/} if test "${m%ro}" = "${m#mtdblock}" then echo $m fi done } toobig() { if test $(stat -L -c "%s" "$1") -gt $(cat /sys/class/mtd/"$2"/size) then return 0 fi return 1 } findmtd() { m=$(grep -xl "$1" /sys/class/mtd/*/name) m=${m%/name} m=${m##*/} echo $m } blkid_fs_type() { # Emulate util-linux's `blkid -s TYPE -o value $1` # Example busybox blkid output: # # blkid /dev/mtdblock5 # /dev/mtdblock5: TYPE="squashfs" # Process output to extract TYPE value "squashfs". blkid $1 | sed -e 's/^.*TYPE="//' -e 's/".*$//' } probe_fs_type() { fst=$(blkid_fs_type $1) echo ${fst:=jffs2} } rwfs=$(findmtd rwfs) rwdev=/dev/mtdblock${rwfs#mtd} rwopts=rw rorwopts=ro${rwopts#rw} rwdir=/run/initramfs/rw upper=$rwdir/cow save=/run/save/${upper##*/} mounted= doflash=y doclean= dosave=y dorestore=y toram= checksize=y checkmount=y whitelist=/run/initramfs/whitelist image=/run/initramfs/image- imglist= while test "$1" != "${1#-}" do case "$1" in --help) cat <&2 "WARNING: Skipping bad whitelist entry $f." continue fi if ! test -e "$upper/$f" then continue fi d="$save/$f" while test "${d%/}" != "${d%/.}" do d="${d%/.}" d="${d%/}" done mkdir -p "${d%/*}" cp -rp "$upper/$f" "${d%/*}/" done < $whitelist if test -n "$mounted" then umount $mounted fi fi imglist=$(echo $image*) if test "$imglist" = "$image*" -a ! -e "$imglist" then # shell didn't expand the wildcard, so no files exist echo "No images found to update." imglist= fi for f in $imglist do m=$(findmtd ${f#$image}) if test -z "$m" then echoerr "Unable to find mtd partition for ${f##*/}." exit 1 fi if test -n "$checksize" && toobig "$f" "$m" then echoerr "Image ${f##*/} too big for $m." exit 1 fi for s in $m $(childmtds $m) do if test -n "$checkmount" && mtdismounted $s then echoerr "Device $s is mounted, ${f##*/} is busy." exit 1 fi done done if test -n "$doflash" then for f in $imglist do if test ! -s $f then echo "Skipping empty update of ${f#$image}." rm $f continue fi m=$(findmtd ${f#$image}) echo "Updating ${f#$image}..." flashcp -v $f /dev/$m && rm $f done fi if test -d $save -a "x$toram" = xy then mkdir -p $upper cp -rp $save/. $upper/ fi if test -d $save -a "x$dorestore" = xy then odir=$rwdir rwdir=/run/rw upper=$rwdir${upper#$odir} mkdir -p $rwdir mount $rwdev $rwdir -t $(probe_fs_type $rwdev) -o $rwopts mkdir -p $upper cp -rp $save/. $upper/ umount $rwdir rmdir $rwdir fi if test "x$doclean" = xy then rm -rf $save fi exit