This adds checksum support to sysupgrade as needed for U-Boot on the ALL0258N.
Probably this can be useful for other targets as well.

Signed-off-by: Daniel Golle <dgo...@allnet.de>

Index: platform.sh
===================================================================
--- platform.sh (revision 28191)
+++ platform.sh (working copy)
@@ -1,11 +1,14 @@
 #
 # Copyright (C) 2009 OpenWrt.org
 #
+# Added U-Boot MD5 checksums and failsafe stuff
+# Copyright (C) 2011 Daniel Golle <dgo...@allnet.de>
+#
 
 . /lib/ar71xx.sh
 
 PART_NAME=firmware
-RAMFS_COPY_DATA=/lib/ar71xx.sh
+RAMFS_COPY_DATA="/lib/ar71xx.sh /etc/fw_env.config"
 
 CI_BLKSZ=65536
 CI_LDADR=0x80060000
@@ -39,6 +42,19 @@
        done
 }
 
+platform_get_firmware_size() {
+       local dev size erasesize name
+       while read dev size erasesize name; do
+               name=${name#'"'}; name=${name%'"'}
+               case "$name" in
+                       firmware)
+                               printf "%d" "0x$size"
+                               break
+                       ;;
+               esac
+       done < /proc/mtd
+}
+
 platform_do_upgrade_combined() {
        local partitions=$(platform_find_partitions)
        local kernelpart=$(platform_find_kernelpart "${partitions#*:}")
@@ -61,6 +77,156 @@
        fi
 }
 
