1 # The U-Boot loader with the datachk patchset for dualbooting requires image
2 # sizes and checksums to be provided in the U-Boot environment.
3 # The devices come with 2 main partitions - while one is active
4 # sysupgrade will flash the other. The boot order is changed to boot the
5 # newly flashed partition. If the new partition can't be booted due to
6 # upgrade failures the previously used partition is loaded.
8 platform_do_upgrade_dualboot_datachk
() {
11 local primary_kernel_mtd
13 local setenv_script
="/tmp/fw_env_upgrade"
15 local kernel_mtd
="$(find_mtd_index $PART_NAME)"
16 local kernel_offset
="$(cat /sys/class/mtd/mtd${kernel_mtd}/offset)"
17 local total_size
="$(cat /sys/class/mtd/mtd${kernel_mtd}/size)"
19 # detect to which flash region the new image is written to.
21 # 1. check what is the mtd index for the first flash region on this
23 # 2. check if the target partition ("inactive") has the mtd index of
24 # the first flash region
26 # - when it is: the new bootseq will be 1,2 and the first region is
28 # - when it isnt: bootseq will be 2,1 and the second region is
31 # The detection has to be done via the hardcoded mtd partition because
32 # the current boot might be done with the fallback region. Let us
33 # assume that the current bootseq is 1,2. The bootloader detected that
34 # the image in flash region 1 is corrupt and thus switches to flash
35 # region 2. The bootseq in the u-boot-env is now still the same and
36 # the sysupgrade code can now only rely on the actual mtd indexes and
37 # not the bootseq variable to detect the currently booted flash
40 # In the above example, an implementation which uses bootseq ("1,2") to
41 # detect the currently booted image would assume that region 1 is booted
42 # and then overwrite the variables for the wrong flash region (aka the
43 # one which isn't modified). This could result in a device which doesn't
44 # boot anymore to Linux until it was reflashed with ap51-flash.
45 local next_boot_part
="1"
46 case "$(board_name)" in
56 echo "failed to detect primary kernel mtd partition for board"
60 [ "$kernel_mtd" = "$primary_kernel_mtd" ] || next_boot_part
="2"
62 local board_dir
=$
(tar tf
$tar_file |
grep -m 1 '^sysupgrade-.*/$')
63 board_dir
=${board_dir%/}
65 local kernel_length
=$
(tar xf
$tar_file ${board_dir}/kernel
-O |
wc -c)
66 local rootfs_length
=$
(tar xf
$tar_file ${board_dir}/root
-O |
wc -c)
67 # rootfs without EOF marker
68 rootfs_length
=$
((rootfs_length-4
))
70 local kernel_md5
=$
(tar xf
$tar_file ${board_dir}/kernel
-O |
md5sum); kernel_md5
="${kernel_md5%% *}"
71 # md5 checksum of rootfs with EOF marker
72 local rootfs_md5
=$
(tar xf
$tar_file ${board_dir}/root
-O |
dd bs
=1 count
=$rootfs_length |
md5sum); rootfs_md5
="${rootfs_md5%% *}"
75 # add tar support to get_image() to use default_do_upgrade() instead?
78 # take care of restoring a saved config
79 [ -n "$UPGRADE_BACKUP" ] && restore_backup
="${MTD_CONFIG_ARGS} -j ${UPGRADE_BACKUP}"
82 tar xf
$tar_file ${board_dir}/root
-O | mtd
-n -p $kernel_length $restore_backup write - $PART_NAME
83 tar xf
$tar_file ${board_dir}/kernel
-O | mtd
-n write - $PART_NAME
85 # prepare new u-boot env
86 if [ "$next_boot_part" = "1" ]; then
87 echo "bootseq 1,2" > $setenv_script
89 echo "bootseq 2,1" > $setenv_script
92 printf "kernel_size_%i 0x%08x\n" $next_boot_part $kernel_length >> $setenv_script
93 printf "vmlinux_start_addr 0x%08x\n" ${kernel_offset} >> $setenv_script
94 printf "vmlinux_size 0x%08x\n" ${kernel_length} >> $setenv_script
95 printf "vmlinux_checksum %s\n" ${kernel_md5} >> $setenv_script
97 printf "rootfs_size_%i 0x%08x\n" $next_boot_part $
((total_size-kernel_length
)) >> $setenv_script
98 printf "rootfs_start_addr 0x%08x\n" $
((kernel_offset
+kernel_length
)) >> $setenv_script
99 printf "rootfs_size 0x%08x\n" ${rootfs_length} >> $setenv_script
100 printf "rootfs_checksum %s\n" ${rootfs_md5} >> $setenv_script
102 # store u-boot env changes
104 fw_setenv
-s $setenv_script ||
{
105 echo "failed to update U-Boot environment"