i.MX 8MQ - ROM Redundant Boot for expansion device

Showing results for 
Search instead for 
Did you mean: 

i.MX 8MQ - ROM Redundant Boot for expansion device

i.MX 8MQ - ROM Redundant Boot for expansion device

Tips collected from zhaoyang-b49593 and dandouglass-b41520 while enabling redundant boot:

Using i.MX 8MQ, same method can be applied for other i.MX devices that support redundant boot, see SoC Reference Manual.

As described on the RM, if primary image authentication fails the ROM can reset and try booting a secondary image.

This feature is only available on closed mode with properly signed binaries, otherwise the ROM boots the primary image despite the auth failure.


For the i.MX 8MQ, the secondary image must start with spl, not HDMI firmware.

Note, there is no ROM redundancy for the hdmi fw, if it is corrupt user can store a 2nd copy on a different memory address and update at run time.

Steps to generate a dual spl image:

1. Build and Sign bootable binary (spl, u-boot, atf, fw, etc)

Use the Yocto BSP or follow this post to build outside the Yocto environment.

To sign the binary, follow the documentation on u-boot source:


Program image to the SD card:

dd if=signed_flash.bin of=<sd path> bs=1024 seek=33

After boot you can use "hab_status" to verify that no events were generated:

u-boot=> hab_status

Secure boot disabled

HAB Configuration: 0xf0, HAB State: 0x66

2. Corrupt spl on your boot image

You can corrupt anywhere on the spl signed area.
For easier visualization at boot time we can corrupt the SPL banner.

First create a copy:

cp signed_flash.bin signed_flash_corrupt.bin

Find the banner:

hexdump -C signed_flash.bin | grep 2019
00020190 26 1c 40 92 04 00 80 d2 05 01 80 52 c4 20 04 aa |&.@........R. ..|
0002eac0 32 30 31 39 2e 30 34 2d 30 30 30 32 39 2d 67 34 |2019.04-00029-g4|
000dde10 3a 20 20 00 55 2d 42 6f 6f 74 20 32 30 31 39 2e |: .U-Boot 2019.|

0002eac3 is on spl area, where "9" for 2019 is, replace by "X"

printf "X" > X
dd if=X of=signed_flash_corrupt.bin seek=$((0x2eac3)) bs=1 conv=notrunc

Verify corrupt binary

hexdump -C -s 0x2eac0 -n 64 signed_flash_corrupt.bin
0002eac0 32 30 31 58 2e 30 34 2d 30 30 30 32 39 2d 67 34 |201X.04-00029-g4|
0002ead0 37 63 31 39 32 32 20 28 41 70 72 20 32 37 20 32 |7c1922 (Apr 27 2|

Transfer image to SD Card

dd if=signed_flash_corrupt.bin of=<sd path> bs=1024 seek=33

Now, you should see hab events after running "hab_status" on u-boot

3. Create a secondary boot image

This can be the same content as your primary image without the HDMI fw or it can be a different spl image.

For easier visualization, we can change the SPL banner, on the code this time.

Modify banner at ./common/spl/spl.c as:

- puts("\nU-Boot " SPL_TPL_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - "
+ puts("\nSecondary U-Boot " SPL_TPL_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - "

As mentioned above, we want our boot image without the HDMI fw, when running imx-mkimage use the flash_evk_no_hdmi target:

make SOC=iMX8MQ flash_evk_no_hdmi

Sign the image as in step 1.

If you program the new image to the SD you should see the new banner.
Make sure to run hab_status to confirm that no HAB events are generated.

4. Program SRK Hash and Close SoC

Follow the documentation on u-boot source for SRK programming and closing the device:


Before closing the SoC, but after the SRK is programmed, try your images to confirm no HAB events are generated.

Be careful with this step, errors could brick your board. This step is irreversible. After closing the SoC it will only boot signed images.

5. Create dual bootloader image

We can concatenate our binaries to create a single file, let's use 2MB distance between primary and secondary images:

For the working primary image:

objcopy -I binary -O binary --pad-to 0x200000 --gap-fill=0x00 signed_flash.bin 1st-spl_pad.bin
cat 1st-spl_pad.bin secondary2_nohdmifw_signed_flash.bin > 1st-spl_pad_2nd-spl.bin

Or for the corrupt primary image experiment:

objcopy -I binary -O binary --pad-to 0x200000 --gap-fill=0x00 signed_flash_corrupt.bin 1st-spl_pad.bin
cat 1st-spl_pad.bin secondary2_nohdmifw_signed_flash.bin > 1st-spl_pad_2nd-spl.bin

Program it to the SD card on 0x8400 offset (33k)

dd if=1st-spl_pad_2nd-spl.bin of=<sd path> bs=1024 seek=33 && sync

6. Add Secondary image table

Follow the format on the RM, this is only 20 bytes long.

For a 2MB distance between the table and the secondary image we can use "0x1000" on the firstSectorNumber field.
2MB/512 = 4096 (0x1000)

The perl script attached, genSecTable.pl, can be used to generate it.

perl genSecTable.pl 0x1000

Program it to the SD card on 0x8200 offset

dd if=secTable.bin of=<sd path> bs=1 seek=$((0x8200)) && sync

7. Verify secondary image is booting

If using the corrupt primary image, you should see the spl with the "Secondary U-Boot SPL..." banner.
You can also read the persist secondary boot bit.

u-boot=> md.l 0x30390098 1
30390098: 40000000 ...@

The work can be extended patching spl for in case of u-boot authentication failure, spl can try to authenticate and jump to the secondary u-boot.

Labels (1)

Would you provide a tutorial or documentation  for using redundant boot on an imx8mm with an emmC memory using Android 9?

Version history
Revision #:
2 of 2
Last update:
‎09-10-2020 02:59 AM
Updated by: