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

Archive Download this file



interactive