'iMX6 get U-Boot to temporarily boot another U-Boot

First some background:

We have the following setup in our iMX6-based embedded system. There are two U-Boot partitions and two system (Linux) partitions. Currently we use only the first U-Boot partition and it uses a standard method for selecting, running and (if need be) rolling back the system partitions.

We are now looking into a similar scheme for upgrading U-Boot itself (this will happen very rarely but we do want the ability to do this without having to return the devices to base).

However, this is more fraught with danger because, once you tell the iMX6 device to boot from the alternate U-Boot partition, that's it - there's no U-Boot/watchdog combo that will revert to the previous one if boot fails, so a bad update runs a serious risk of bricking the device until we can return it to base for repair (a costly option which is why we're trying to mitigate it as much as possible).

The method chosen is a two-step U-Boot install procedure, consisting of 'write' and 'activate'. It relies on our ability to successfully figure out which U-Boot partition will be run if the device reboots (the selected one) and which is currently being run (the booted one). We've got this bit sorted out already.

But the bit that we're missing is the ability for UBoot to transfer control to the other UBoot partition under some circumstances. We got it doing different actions based solely on the UBoot environment as follows:

First, mmcboot has a prefix added so that it checks for the control transfer, specifically it's set to run ub_xfer_chk ; <original content of mmcboot>.

Secondly, we have a variable ub_xfer_flag normally set to 0.

Thirdly, we have the checking function ub_xfer_chk, defined as:

if test ${ub_xfer_flag} -eq 1 ; then
    echo Soft-booting other UBoot...
    setenv ub_xfer_flag 0
    saveenv
    weave_magic
fi

The weave_magic code is where we are having trouble :-) The idea is that this will load the other UBoot partition into memory (at our CONFIS_SYS_TEXT_BASE of 0x1780000) and execute it as if the actual device had done it.

We've tested the meat of this solution by using reset in place of weave_magic and it successfully restarts the device once, so we're certain we can make it safe.


My specific question then is :how can I convince U-Boot to load a second copy from another partition and run it?

The two UBoot partitions live in the /dev/mmcblk3boot0 and /dev/mmcblk3boot1 devices accessible from the system partition and are 2M files, including the 1K lead-in header and a fair bit of padding at the end.


Update:

We have actually had some success and managed to load an IMX image from the boot partition with the command:

ext4load mmc ${mmcdev}:${mmcpart} 0x17800000 ${bootdir}/u-boot.imx

but, when trying to execute it with:

go 0x17800000

we get an illegal instruction and immediate reboot:

pc : [<17800070>]          lr : [<4ff83c64>]
sp : 4f579ac0  ip : 00000030     fp : 4f57be58
r10: 00000002  r9 : 4f579efc     r8 : 4ffbe2b0
r7 : 4f57be68  r6 : 17800000     r5 : fffff200  r4 : 000002cc
r3 : 17800000  r2 : 4f57be6c     r1 : 4f57be6c  r0 : 00000000
Flags: nZCv  IRQs off  FIQs off  Mode SVC_32
Resetting CPU ...

So I'm guessing that's not executable code at the start of that file. Any ideas on where to go from here?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source