+platform_get_offset() {
+       # Scan through the update image pages until matching a magic
+       offsetcount=0
+       magiclong="x"
+       if [ -n "$3" ]; then
+               offsetcount=$3
+       fi
+       while magiclong=$( dd if="$1" skip=$(( $CI_BLKSZ / 4 * $offsetcount )) 
bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' ) && [ -n 
"$magiclong" ]; do
+               case "$magiclong" in
+                       "2705"*)
+                               # U-Boot image magic
+                               if [ "$2" = "uImage" ]; then
+                                       echo $offsetcount
+                                       return
+                               fi
+                       ;;
+                       "68737173"|"73717368")
+                               # SquashFS
+                               if [ "$2" = "rootfs" ]; then
+                                       echo $offsetcount
+                                       return
+                               fi
+                       ;;
+                       "deadc0de"|"19852003")
+                               # JFFS2 empty page
+                               if [ "$2" = "rootfs-data" ]; then
+                                       echo $offsetcount
+                                       return
+                               fi
+                       ;;
+               esac
+               offsetcount=$(( $offsetcount + 1 ))
+       done
+}
+
+platform_get_filesize() {
+       # busybox does not come with stat by default
+       # anyway, use it if we got it
+       local stat=$( which stat )
+       if [ -n "$stat" -a -x "$stat" ]; then
+               $stat -c "%s" "$1"
+       else
+               ls -l "$1" | while read _p _x _u _g image_size _d _t _n ; do 
echo $image_size ; break; done
+       fi
+}
+
+platform_do_upgrade_uboot() {
+       local firmware_base_addr=$( printf "%d" "$1" )
+       local fw_setenv=$( which fw_setenv )
+       local fw_printenv=$( which fw_printenv )
+       local failsafe_hexaddr=""
+       shift
+
+       if [ ! -n "$fw_setenv" -o ! -x "$fw_setenv" -o ! -n "$fw_printenv" -o ! 
-x "$fw_printenv" ]; then
+               echo "Please install uboot-envtools!"
+               return 1
+       fi
+       if [ ! -r "/etc/fw_env.config" ]; then
+               echo "/etc/fw_env.config is missing"
+               return 1
+       fi
+       local vmlinux_blockoffset=$( platform_get_offset "$1" uImage )
+       local rootfs_blockoffset=$( platform_get_offset "$1" rootfs  $(( 
$vmlinux_blockoffset + 1 )) )
+
+       local vmlinux_blockoffset=$( platform_get_offset "$1" uImage )
+       if [ ! -n "$vmlinux_blockoffset" ]; then
+               echo "can't determine uImage offset"
+               return 1
+       fi
+       local rootfs_blockoffset=$( platform_get_offset "$1" rootfs $(( 
$vmlinux_blockoffset + 1 )) )
+       local vmlinux_offset=$(( $vmlinux_blockoffset * $CI_BLKSZ ))
+       local vmlinux_addr=$(( $firmware_base_addr + $vmlinux_offset ))
+       local vmlinux_hexaddr=0x$( printf "%08x" "$vmlinux_addr" )
+       if [ -n "$rootfs_blockoffset" ]; then
+               local rootfs_offset=$(( $rootfs_blockoffset * $CI_BLKSZ ))
+               local rootfs_addr=$(( $firmware_base_addr + $rootfs_offset ))
+               local rootfs_hexaddr=0x$( printf "%08x" "$rootfs_addr" )
+               local vmlinux_blockcount=$(( $rootfs_blockoffset - 
$vmlinux_blockoffset ))
+               local vmlinux_size=$(( $rootfs_offset - $vmlinux_offset ))
+               local vmlinux_hexsize=0x$( printf "%08x" "$vmlinux_size" )
+               local data_blockoffset=$( platform_get_offset "$1" rootfs-data 
$(( $rootfs_blockoffset + 1 )) )
+               if [ ! -n "$data_blockoffset" ]; then
+                       echo "can't determine rootfs size"
+                       return 1
+               fi
+               local data_offset=$(( $data_blockoffset * $CI_BLKSZ ))
+               local rootfs_blockcount=$(( $data_blockoffset - 
$rootfs_blockoffset ))
+               local rootfs_size=$(( $data_offset - $rootfs_offset ))
+               local rootfs_hexsize=0x$( printf "%08x" "$rootfs_size" )
+
+               # scan for a 2nd uImage, if found, update failsafe
+               local failsafe_hexsize
+               local failsafe_blockoffset=$( platform_get_offset "$1" uImage 
$(( $data_blockoffset + 1 )) )
+               if [ -n "$failsafe_blockoffset" ]; then
+                       echo "Decteted a factory update package including the 
failsafe part"
+                       local failsafe_offset=$(( $data_blockoffset * $CI_BLKSZ 
))
+                       local failsafe_addr=$(( $firmware_base_addr + 
$failsafe_offset ))
+                       failsafe_hexaddr=0x$( printf "%08x" "$failsafe_addr" )
+                       failsafe_size=$(( $( platform_get_filesize "$1" ) - 
$failsafe_offset ))
+                       failsafe_hexsize=0x$( printf "%08x" "$failsafe_size" )
+                       # the usual JFFS2-append method to keep the config 
files can't be used in case of a factory image
+                       # if we really want it, we have to do it differently
+                       SAVE_CONFIG=0
+               fi
+
+               echo -n "Partitions in upgrade image: "
+               for part in vmlinux rootfs failsafe ; do
+                       eval b=\$${part}_blockoffset
+                       eval a=\$${part}_hexaddr
+                       eval s=\$${part}_hexsize
+                       [ -n "$b" ] && echo -n "$part (b#$b@$a,$s) "
+               done
+               echo
+               echo "Updating checksums and sizes in U-Boot environment"
+               local rootfs_md5=$( dd if="$1" bs=$CI_BLKSZ 
skip=$rootfs_blockoffset count=$rootfs_blockcount 2>/dev/null | md5sum -); 
rootfs_md5="${rootfs_md5%% *}"
+               local vmlinux_md5=$( dd if="$1" bs=$CI_BLKSZ 
skip=$vmlinux_blockoffset count=$vmlinux_blockcount 2>/dev/null | md5sum -); 
vmlinux_md5="${vmlinux_md5%% *}"
+               # this needs a recent version of uboot-envtools!
+               $fw_setenv -s - <<EOF
+vmlinux_start_addr $vmlinux_hexaddr
+vmlinux_size $vmlinux_hexsize
+vmlinux_checksum $vmlinux_md5
+rootfs_start_addr $rootfs_hexaddr
+rootfs_size $rootfs_hexsize
+rootfs_checksum $rootfs_md5
+bootcmd bootm $vmlinux_hexaddr
+$( [ -n "$failsafe_hexaddr" ] && echo "failsafe_boot bootm $failsafe_hexaddr" )
+EOF
+               default_do_upgrade "$@"
+       else
+               # update failsafe if we get a single uImage without rootfs
+               echo "updating failsafe partition"
+               failsafe_offset=$vmlinux_offset
+               failsafe_blockoffset=$vmlinux_blockoffset
+               failsafe_hexaddr=$( $fw_printenv failsafe_boot | while read 
_dontcare failsafe_hexaddr _dontcare2 ; do echo $failsafe_hexaddr ; done )
+               if [ -z "$failsafe_hexaddr" ]; then
+                       echo "no failsafe bootcmd defined in current U-Boot 
environment"
+                       return 1
+               fi
+               failsafe_addr=$( printf "%d" "$failsafe_hexaddr" )
+               failsafe_maxsize=$(( $( platform_get_firmware_size ) - ( 
$failsafe_addr - $firmware_base_addr ) ))
+               image_size=$(( $( platform_get_filesize "$1" ) - 
$failsafe_offset ))
+               if [ "$image_size" -gt "$failsafe_maxsize" ]; then
+                       echo "image to large ($failsafe_maxsize bytes allowed 
for failsafe)"
+                       return 1
+               fi
+               echo "writing $image_size bytes to failsafe@$failsafe_hexaddr"
+               dd bs=$CI_BLKSZ if=$1 skip=$failsafe_blockoffset 2>/dev/null | 
mtd write - failsafe
+       fi
+}
+
 platform_check_image() {
        local board=$(ar71xx_board_name)
        local magic="$(get_magic_word "$1")"
@@ -69,8 +235,64 @@
        [ "$ARGC" -gt 1 ] && return 1
 
        case "$board" in
+       all0258n )
+               # accept both, OpenWrt uImage or factory-dump starting with 
'custom' partition
+               [ "$magic" != "2705" -a "$magic_long" != "19852003" ] && {
+                       echo "Invalid image type."
+                       return 1
+               }
+               case "$magic" in
+                       2705)
+                               # OpenWrt uImage must have kernel and rootfs
+                               local vmlinux_blockoffset=$( 
platform_get_offset "$1" uImage )
+                               [ -z $vmlinux_blockoffset ] && {
+                                       echo "vmlinux-uImage not found"
+                                       return 1
+                               }
+                               local rootfs_blockoffset=$( platform_get_offset 
"$1" rootfs "$vmlinux_blockoffset" )
+                               [ -z $rootfs_blockoffset ] && {
+                                       echo "rootfs not found"
+                                       return 1
+                               }
+                               local data_blockoffset=$( platform_get_offset 
"$1" rootfs-data "$rootfs_blockoffset" )
+                               [ -z $data_blockoffset ] && {
+                                       echo "rootfs doesn't have JFFS2 end 
marker"
+                                       return 1
+                               }
+                       ;;
+                       1985)
+                               # Factory dump got a custom filesystem first
+                               local custom_blockoffset=$( platform_get_offset 
"$1" rootfs-data )
+                               [ -z $custom_blockoffset ] && {
+                                       echo "custom part not found"
+                                       return 1
+                               }
+                               local vmlinux_blockoffset=$( 
platform_get_offset "$1" uImage "$custom_blockoffset" )
+                               [ -z $vmlinux_blockoffset ] && {
+                                       echo "vmlinux-uImage not found"
+                                       return 1
+                               }
+                               local rootfs_blockoffset=$( platform_get_offset 
"$1" rootfs "$vmlinux_blockoffset" )
+                               [ -z $rootfs_blockoffset ] && {
+                                       echo "rootfs not found"
+                                       return 1
+                               }
+                               local data_blockoffset=$( platform_get_offset 
"$1" rootfs-data "$rootfs_blockoffset" )
+                               [ -z $data_blockoffset ] && {
+                                       echo "rootfs doesn't have JFFS2 end 
marker"
+                                       return 1
+                               }
+                               local failsafe_blockoffset=$( 
platform_get_offset "$1" uImage "$data_blockoffset" )
+                               [ -z $failsafe_blockoffset ] && {
+                                       echo "failsafe-uImage not found"
+                                       return 1
+                               }
+                       ;;
+               esac
+               return 0
+               ;;
        ap121 | ap121-mini | ap96 | db120 | zcn-1523h-2 | zcn-1523h-5)
-               [ "$magic" != "68737173" -a "$magic" != "19852003" ] && {
+               [ "$magic_long" != "68737173" -a "$magic_long" != "19852003" ] 
&& {
                        echo "Invalid image type."
                        return 1
                }
@@ -141,6 +363,10 @@
        routerstation | routerstation-pro | ls-sr71 | eap7660d | ja76pf )
                platform_do_upgrade_combined "$ARGV"
                ;;
+       all0258n )
+               local firmware_phys_addr=0x9f050000
+               platform_do_upgrade_uboot $firmware_phys_addr "$ARGV"
+               ;;
        *)
                default_do_upgrade "$ARGV"
                ;;
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to