wrs-boot-procedure 9.33 KB
Newer Older
1 2
#!/bin/sh

3
# This is executed as "sysinit" level, before all /etc/init.d/rcS/S* scripts.
4 5 6 7

# Warning: this file (and only this one) is executed in initramfs
# *before* /etc is copied from flash, so you can't edit this on
# flash, as it won't work. This can only be modified at build time.
8 9
# Don't run/access anything from /usr, because it is not mounted until
# the end of this file.
10 11 12 13 14 15 16 17 18

echo "$0: Running"

# This allows me to pass WRS_VERBOSE=y on the command line...
if [ -n "$WRS_VERBOSE" ]; then
    set -x
fi

# This used to be S01modules
19 20 21 22
insmod /lib/modules/`uname -r`/kernel/libcomposite.ko

insmod /lib/modules/`uname -r`/kernel/u_serial.ko
insmod /lib/modules/`uname -r`/kernel/usb_f_acm.ko
23
insmod /lib/modules/`uname -r`/kernel/g_serial.ko
24
rmmod g_serial
25
insmod /lib/modules/`uname -r`/kernel/g_serial.ko
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

/bin/mkdir -p /dev/pts
/bin/mkdir -p /dev/shm

# See fstab:  /dev/pts, /tmp, /sys
/bin/mount -a;

# Allow me to have a shell at this point in time,
# by passing WRS_INTERACTIVE=y in the command line.
#echo "WRS_INTERACTIVE: \"$WRS_INTERACTIVE\""
if [ -n "$WRS_INTERACTIVE" ]; then sh; fi


# At installation time, we have WRS_INSTALLING=y
if [ -n "$WRS_INSTALLING" ]; then install=true; else install=false; fi

42 43
# All special file names are factorized here. All "old" copies use
# "current-" as a prefix. And we support "previous-" too.
44
WRS_FW="wrs-firmware.tar"
45
WRS_USR="wrs-usr.tar.gz"
46 47 48 49 50 51 52
WRS_KER="zImage"
WRS_RAMFS="wrs-initramfs.gz"
WRS_BB="barebox.bin"

# This is an old name we need to remove so users are not confused
OLD_FW_OLDNAME="wrs-firmware-old.tar"

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

# This helps create the devices that we need over time (and are dynamic)
mkdev_sh () {
    f="$1/dev"
    name=$(busybox basename $1)
    maj=$(busybox awk -F: '{print $1}' $f)
    min=$(busybox awk -F: '{print $2}' $f)
    rm -f /dev/$name
    mknod /dev/$name c $maj $min
}

# Create ubi_ctrl in any case
mkdev_sh "/sys/devices/virtual/misc/ubi_ctrl"


68
TEE="/bin/nbtee"; # often used. And non-blocking, in case ttyGS0 is unplugged
69

70 71 72 73 74 75 76 77
# Installing is like updating, but there are more steps to do initially
if $install; then

    # keep /dev/ttyGS0 open, to prevent EOF being seen from the PC
    sleep 99999 > /dev/ttyGS0 &
    sleep 1; # extra delay, so sleep above opens device before echo below

    # format the ubi device and create volumes
78
    echo -n "Formatting UBI device..." | $TEE /dev/ttyGS0
79
    ubiformat -y -q /dev/mtd1; # This takes up to 40s if flash is dirty
80
    echo " done" | $TEE /dev/ttyGS0
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98

    ubiattach -p /dev/mtd1
    mkdev_sh "/sys/devices/virtual/ubi/ubi0"
    ubimkvol /dev/ubi0 -s  32MiB -N boot
    ubimkvol /dev/ubi0 -s 150MiB -N usr
    ubimkvol /dev/ubi0 -s 150MiB -N update

    # be able to access them in /dev
    mkdev_sh "/sys/devices/virtual/ubi/ubi0/ubi0_0"
    mkdev_sh "/sys/devices/virtual/ubi/ubi0/ubi0_1"
    mkdev_sh "/sys/devices/virtual/ubi/ubi0/ubi0_2"

    # mount the "update" directory, and download stuff in there
    mkdir -p /update
    mount -t ubifs ubi0:update /update

    # Eth0 is already up, thanks to ip= passed by bootloader
    cd /update
99 100
    echo -n "Getting tftp://$SERVERIP/$WRS_FW ..." | $TEE /dev/ttyGS0
    busybox tftp -g -r $WRS_FW -l $WRS_FW $SERVERIP 2>&1 | $TEE /dev/ttyGS0
