ar71xx: add support for RB951Ui-2nD
[openwrt/staging/wigyori.git] / target / linux / ar71xx / base-files / lib / upgrade / allnet.sh
1 # The U-Boot loader of the some Allnet devices requires image sizes and
2 # checksums to be provided in the U-Boot environment.
3 # In case the check fails during boot, a failsafe-system is started to provide
4 # a minimal web-interface for flashing a new firmware.
5
6 # make sure we got uboot-envtools and fw_env.config copied over to the ramfs
7 # create /var/lock for the lock "fw_setenv.lock" of fw_setenv
8 platform_add_ramfs_ubootenv() {
9 [ -e /usr/sbin/fw_printenv ] && install_bin /usr/sbin/fw_printenv /usr/sbin/fw_setenv
10 [ -e /etc/fw_env.config ] && install_file /etc/fw_env.config
11 mkdir -p $RAM_ROOT/var/lock
12 }
13 append sysupgrade_pre_upgrade platform_add_ramfs_ubootenv
14
15 # determine size of the main firmware partition
16 platform_get_firmware_size() {
17 local dev size erasesize name
18 while read dev size erasesize name; do
19 name=${name#'"'}; name=${name%'"'}
20 case "$name" in
21 firmware)
22 printf "%d" "0x$size"
23 break
24 ;;
25 esac
26 done < /proc/mtd
27 }
28
29 # get the first 4 bytes (magic) of a given file starting at offset in hex format
30 get_magic_long_at() {
31 dd if="$1" skip=$(( $CI_BLKSZ / 4 * $2 )) bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
32 }
33
34 get_filesize() {
35 wc -c "$1" | while read image_size _n ; do echo $image_size ; break; done
36 }
37
38 # scan through the update image pages until matching a magic
39 platform_get_offset() {
40 offsetcount=0
41 magiclong="x"
42 if [ -n "$3" ]; then
43 offsetcount=$3
44 fi
45 while magiclong=$( get_magic_long_at "$1" "$offsetcount" ) && [ -n "$magiclong" ]; do
46 case "$magiclong" in
47 "2705"*)
48 # U-Boot image magic
49 if [ "$2" = "uImage" ]; then
50 echo $offsetcount
51 return
52 fi
53 ;;
54 "68737173"|"73717368")
55 # SquashFS
56 if [ "$2" = "rootfs" ]; then
57 echo $offsetcount
58 return
59 fi
60 ;;
61 "deadc0de"|"19852003")
62 # JFFS2 empty page
63 if [ "$2" = "rootfs-data" ]; then
64 echo $offsetcount
65 return
66 fi
67 ;;
68 esac
69 offsetcount=$(( $offsetcount + 1 ))
70 done
71 }
72
73 platform_check_image_allnet() {
74 local fw_printenv=/usr/sbin/fw_printenv
75 [ ! -n "$fw_printenv" -o ! -x "$fw_printenv" ] && {
76 echo "Please install uboot-envtools!"
77 return 1
78 }
79
80 [ ! -r "/etc/fw_env.config" ] && {
81 echo "/etc/fw_env.config is missing"
82 return 1
83 }
84
85 local image_size=$( get_filesize "$1" )
86 local firmware_size=$( platform_get_firmware_size )
87 [ $image_size -ge $firmware_size ] &&
88 {
89 echo "upgrade image is too big (${image_size}b > ${firmware_size}b)"
90 }
91
92 local vmlinux_blockoffset=$( platform_get_offset "$1" uImage )
93 [ -z $vmlinux_blockoffset ] && {
94 echo "vmlinux-uImage not found"
95 return 1
96 }
97
98 local rootfs_blockoffset=$( platform_get_offset "$1" rootfs "$vmlinux_blockoffset" )
99 [ -z $rootfs_blockoffset ] && {
100 echo "missing rootfs"
101 return 1
102 }
103
104 local data_blockoffset=$( platform_get_offset "$1" rootfs-data "$rootfs_blockoffset" )
105 [ -z $data_blockoffset ] && {
106 echo "rootfs doesn't have JFFS2 end marker"
107 return 1
108 }
109
110 return 0
111 }
112
113 platform_do_upgrade_allnet() {
114 local firmware_base_addr=$( printf "%d" "$1" )
115 local vmlinux_blockoffset=$( platform_get_offset "$2" uImage )
116 if [ ! -n "$vmlinux_blockoffset" ]; then
117 echo "can't determine uImage offset"
118 return 1
119 fi
120 local rootfs_blockoffset=$( platform_get_offset "$2" rootfs $(( $vmlinux_blockoffset + 1 )) )
121 local vmlinux_offset=$(( $vmlinux_blockoffset * $CI_BLKSZ ))
122 local vmlinux_addr=$(( $firmware_base_addr + $vmlinux_offset ))
123 local vmlinux_hexaddr=0x$( printf "%08x" "$vmlinux_addr" )
124 if [ ! -n "$rootfs_blockoffset" ]; then
125 echo "can't determine rootfs offset"
126 return 1
127 fi
128 local rootfs_offset=$(( $rootfs_blockoffset * $CI_BLKSZ ))
129 local rootfs_addr=$(( $firmware_base_addr + $rootfs_offset ))
130 local rootfs_hexaddr=0x$( printf "%08x" "$rootfs_addr" )
131 local vmlinux_blockcount=$(( $rootfs_blockoffset - $vmlinux_blockoffset ))
132 local vmlinux_size=$(( $rootfs_offset - $vmlinux_offset ))
133 local vmlinux_hexsize=0x$( printf "%08x" "$vmlinux_size" )
134 local data_blockoffset=$( platform_get_offset "$2" rootfs-data $(( $rootfs_blockoffset + 1 )) )
135 if [ ! -n "$data_blockoffset" ]; then
136 echo "can't determine rootfs size"
137 return 1
138 fi
139 local data_offset=$(( $data_blockoffset * $CI_BLKSZ ))
140 local rootfs_blockcount=$(( $data_blockoffset - $rootfs_blockoffset ))
141 local rootfs_size=$(( $data_offset - $rootfs_offset ))
142 local rootfs_hexsize=0x$( printf "%08x" "$rootfs_size" )
143
144 local rootfs_md5=$( dd if="$2" bs=$CI_BLKSZ skip=$rootfs_blockoffset count=$rootfs_blockcount 2>/dev/null | md5sum -); rootfs_md5="${rootfs_md5%% *}"
145 local vmlinux_md5=$( dd if="$2" bs=$CI_BLKSZ skip=$vmlinux_blockoffset count=$vmlinux_blockcount 2>/dev/null | md5sum -); vmlinux_md5="${vmlinux_md5%% *}"
146 # this needs a recent version of uboot-envtools!
147 cat >/tmp/fw_env_upgrade <<EOF
148 vmlinux_start_addr $vmlinux_hexaddr
149 vmlinux_size $vmlinux_hexsize
150 vmlinux_checksum $vmlinux_md5
151 rootfs_start_addr $rootfs_hexaddr
152 rootfs_size $rootfs_hexsize
153 rootfs_checksum $rootfs_md5
154 bootcmd bootm $vmlinux_hexaddr
155 EOF
156 fw_setenv -s /tmp/fw_env_upgrade || {
157 echo "failed to update U-Boot environment"
158 return 1
159 }
160 shift
161 default_do_upgrade "$@"
162 }