#!/bin/sh # This is executed as "sysinit" level, before all /etc/init.d/rcS/S* scripts. # 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. # Don't run/access anything from /usr, because it is not mounted until # the end of this file. 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 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 insmod /lib/modules/`uname -r`/kernel/g_serial.ko rmmod g_serial insmod /lib/modules/`uname -r`/kernel/g_serial.ko /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 # All special file names are factorized here. All "old" copies use # "current-" as a prefix. And we support "previous-" too. WRS_FW="wrs-firmware.tar" WRS_USR="wrs-usr.tar.gz" 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" # 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" TEE="/bin/nbtee"; # often used. And non-blocking, in case ttyGS0 is unplugged # 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 echo -n "Formatting UBI device..." | $TEE /dev/ttyGS0 ubiformat -y -q /dev/mtd1; # This takes up to 40s if flash is dirty echo " done" | $TEE /dev/ttyGS0 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 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 while [ ! -f $WRS_FW ]; do echo "Downloading tftp://$SERVERIP/$WRS_FW failed" | \ $TEE /dev/ttyGS0 # this loops forever sleep 5 busybox tftp -g -r $WRS_FW -l $WRS_FW $SERVERIP 2>&1 | $TEE /dev/ttyGS0 done cd /; umount /update echo " done" | $TEE /dev/ttyGS0 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" fi # Now, whether installing or not, mount /update and check what is there mkdir -p /update mount -t ubifs ubi0:update /update # Mount /boot too, as we check for files in there, later mkdir -p /boot mount -t ubifs ubi0:boot /boot # Some steps later set reboot=true; prepare a sane default. reboot=false #whether to change date of last update change_update_date=false 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 # 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 # FIXME: save configuration somewhere, and recover it later echo -n "Extracting filesystem..." | $TEE /dev/ttyGS0 # since we are upgrading, we'd better remove and recreate the volume ubirmvol /dev/ubi0 --name=usr ubimkvol /dev/ubi0 -s 150MiB -N usr # So, it's new: mount and untar, from whole-tar or usr only mount -t ubifs ubi0:usr /usr cd /usr if [ -f /update/$WRS_FW ]; then tar -xOf /update/$WRS_FW $WRS_USR | zcat | tar xf - else tar xzf /update/$WRS_USR fi sync; cd /; umount /usr echo " done" | $TEE /dev/ttyGS0 # check if we have an initramfs and/or kernel too # FIXME: should rather check first and save a backup cd /boot 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 # Do the same for barebox.bin, so we can upgrade it all in a step cd /tmp tar -xf /update/$WRS_FW $WRS_BB if [ -f $WRS_BB ]; then echo -n "Updating barebox..." | $TEE /dev/ttyGS0 cat $WRS_BB > /dev/mtd3 rm $WRS_BB echo " done" | $TEE /dev/ttyGS0 fi # done: rename the firmware file (whole or usr, whatever is there) 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 change_update_date=true fi # Allow replacing the kernel or initramfs alone (new in v4.1 of wr-switch-sw) for file in $WRS_KER $WRS_RAMFS; do if [ -f /update/$file ]; then echo -n "Replacing $file..." | $TEE /dev/ttyGS0 cp /update/$file /boot; sync mv /update/current-$file /update/previous-${file} 2> /dev/null mv /update/$file /update/current-$file reboot=true echo " done" | $TEE /dev/ttyGS0 fi done # Allow changing the boot loader (new in v4.1 of wr-switch-sw) if [ -f /update/$WRS_BB ]; then echo -n "Updating barebox..." | $TEE /dev/ttyGS0 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 change_update_date=true echo " done" | $TEE /dev/ttyGS0 fi if $change_update_date; then cp /update/saved_date /update/last_update > /dev/null 2>&1 fi # If we changed bloader or kernel or initramfs, we reboot. Otherwise proceed. if $reboot; then cd / umount /update umount /boot echo "Gentle reboot" reboot 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 fi # 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 # Remove this script: avoid overwriting an open file rm /etc/init.d/wrs-boot-procedure; cp -a /usr/etc/* /etc fi # create dir for home dirs mkdir -p /tmp/home