101 102
    while [ ! -f $WRS_FW ]; do
	echo "Downloading tftp://$SERVERIP/$WRS_FW failed" | \
103
		$TEE /dev/ttyGS0
104 105
	# this loops forever
	sleep 5
106
	busybox tftp -g -r $WRS_FW -l $WRS_FW $SERVERIP 2>&1 | $TEE /dev/ttyGS0
107 108 109
    done


110
    cd /; umount /update
111
    echo " done" | $TEE /dev/ttyGS0
112
    
113 114 115 116 117 118 119
else
    # Not installing, access existing UBI volumes
    ubiattach -p /dev/mtd1
    mkdev_sh "/sys/devices/virtual/ubi/ubi0"
    mkdev_sh "/sys/devices/virtual/ubi/ubi0/ubi0_0"
    mkdev_sh "/sys/devices/virtual/ubi/ubi0/ubi0_1"
    mkdev_sh "/sys/devices/virtual/ubi/ubi0/ubi0_2"
120 121 122 123 124
fi

# Now, whether installing or not, mount /update and check what is there
mkdir -p /update
mount -t ubifs ubi0:update /update
125 126 127
# Mount /boot too, as we check for files in there, later
mkdir -p /boot
mount -t ubifs ubi0:boot /boot
128

129 130 131
# Some steps later set reboot=true; prepare a sane default.
reboot=false

132 133 134
#whether to change date of last update
change_update_date=false

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
checksum_error=false

# commands below are links to the busybox from /usr, which is not mounted yet
# at this moment
md5sum_bin="/bin/busybox md5sum"
cut_bin="/bin/busybox cut"

# check checksums, but only if we have $WRS_FW archive
if [ -f /update/$WRS_FW  ]; then
    tar -xOf /update/$WRS_FW checksums.md5 &>/dev/null
    if [ $? != 0 ]; then
	echo -e "\nWarning: File with checksums for the new firmware not found\n" | $TEE /dev/ttyGS0
    else
	echo "Verifying checksums of the new firmware" | $TEE /dev/ttyGS0
	for file in `tar -tf /update/$WRS_FW`; do
	    if [ x"$file" = x"checksums.md5" ]; then
		continue;
	    fi
	    echo -n "Checking $file ... " | $TEE /dev/ttyGS0
	    sum=`tar -xOf /update/$WRS_FW $file | $md5sum_bin  | $cut_bin -f 1 -d " "`
	    expected_sum=`tar -xOf /update/$WRS_FW checksums.md5 | grep "$file" | $cut_bin -f 1 -d " "`
	    if [ x"$expected_sum" = x"" ]; then
		echo "Error no checksum found for file $file" | $TEE /dev/ttyGS0
		checksum_error=true
	    else
		echo "$expected_sum" | grep "$sum" > /dev/null
		if [ $? != 0 ]; then
		    echo "Checksum error! Expected $expected_sum, calculated $sum" | $TEE /dev/ttyGS0
		    checksum_error=true
		else
		    echo "OK" | $TEE /dev/ttyGS0
		fi
	    fi
	done
	if [ $checksum_error = true ]; then
	    echo -e "\nChecksum error! skip firmware update!\n" | $TEE /dev/ttyGS0
	    mv /update/"$WRS_FW" /update/"$WRS_FW".checksum_error
	else
	    if [ -f /update/"$WRS_FW".checksum_error ]; then
		echo "Remove file /update/"$WRS_FW".checksum_error" | $TEE /dev/ttyGS0
		rm -f /update/"$WRS_FW".checksum_error
	    fi
	fi
    fi

fi


183 184
# First: update usr: we may have the whole thing, or just wrs-usr.tar.gz
if [ -f /update/$WRS_FW -o -f /update/$WRS_USR ]; then
185
    # FIXME: save configuration somewhere, and recover it later
186
    echo -n "Extracting filesystem..." | $TEE /dev/ttyGS0
187 188 189
    # since we are upgrading, we'd better remove and recreate the volume
    ubirmvol /dev/ubi0 --name=usr
    ubimkvol /dev/ubi0 -s 150MiB -N usr
190
    # So, it's new: mount and untar, from whole-tar or usr only
191 192
    mount -t ubifs ubi0:usr /usr
    cd /usr
193 194 195 196 197
    if [ -f /update/$WRS_FW ]; then
	tar -xOf /update/$WRS_FW $WRS_USR | zcat | tar xf -
    else
	tar xzf /update/$WRS_USR
    fi
