root/trunk/freewrt/scripts/flash.sh

Revision 3724, 7.1 kB (checked in by tg, 8 months ago)

new option -s, to be used together with -F:
do *not* write empty FWCF filesystem (131072 bytes),
just invalidate its signature magic (1 byte)

to work around bootloader issues

  • Property svn:keywords set to Id
Line 
1 # $Id$
2 #-
3 # This file is part of the FreeWRT project. FreeWRT is copyrighted
4 # material, please see the LICENCE file in the top-level directory
5 # or at http://www.freewrt.org/licence for details.
6
7 if test -z "$KSH_VERSION$BASH_VERSION"; then
8         echo >&2 Sorry, at the moment, a Korn shell or GNU bash is required.
9         exit 255
10 fi
11
12 [[ -n $BASH_VERSION ]] && shopt -s extglob
13 [[ -n $KSH_VERSION ]] && alias which='whence -p'
14
15 me=${0##*/}
16 wd=$(pwd)
17
18 if ! which stat >/dev/null 2>&1; then
19         getsize() {
20                 # no stat(1)
21                 echo 0
22         }
23 elif stat --help >/dev/null 2>&1; then
24         getsize() {
25                 # GNU stat, not standards-compliant
26                 stat -c '%s' "$@" 2>/dev/null
27         }
28 else
29         getsize() {
30                 # BSD stat(1)
31                 stat -f '%z' "$@" 2>/dev/null
32         }
33 fi
34
35 die() {
36         printf >&2 '%s: %s\n' "$me" "$*"
37         exit 1
38 }
39
40 usage() {
41         cat >&2 <<-EOF
42                 Syntax: $me [-nx] [-c tftp] [-D dir | -F | -f fwcf.bin] [-t type] file [ip]
43                 Valid types are:
44                     wl500g wl500gd wl500gp wl500gx linksys
45                 Meta-types (no support for -f or -F):
46                     wl500gx = wl500gd or wl500gp
47                     linksys = all linksys models
48                 Use -x to flash oversized images.
49         EOF
50         exit 1
51 }
52
53 imgtype=auto
54 flashtype=auto
55 typeset -i dopad=0
56 typeset -i padsize=0
57 paddir=
58 padfile=
59 tftp=tftp
60 typeset -i nflag=0
61 typeset -i sflag=0
62 typeset -i xflag=0
63
64 while getopts ":c:D:Ff:nst:x" ch; do
65         case $ch in
66         (c)     tftp=$OPTARG
67                 ;;
68         (D)     dopad=1
69                 paddir=$OPTARG
70                 padfile=
71                 ;;
72         (F)     dopad=1
73                 paddir=
74                 padfile=
75                 ;;
76         (f)     dopad=1
77                 paddir=
78                 padfile=$OPTARG
79                 [[ -s $padfile ]] || die "Invalid pad file '$padfile'"
80                 ;;
81         (n)     nflag=1
82                 ;;
83         (s)     sflag=1
84                 ;;
85         (t)     imgtype=$OPTARG
86                 ;;
87         (x)     xflag=1
88                 ;;
89         (:)     echo >&2 "$me: Error: missing argument to -$OPTARG"
90                 usage
91                 ;;
92         (*)     echo >&2 "$me: Error: invalid option -$OPTARG"
93                 usage
94                 ;;
95         esac
96 done
97 shift $((OPTIND - 1))
98
99 [[ $# -lt 1 || $# -gt 2 ]] && usage
100 imgfile=$1
101 [[ $imgfile = *@( )* ]] && die Spaces in filenames are not supported
102 [[ -s $imgfile ]] || die "Image file '$imgfile' non-existent or 0 bytes"
103 if (( nflag )); then
104         ofile=${2:-flash.out}
105 else
106         ip=${2:-192.168.1.1}
107         [[ $ip = +([0-9]).+([0-9]).+([0-9]).+([0-9]) ]] || \
108             die "Invalid IPv4 address '$ip'"
109 fi
110
111 [[ $imgtype = auto ]] && case ${imgfile%.[bt][ir][nx]} in
112 *-asus-wl500g-premium-*)
113         imgtype=wl500gp ;;
114 *-asus-wl500g-deluxe-*)
115         imgtype=wl500gd ;;
116 *-asus-wl500g-*)
117         imgtype=wl500g ;;
118 *-linksys-*)
119         imgtype=linksys ;;
120 *)
121         die "Cannot determine model from filename '$imgfile', use -t option" ;;
122 esac
123
124 case $imgtype in
125 wl500g)
126         flashtype=wl500g ;;
127 wl500gd|wl500gp|wl500gx)
128         flashtype=wl500gx ;;
129 linksys)
130         flashtype=linksys ;;
131 *)
132         die "Unknown model '$imgtype'" ;;
133 esac
134
135 case $imgtype in
136 wl500g|wl500gd)
137         padsize=3735552 ;;
138 wl500gp)
139         padsize=7929856 ;;
140 *)
141         padsize=0 ;;
142 esac
143
144 typeset -i imgsize="$(getsize "$imgfile")" 2>&-
145 #   stat retval ok?      know maxsz?      image too large?
146 (( xflag )) && imgsize=0
147 (( (imgsize > 65536) && (padsize > 0) && (imgsize > padsize) )) && \
148     die "Image '$imgfile' too large ($imgsize bytes, max. $padsize bytes)"
149
150 if (( dopad )); then
151         (( padsize )) || die "Cannot use -F or -f with a $imgtype yet"
152         TF=$(mktemp /tmp/fwflash.XXXXXXXXXX) || die Cannot mktemp
153         TI=$(mktemp /tmp/fwflash.XXXXXXXXXX) || { rm $TF; die Cannot mktemp; }
154         trap 'cd "$wd"; rm -f $TF $TI; exit 0' 0
155         trap 'cd "$wd"; rm -f $TF $TI; exit 1' 1 2 3 5 13 15
156         randsrc=/dev/arandom
157         [[ -e $randsrc ]] || randsrc=/dev/urandom
158         [[ -e $randsrc ]] || randsrc=/dev/random
159         [[ -e $randsrc ]] || die Cannot find an entropy source
160         dd if=$randsrc of=$TF bs=131072 count=1 2>&-
161         if [[ -n $padfile ]]; then
162                 id=
163                 eval $(dd if="$padfile" bs=7 count=1 2>&- | \
164                     hexdump -e '"id=" 4/1 "%02X" " n=" 3/1 "%02X" "\n"')
165                 if [[ $id = 46574346 ]]; then
166                         sz=$(printf 'ibase=16\n%s\n' $(echo -n $n | \
167                             sed 's/\(..\)\(..\)\(..\)/\3\2\1/') | bc)
168                         dd if="$padfile" bs=$sz count=1
169                 else
170                         cat "$padfile"
171                 fi | dd of=$TF conv=notrunc 2>&-
172                 typeset -i fwcfsize="$(getsize $TF)" 2>&-
173                 (( fwcfsize > 131072 )) && die "FWCF filesystem '$padfile' too" \
174                     "large ($fwcfsize bytes, max. 131072 bytes)"
175                 echo "TRX file constructed from root='$imgfile' and fwcf='$padfile'"
176         elif [[ -n $paddir ]]; then
177                 # locate fwcf.helper
178                 p=fwcf.helper
179                 $p -l 2>&1 | fgrep lzo1x1 >/dev/null || \
180                     for dir in . .. ../.. ../../.. ../../../.. *wrt* *WRT*; do
181                         p=$dir/lbin/fwcf.helper
182                         [[ -e $dir/. ]] || continue
183                         [[ -x $p ]] || continue
184                         $p -l 2>&1 | fgrep lzo1x1 >/dev/null && break
185                         p=
186                 done
187                 [[ $p = fwcf.helper || -x $p ]] || die Cannot find fwcf.helper
188                 # create fwcf filesystem image
189                 $p -M "$paddir" >$TI || die Error creating fwcf filesystem image
190                 dd if=$TI of=$TF conv=notrunc 2>&-
191                 echo "TRX file constructed from '$imgfile' and FWCF from '$paddir'"
192         else
193                 printf 'FWCF\x18\x00\x00\x01\x01\x00\x00\x10\x12\x00\x11\x00\x00\x00\x00\x00\x74\x01\x7C\x18' | \
194                     dd of=$TF conv=notrunc 2>&-
195                 echo "TRX file constructed from '$imgfile' and empty fwcf filesystem"
196         fi
197         dd if=/dev/zero of=$TI bs=$padsize count=1 2>&-
198         dd if="$imgfile" of=$TI conv=notrunc 2>&-
199         if (( sflag )); then
200                 [[ -n $padfile || -n $paddir ]] && die Cannot use -s without -F
201                 printf '!' >>$TI
202         else
203                 cat $TF >>$TI
204         fi
205         imgfile=$TI
206 else
207         echo "Using TRX file from '$imgfile'"
208 fi
209
210 if (( nflag )); then
211         cat "$imgfile" >"$ofile"
212         echo "Output file '$ofile' written."
213         exit 0
214 fi
215
216 x=$tftp
217 [[ -x $tftp ]] || tftp=$(which $tftp 2>&-)
218 [[ -x $tftp ]] || die "TFTP client '${x:-tftp}' not found"
219
220 echo ATTENTION: Do not turn off the power on your device $ip now!
221 sleep 3
222
223 imgdir=${imgfile%/*}
224 [[ $imgdir = $imgfile ]] && imgdir=.
225 imgfile=${imgfile##*/}
226 cd "$imgdir"
227 typeset -i rv=1
228 text2='This device will reboot itself automatically.'
229 case $flashtype in
230 wl500g)
231         echo Confirming IP address setting...
232         printf 'get ASUSSPACELINK\x01\x01\xA8\xC0 /dev/null\nquit\n' | $tftp $ip
233         echo Flashing image...
234         printf 'binary\nput %s ASUSSPACELINK\nquit\n' "$imgfile" | $tftp $ip
235         rv=$?
236         text1='Please wait until the LEDs stop flashing.'
237         ;;
238 wl500gx)
239         echo Flashing image...
240         printf 'rexmt 1\ntrace\nbinary\nput %s\nquit\n' "$imgfile" | $tftp $ip
241         rv=$?
242         text1='Please wait 5-6 minutes and then remove the power plug.'
243         text2='This device does not reboot automatically after flashing.'
244         ;;
245 linksys)
246         echo Flashing image...
247         printf 'rexmt 1\ntrace\nbinary\nput %s\nquit\n' "$imgfile" | $tftp $ip
248         rv=$?
249         text1='Please wait 3-5 minutes.'
250         ;;
251 esac
252 cd "$wd"
253 if (( rv )); then
254         echo tftp returned with error code $rv.
255         echo The device may not have been flashed correctly.
256         exit 1
257 fi
258 cat <<-EOF
259         $text1
260         $text2
261
262         After flashing is finished and the device has rebooted, it will need
263         to restart once if the filesystem type is squashfs with jffs2 overlay.
264         The power LED will flash quickly as long as startup is in progress.
265
266         Once it has finished flashing, you should be able to access the device
267         via ssh to the "admin" user, for example: ssh -l admin $ip
268
269         If you didn't change the password in menuconfig, it's "FreeWRT" (case
270         sensitive and without the quotation marks). Give the device a while to
271         generate the SSH keys for dropbear first.
272
273         After device initialisation and key generation has finished, it is
274         highly recommended to log in and issue the command "fwcf commit" so that
275         the SSH host keys will be stored in the configuration filesystem and
276         do not have to be regenerated each time the device starts.
277
278 EOF
279 exit 0
Note: See TracBrowser for help on using the browser.