Updating U-Boot on iMX8 without Toradex Easy Installer

The TorizonCore Yocto build generates a U-Boot image (/workdir/torizon/build-torizon-rt/deploy/images/apalis-imx8/u-boot-sd-2020.04-r0.bin). I would like to update U-Boot on the eMMC using this build artifact. Furthermore, I would like to do so via either U-Boot commands (e.g., mmc write) or Linux commands (e.g., dd), rather than Toradex Easy Installer. My use case is OTA updates of the bootloader and I’m not aware of a straightforward path to do this with Easy Installer.

I got the impression from reading Build U-Boot and Linux Kernel page that this was possible in the past but no longer supported for the newer TorizonCore OS on i.MX8. (I’ve seen some mention of a legacy ‘update.sh’ script. There also appears to be a “update_uboot” command defined in the i.MX8 U-Boot environment, but it expects you to have loaded a file called “u-boot-dtb.imx”.)

I’m trying to understand what image I have to work with and what Easy Installer is doing under the hood. Is the u-boot-sd-2020.04-r0.bin image in a form suitable for programming to the eMMC or does it need to be modified? The latter link above explains that the i.MX8 requires the image be wrapped in a boot container. Is that already being handled by the Yocto build?

I’m not adverse to rebuilding U-Boot myself and packaging it with the correct boot container (per the instructions on the page linked above). But once I have a suitable artifact, where should it be written? To the beginning of /dev/mmcblk0boot0 as described here?

You can modify json file as described here and flash just a boot container using Toradex Easy installer.

If you need an OTA why don’t use an existing Torizon OTA solution?

Thanks @alex.tx, I’ll definitely take a look at the Toradex Easy Installer json configuration. That will be handy for device manufacturing. And yes, we’re planning to use Torizon OTA to update the OS and application containers.

However, I’m still curious about how to flash U-Boot over-the-air. Our application may involve some custom U-Boot code and we want to be able to remotely update U-Boot in rare circumstances (despite the risks of bricking the device if the update fails).

I was under the impression that Torizon OTA did not support updates to U-Boot. Perhaps I am just missing something. The Torizon OTA Technical Overview page says it can update bootloader configuration, which is stored in the file system and managed by OSTree, but I didn’t see anything about flashing a new bootloader binary.

Or maybe I’m missing something about Toradex Easy Installer. Can you configure Easy Installer to run on the next boot and automatically apply the update, rather than having to load it via USB OTG?

Hi @dcullen, bootloader updates are not a feature of Torizon OTA at the moment but it is a planned feature. Do you have a specific timeline when you will need that?

Drew

Hi @dcullen . No you can’t configure Easy Installer to run on a next boot. But you can try to replace a boot container. It located at eMMC boot partition mmcblk0boot0 as a blob (no FS). It available under Linux as a /dev/mmcblk0boot0.

Hi @drew.tx, we are still in early development and won’t need that functionality for another 6 to 12 months, but I wanted to make sure we had a path forward to mitigate some project risk. It’s great to hear this is a planned feature. In the meantime, I will continue to experiment with this manual approach-- overwriting the boot container. Thanks!

Thanks @alex.tx! That’s what I was looking for. It’s good to have some assurance that this might be a viable path. I’ll post some instructions if I am successful.

I succeeded in flashing the iMX8 u-boot image from Linux!

It turns out that u-boot-sd-2020.04-r0.bin was the wrong image because it is missing the boot container piece. Instead you must use imx-boot-apalis-imx8-sd.bin-flash_b0, which appears to be the U-Boot image wrapped with the iMX8 boot container. (This file is available in the TorizonCore Yocto build output directory.)

I also discovered you must first unlock the eMMC by updating /sys/block/mmcblk0boot0/force_ro as discussed in this post; otherwise the dd command will fail with an “Operation not permitted” error.

Here is the complete set of commands for unlocking the eMMC and writing U-Boot:

apalis-imx8-06805224:~$ sudo echo 0 > /sys/block/mmcblk0boot0/force_ro
apalis-imx8-06805224:~$ sudo dd if=imx-boot-apalis-imx8-sd.bin-flash_b0 of=/dev/mmcblk0boot0
2482+0 records in
2482+0 records out
1270784 bytes (1.3 MB, 1.2 MiB) copied, 0.141241 s, 9.0 MB/s

Then you can reboot and observe the U-Boot version string in the serial console output to confirm the change was successful.

I later discovered that the image-torizon-core-docker.json file (also in the Yocto output directory), which is used by Toradex Easy Installer, gives a pretty good hint about where the images need to be written:

...
{
    "name": "mmcblk0boot0",
    "erase": true,
    "content": {
        "filesystem_type": "raw",
        "rawfiles": [
            {
                "filename": "imx-boot",
                "dd_options": "seek=0"
            }
        ]
    }
}
...

Noting, of course, that imx-boot is actually a symlink to imx-boot-apalis-imx8-sd.bin-flash_b0.

I’m a bit embarrassed it took me this long to figure out, but many thanks for pointing me in the right direction!

1 Like

Thanks for sharing your findings this is useful information for the community!

Thanks for the guide @dcullen.

I can confirm this also works for the Verdin IMX8MM, but it’s important to add the ‘seek=2’ option to the dd command, as indicated by the image.json file (says “seek=2” in my case). If you forget that option, it’s recovery mode time. So for anyone else, confirm not only the boot device name but also the dd options in your image.json file.