198

199
    sync; cd /; umount /usr
200
    echo " done" | $TEE /dev/ttyGS0
201 202 203 204

    # check if we have an initramfs and/or kernel too
    # FIXME: should rather check first and save a backup
    cd /boot
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220

    if [ -f /update/$WRS_FW ]; then
	# The commands may fail because we miss wrs-firmware.tar or the content
	for file in $WRS_KER $WRS_RAMFS; do
	
	    echo -n "Trying to extract $file..." | $TEE /dev/ttyGS0
	    tar -xf /update/$WRS_FW $file &> /dev/null
	    ret=$?
	    if [ $ret = 0 ]; then
		echo " done" | $TEE /dev/ttyGS0
		reboot=true
	    else
		echo " not present in anchive" | $TEE /dev/ttyGS0
	    fi
	done
    fi
221
    # Do the same for barebox.bin, so we can upgrade it all in a step
222 223 224
    cd /tmp
    tar -xf /update/$WRS_FW $WRS_BB
    if [ -f $WRS_BB ]; then
225
	echo -n "Updating barebox..." | $TEE /dev/ttyGS0
226 227
	cat $WRS_BB > /dev/mtd3
	rm $WRS_BB
228
	echo " done" | $TEE /dev/ttyGS0
229 230 231
    fi

    # done: rename the firmware file (whole or usr, whatever is there)
232 233 234 235 236 237 238 239 240
    if [ -f /update/$WRS_FW ]; then
	mv /update/current-$WRS_FW /update/previous-$WRS_FW 2> /dev/null
	mv /update/$WRS_FW /update/current-$WRS_FW
    else
	mv /update/current-$WRS_USR  /update/previous-$WRS_USR 2> /dev/null
	mv /update/$WRS_USR  /update/current-$WRS_USR
    fi
    # And, to be sure, remove a file that may exist from a 4.0 install
    rm -f /update/$OLD_FW_OLDNAME
241
    change_update_date=true
242
fi
243

244
# Allow replacing the kernel or initramfs alone (new in v4.1 of wr-switch-sw)
245
for file in $WRS_KER $WRS_RAMFS; do
246
    if [ -f /update/$file ]; then
247
	echo -n "Replacing $file..." | $TEE /dev/ttyGS0
248
	cp /update/$file /boot; sync
249 250 251
	mv /update/current-$file /update/previous-${file} 2> /dev/null
	mv /update/$file /update/current-$file
	reboot=true
252
	echo " done" | $TEE /dev/ttyGS0
253
    fi
254 255 256
done

# Allow changing the boot loader (new in v4.1 of wr-switch-sw)
257
if [ -f /update/$WRS_BB ]; then
258
    echo -n "Updating barebox..." | $TEE /dev/ttyGS0
259 260 261 262
    cat /update/$WRS_BB > /dev/mtd3
    mv /update/current-$WRS_BB /update/previous-$WRS_BB
    mv /update/$WRS_BB /update/current-$WRS_BB
    reboot=true
263
    change_update_date=true
264
    echo " done" | $TEE /dev/ttyGS0
265
fi
266

267 268 269
if $change_update_date; then
    cp /update/saved_date /update/last_update > /dev/null 2>&1
fi
270 271
# If we changed bloader or kernel or initramfs, we reboot. Otherwise proceed.
if $reboot; then
272
    cd /
273 274
    umount /update
    umount /boot
275
    echo "Gentle reboot"
276
    reboot
277 278 279 280 281 282 283 284 285 286 287 288
    sleep 2
    # If init ignores signals before all sysinit entires from inittab are done,
    # we have to force the reboot.
    echo "Force reboot"
    # Firstly, remount / in case we use nfs
    /bin/mount -o remount,ro /
    # umount what is left
    /bin/umount -a -r
    # force reboot
    reboot -f
    # wait forever
    while true; do sleep 1; done
289 290
fi

291 292 293 294
# Here we are: boot normally: if initrd, mount /usr and copy /etc
# Otherwise do not do that, because we likely are nfs-root
if grep -q initrd= /proc/cmdline; then
    mount -t ubifs ubi0:usr /usr
295
    # Remove this script: avoid overwriting an open file
296 297 298
    rm /etc/init.d/wrs-boot-procedure;
    cp -a /usr/etc/* /etc
fi
299 300 301

# create dir for home dirs
mkdir -p /tmp/home