Flashing U-Boot bricked Verdin iMX8MP board

Model: Toradex Verdin iMX8M Plus Quad 4GB Wi-Fi / BT IT V1.0D, Serial# 06965633
Carrier: Toradex Verdin Development Board V1.1B, Serial# 10893438
Image: Torizon Minimal 7.x.y

I built an extended torizon-minimal image with tdx-signed enabled for integrity checks of U-Boot and Linux kernel. U-Boot hardening is enabled. The image booted successfully. I could see from the messages that all the integrity checks worked fine.

My next idea was to make the integrity check for U-Boot fail. I expected to see some HAB events (I have flashed the SRKs to the efuses but not closed the device). I set up my test as follows.

I copied /dev/mmcblk2boot0 into a filie: dd if=/dev/mmcblk2boot0 of=mmcblk2boot0.

I changed the date Jan 01 1970 in the “U-Boot 2024.07” messages into Jan 01 2025 with ghex on my host computer.

I installed the modified U-Boot into the second boot partition /dev/mmcblk2boot1, which is empty (all zeros) by default. Then, I made the board boot from the second partition. Here are the commands:

echo 0 > /sys/class/block/mmcblk2boot1/force_ro
dd if=mmcblk2boot0-mod of=/dev/mmcblk2boot1
echo 1 > /sys/class/block/mmcblk2boot1/force_ro
mmc bootpart enable 2 0 /dev/mmcblk2

Rebooting the board with the same image from before failed. I didn’t see a single boot message. Nothing.

I used TEZI to install several different standard images including Torizon Easy Pairing and Toradex Multimedia Reference Image. Fortunately, TEZI was and is working in recovery mode. TEZI diligently installed the images. But still not single message after rebooting.

Then, I used the Linux prompt of the TEZI image to switch the board to booting from partition 1 again: mmc bootpart enable 1 0 /dev/mmcblk2. Still not a single boot message.

I installed the original empty U-Boot image in the second partition and switched the board to booting from the first partition /dev/mmcblk2boot0. Nothing changed with different images installed via TEZI.

I finally installed the original U-Boot image into the first boot partition mmcblk2boot0 (I kept a copy). After installing the standard Toradex Multimedia Reference image with TEZI and rebooting, I got the following the messages:

U-Boot SPL 2022.04-6.8.3+git.75060d6a4c97 (May 19 2025 - 09:27:16 +0000)
DDRINFO: start DRAM init
DDRINFO: DRAM rate 4000MTS
Training FAILED
DDRINFO: start DRAM init
DDRINFO: DRAM rate 4000MTS
DDRINFO:ddrphy calibration done
DDRINFO: ddrmix config done
DDR configured as single rank
SEC0:  RNG instantiated
Normal Boot
WDT:   Started watchdog@30280000 with servicing (60s timeout)
Trying to boot from BOOTROM
Boot Stage: Primary boot
Can't found uboot image in 640K range
SPL: failed to boot from all boot devices
### ERROR ### Please RESET the board ###

Resetting the board doesn’t help. There are no messages after pressing the RESET hardware button.

How can I install working U-Boot images in the bootloader partitions and re-animate my board?

It seems that TEZI doesn’t install a bootloader. Is that right?

How can I install a tampered U-Boot to test a failing integrity check? What did I do wrong?

Many thanks for your help,
Burkhard

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


(1), (2), (3), (4), (5)

Understanding Your Situation

Your board is in a state where the bootloader has been corrupted or modified, preventing proper boot. The error message “Can’t found uboot image in 640K range” indicates that the ROM code cannot find a valid U-Boot image in the expected location.

Recovery Steps

1. Use Toradex Easy Installer to Restore Bootloader

The Toradex Easy Installer (TEZI) does install bootloaders when flashing complete images. From the documentation, TEZI is designed to handle complete system installation including bootloader components (2).

To recover your board:

  1. Enter Recovery Mode: Put your Verdin iMX8M Plus into recovery mode following the specific procedure for your carrier board (2)

  2. Load TEZI: Use the recovery scripts to load TEZI into RAM (2):

    ./recovery-linux.sh    # On Linux
    recovery-windows.bat   # On Windows
    
  3. Flash Complete Image: Install a complete Torizon image through TEZI, which will restore both the bootloader and the operating system

2. Understanding Boot Partition Management

The issue occurred because you modified the bootloader in a way that corrupted the boot process. When you:

  • Modified the U-Boot binary directly
  • Switched between boot partitions
  • The ROM code couldn’t validate or execute the modified bootloader

3. Testing HAB Integrity Checks Safely

For testing HAB failures without bricking your device, consider these approaches:

Option A: Use TEZI Recovery Method

Since you can still access TEZI in recovery mode, you can:

  1. Flash a known-good image first
  2. Make controlled modifications to test HAB
  3. Always keep the ability to recover via TEZI

Option B: Modify TEZI Image for Testing

You can create a modified TEZI image for testing purposes (3). The process involves:

  1. Extracting the TEZI image components using dumpimage (3)
  2. Modifying specific components
  3. Rebuilding the image with proper signatures

Immediate Recovery Solution

  1. Download Fresh TEZI: Get the appropriate TEZI image for your Verdin iMX8M Plus from the Toradex downloads

  2. Enter Recovery Mode: Follow the recovery procedure for your specific carrier board configuration (2)

  3. Load and Flash: Use the recovery scripts to load TEZI and flash a complete, unmodified Torizon image

  4. Verify Boot: Ensure the system boots properly before attempting further modifications

Prevention for Future Testing

When testing secure boot features:

  • Always maintain a recovery path via TEZI
  • Test modifications on the secondary boot partition first
  • Keep backups of working bootloader images
  • Consider using the HAB status commands to verify integrity without modifying binaries

The key point is that TEZI does install bootloaders as part of complete image flashing, so using it for recovery should restore your board to a working state.

Best regards, Toradex AI Assistant.

I have installed several different standard images on my board with TEZI. If TEZI installs a bootloader (as I would expect), my board should boot again. But it doesn’t!

I can see one other reason, why the board doesn’t boot. U-Boot hardening prevents the board from booting. This shouldn’t happen, if I install a correctly signed image on the board with TEZI. So, how can I undo the U-Boot hardening?

Hi Burkhard,

Before going into the topic of how to validate the integrity check, let’s try to understand what’s preventing your device from booting, shall we?

First of all, let me confirm that TEZI does install the bootloader. So, almost everything that you’ve done to the device should be fixed/undone by TEZI. Some things not necessarily undone by TEZI that come to mind:

  • The fuse programming (of course).
  • The selection of the current partition on the MMC register: only sufficiently new versions of the installer are able to reset the current partition; please be sure to use the latest version of TEZI for your device.
  • Some data stored at the end of the boot partition that is normally programmed by Toradex (config block).

Since your device is still open in terms of secure boot, the fusing shouldn’t be preventing the loading/execution of U-Boot. The corruption of the config block could cause issues but I don’t think it would prevent the U-Boot from running either.

Another point is that the hardening is related to the second link of the chain of trust (bootloader => kernel) such that it can only prevent a tampered kernel from being executed. It has no impact on the loading/execution of U-Boot itself. Also, the hardening is code that is part of U-Boot so that there are not long standing changes on the device due to the execution of a hardened U-Boot.

Therefore, it seems we don’t have many options to explore. My suggestion would be for you to copy (again) the original contents of mmcblk2boot0 to that partition on the device (to restore the config block) and then repeat an OS installation using the latest version of Toradex Easy Installer.

Hi,

I think your issue might be due to the manual changes of u-boot files.
From my head the u-boot is also verified as part of the secure-boot process.

I am not sure if TEZI will already do this, but you need to reset the board so that the original bootloader is loaded.
In the short term as you are likely unable to reflash the boot1 partition, you could manually update the TEZI image manifest.json so that it writes the same bootloader to the second boot partition (pretty much a copy and paste of some json text).
With the modified TEZI manifest you should be able to flash the device normally and restore the bootloader.
After booting you should then be able to reset the system to use boot0.

This is essentially what I do as part of my swupdate image as we have a patch to enable dual-boot in an imx8mp verdin module.

Hope this helps.

Regards,
Izzy

Hi @rogerio.tx,

Thank you for your detailed answer.

As suggested, I copied the original contents back to /dev/mmcblk2boot0 with dd and ran the latest TEZI 7.3.0+build.7.

The problem with TEZI versions 6 and 7 on my board is that the GUI isn’t displayed. I have reported that in an earlier support request GUI displayed for TEZI version 5, but not for versions 6 and 7. The problem still persists.

As I don’t have the GUI, I configured TEZI for auto-installation, auto-confirmation of the license and auto-reboot in image.json. TEZI seems to do something as eventually the board shuts down with the following messages:

[  104.366426] imx2-wdt 30280000.watchdog: Device shutdown.
[  104.373013] reboot: Restarting system

However, the board does not restart. There are no messages in the serial console.

I tried the same with TEZI 5.7.6+build.21. Both the manual and the automatic installation yielded the same results.

Is there any way that I can install a standard U-Boot and rootfs image manually from the Linux prompt of the TEZI image? dd’ing imx-boot from the TEZI tarball or my original mmcblk2boot0 into /dev/mmcblk2boot0 doesn’t work.

Thanks, Burkhard

Hi Izzy,

Thank you very much for your suggestion.

I changed the boot device name in image.json from emmc-boot0 to emmc-boot1 and also changed the boot partition to /dev/emmc-boot1 (a link to /dev/mmcblk2boot0) before rebooting.

The board shuts down but never reboots. I don’t see a single boot messages in the serial console :frowning:

It seems that there is something seriously wrong with my SoM.

Cheers,
Burkhard

@bstubert

Can you share your full image.json file?
I am not sure if that is the same change I was thinking of.
I am back in the office tomorrow and will try to dig out what our image.json file looks like as that may help.

By default the TEZI image only writes to a single boot partition.
What we have done is added the same image to be written to the second one in addition.

I think what you’re seeing is that the image in boot-1 is invalid and that is why it’s not loading.
But if the TEZI image can write a new good u-boot (without any modifications) into that partition it should load again.

Once in u-boot you can then reset which boot partition to use. However, I believe it requires a working u-boot image first to be able to do that.

Regards,
Izzy

Hi @bstubert,

The latest TEZI in the 5 series should be able to properly reset the boot partition and, since you tried with that version, there’s probably some other issue with your device.

Since you have a copy of the original contents of the boot partition, you could try something a bit more dramatic:

  • Zero out both boot partitions (running dd if=/dev/zero of=<part> on each one).
  • Run TEZI 5 and try to install your signed image again. Due to the above step, TEZI will ask you some information in order for it to set up the config block (in particular the serial number of the device).

If this doesn’t work you could run TEZI again and through its shell, dd the imx-boot binary directly into the boot partition, but the binary should be the one from a installable image (e.g. your signed image (that you could put into a USB stick) or even a stock image from Toradex). The imx-boot from TEZI itself won’t work because that one is designed to be loaded via SDP. However, I believe this is unlikely to work, because TEZI is already supposed to perform that dd operation.

Is there any way that I can install a standard U-Boot and rootfs image manually from the Linux prompt of the TEZI image?

Unfortunately, at the moment there’s no way for you to perform the full installation only through the Linux prompt.

Well, if none of the above works, then I think we’ll probably need to try to repeat your steps on one of our devices to see if we can replicate the issue. Please let us know.

Hi Rogerio,

NOTE: I am away from my board until September 5. So, I can’t try out things at the moment. Please bear with me.

Good to know that the latest TEZI from version 5 should work.

I’ll zero out both boot partitions and try again. So far, I only zeroed out mmcblk2boot1 and dd’ed the original image into mmcblk2boot0.

Where do I find the imx-boot binary in the deploy directory? I am pretty sure that I tried the imx-boot and imx-boot-tagged from the deploy directory but neither worked. But I’m happy to try again.

What exactly do you mean by TEZI shell? Is this the same as a serial console via putty? The serial console via putty is working fine for me. And that’s what I have been using.

I have tried to install some Toradex stock images - without zeroing out the boot partitions though - on the board. No success so far. But, I’ll try with zeroing out again.

Thanks,
Burkhard

Hi Izzy,

NOTE: I am away from my board until September 5. So, I can’t try out anything in the next 10 days.

I am building a torizon-minimal image with some extra packages for Qt6 and Weston/Wayland. So, the image.json should be the standard one. image.json has a name attribute for each item in the blockdevs section. According to tezi.schema, the device file is created as /dev/<name>. So, I tried emmc-boot1 and mmcblk2boot0 for name to boot from the second paritition. Both failed.

Once in u-boot you can then reset which boot partition to use. However, I believe it requires a working u-boot image first to be able to do that.

I always change the boot partition from the Linux prompt of the TEZI image with mmc bootpart enable <p> 0 /dev/mmcblk2, where <p> is 1 or 2 for mmcblk2boot0 and mmcblk2boot1, respectively. This works in the same way as from the U-Boot prompt, doesn’t it?

Thanks,
Burkhard

Hi @bstubert,

Just in-case it helps…
My image.json file looks like this:

{
    "config_format": "4",
    ...
    "blockdevs": [
        {
            "name": "emmc",
            "table_type": "gpt",          <<<< ignore this difference as we have to use GPT instead of MBR (so the partition_types below will also be irrelevant)
            "partitions": [
                {
                    "partition_size_nominal": 96,
                    "want_maximised": false,
                    "partition_type": "BC13C2FF-59E6-4262-A352-B275FD6F7172",
                    "active": true,
                    "content": {
                        "label": "BOOT",
                        "filesystem_type": "FAT",
                        "mkfs_options": "",
                        "filename": "hue-image-verdin-imx8mp.bootfs.tar.xz",
                        "uncompressed_size": 20.078125
                    }
                },
                ...
            ]
        },
        {
            "name": "emmc-boot0",
            "erase": true,
            "content": {
                "filesystem_type": "raw",
                "rawfiles": [
                    {
                        "filename": "imx-boot",
                        "dd_options": "seek=0"
                    }
                ]
            }
        },
        {                                                                      <<<< Added this section to duplicate the imx-boot into both available partitions (with the erase specified as true which should clear it all out)
            "name": "emmc-boot1",
            "erase": true,
            "content": {
                "filesystem_type": "raw",
                "rawfiles": [
                    {
                        "filename": "imx-boot",
                        "dd_options": "seek=0"
                    }
                ]
            }
        }
    ]
}

Hi again @bstubert,

What exactly do you mean by TEZI shell? Is this the same as a serial console via putty? The serial console via putty is working fine for me. And that’s what I have been using.

Yes, I’m referring to the Linux prompt you get via the serial console. You’re at the right place :slight_smile:

Where do I find the imx-boot binary in the deploy directory? I am pretty sure that I tried the imx-boot and imx-boot-tagged from the deploy directory but neither worked. But I’m happy to try again.

Oh, you’re talking about the Yocto deploy directory, right? So, the imx-boot file from that directory should work as well.

However, ideally you should take the imx-boot from the Toradex Easy Installer image produced by Yocto. So, since you built your own signed image through Yocto, you should be able to find that installer image inside the <build-directory>/deploy/images subdirectory, e.g.:

pokyuser@6c3e3216f5dc:/workdir/build-smarc-imx95:
$ ls deploy/images/toradex-smarc-imx95/*Tezi*
deploy/images/toradex-smarc-imx95/torizon-minimal-toradex-smarc-imx95-Tezi_7.4.0-devel-20250817233114+build.0.tar
deploy/images/toradex-smarc-imx95/torizon-minimal-toradex-smarc-imx95-Tezi.tar

Normally, you’d grab that tarball, unpack it into a USB flash drive and stick that drive into your carried board. Then you’d run TEZI on your host machine, access the console and perform the manual steps that you like which would include grabbing the imx-boot file from the unpacked tarball.

I have tried to install some Toradex stock images - without zeroing out the boot partitions though - on the board. No success so far. But, I’ll try with zeroing out again.

Yes, please try again and let us know. Next week I should be able to run some tests, perhaps trying to replicate your steps.

Best regards,
Rogerio

Hi @rogerio.tx and @izzycoding,

I am back in my office and can “play” with my boards again. Thanks for your patience.

I tried the following three variants - without success. When rebooted, the board/SoM still doesn’t show any messages or can’t execute any bootloader. I am happy to have a video session with you to figure out the problem, but it’s up to you.

Below you find a detailed explanation what I tried.

Thanks,
Burkhard

Variant 0

My image.json (inside the unpacked TEZI image) now has identical definitions for the block devices emmc-boot0 and emmc-boot1 - except for the name, of course.

I boot my Verdin board and SoM into the TEZI installer 5.7.6 and use the serial console of the TEZI image for executing Linux commands.

I zero out both boot partitions:

/ # dd if=/dev/zero of=/dev/mmcblk2boot0
dd: error writing '/dev/mmcblk2boot0': No space left on device
64513+0 records in
64512+0 records out
/ # dd if=/dev/zero of=/dev/mmcblk2boot1
dd: error writing '/dev/mmcblk2boot1': No space left on device
64513+0 records in
64512+0 records out

I plug the USB drive with the unpacked TEZI image into the Verdin board. The TEZI installer shows my image. As the USB drive is not auto-mounted, I mount it manually with:

/ # mount /dev/sda1 /mnt

I copy the boot image imx-boot from the update package into the first boot partition:

/ # dd if=/mnt/b4-hmi-product-image-verdin-imx8mp-Tezi_7.3.0-devel-20250821085859+build.0/imx-boot of=/dev/mmcblk2boot0
2792+0 records in
2792+0 records out

I unmount the USB drive again:

/ # umount /mnt

I run the TEZI installer for my image b4-hmi-product-image-verdin-imx8mp-Tezi_7.3.0-devel-2025082108585. TEZI installs my image successfully. I reboot the board from the dialog offered by TEZI.

Rebooting fails with the following messages:

U-Boot SPL 2024.07-7.3.0-devel+git.3f772959501c (Jan 01 1970 - 00:00:00 +0000)
Training FAILED
DDR configured as single rank
SEC0:  RNG instantiated
Normal Boot
WDT:   Started watchdog@30280000 with servicing every 1000ms (60s timeout)
Trying to boot from BOOTROM
Boot Stage: Primary boot
Can't found uboot image in 640K range
SPL: failed to boot from all boot devices
### ERROR ### Please RESET the board ###

Variant 1

I zero out both boot partitions but do not install imx-boot in the first boot partition. When I start TEZI, it shows a message saying “Reading the Toradex Config Block failed, the Toradex Config Block might be erased or corrupted. Please restore the Config Block using the information on the Modules Sticker before continuing.” I press OK and fill out the form.

Module Type: 0058 Verdin iMX8M Plus Quad 4GB Wi-Fi / BT IT
Version: V1.0D
Serial: 069xxxxx

The installation of my image succeeds, but rebooting doesn’t show a single message.

Variant 2

I do the same as in Variant 1, but I install the standard Toradex image Toradex Embedded Linux Reference Minimal (7.3.0+build.8, 2025-07-03). The installation succeeds, but rebooting doesn’t show a single image.

Hi @bstubert,

I couldn’t spot anything wrong with your procedures, so probably a video call wouldn’t help much.

I’m guessing there might be something wrong with the fuses that control the boot device, but I’d need to familiarize myself with them to be honest. Is there any chance you’ve changed any other OCOTP fuses on your device besides those defining the secure boot key hashes?

Regardless of that, I’ll try to arrange for us to repeat your steps to see what happens on a different device.

Regards,

Rogerio

Hi @rogerio.tx,

A miracle happened: I reanimated my board!!! It’s working again.

I booted the TEZI image and pressed a key in the serial console to break into the U-Boot prompt. I changed the boot partition to /dev/mmcblk2boot0 from the U-Boot prompt with the following command:

Verdin iMX8MP TEZI # mmc partconf 2 1 1 0

In general, the command

mmc partconf <dev> 1 <part> 0

maps to /dev/mmc<dev>boot<part-1>. The command starts partition counting at 1, whereas the device file starts at 0.

After rebooting the board, it booted straight into my simple Qt application. Fine so far, but I don’t understand yet what went wrong.

The first thing I did, when my board wouldn’t boot any more, was to switch from boot partition 2 back to 1 with the Linux equivalent of the mmc partconf command:

mmc bootpart enable 1 0 /dev/mmcblk2

Checking the boot partition with the following command show that the board was correctly set back to boot partition 1 (/dev/mmcblk2boot0):

mmc extcsd read /dev/mmcblk2 | grep -A2 PARTITION_CONFIG

I don’t understand why the Linux command (executed from the TEZI prompt) for switching the boot partition didn’t work, but the U-Boot command did. Does TEZI block the mmc bootpart command? Does the Linux kernel hardening, which I had enabled, block this command?

Well, I’ll try again to boot the board from a modified imx-boot in the second boot partition. I should see a couple of “HAB events” saying that someone has tampered with imx-boot.

One last question for you: Where are the messages from TEZI logged?

Many thanks for your help!

Cheers, Burkhard

Hi @bstubert,

I’m very glad to hear of this miracle :slight_smile:

I don’t understand why the Linux command (executed from the TEZI prompt) for switching the boot partition didn’t work, but the U-Boot command did. Does TEZI block the mmc bootpart command? Does the Linux kernel hardening, which I had enabled, block this command?

I’m not aware of TEZI blocking this command in any way and since you were able to read it back I’d assume it worked. But, maybe you could try to change the configuration on the Linux prompt and read the current config from the U-Boot prompt to confirm? If it didn’t work, it’s likely a bug that we’d need to fix.

What I can tell you is that the partition switching works when running the installed OS, in particular Torizon OS, because we use that same command on the bootloader update feature to do the partition switching.

Also, the hardening for sure does not influence any of this since it basically protects only the second link of the chain of trust (kernel loading) - it has no impact to the bootloader loading.

Well, I’ll try again to boot the board from a modified imx-boot in the second boot partition. I should see a couple of “HAB events” saying that someone has tampered with imx-boot.

Please let us know the results.

One last question for you: Where are the messages from TEZI logged?

What messages do you mean? You can use dmesg to see the kernel messages for example. If you mean the UI program, then you can stop the tezi executable and run it from the prompt with the same argument that it was started before (run ps first to determine the original arguments and then kill it with kill PID) and it should show messages on its stdout.

Many thanks for your help!

My pleasure!

Hi @rogerio.tx,

I found the reason why my board boots properly when I change the boot partition from the U-Boot prompt but not when I do the change from the Linux prompt.

When I change the boot partition to 2 from the U-Boot prompt with

    Verdin iMX8MP # mmc partconf 2 1 2 0
    ## WARNING: Command execution WOULD BE DENIED in closed state (blocked by category) for `mmc partconf 2 1...`.

I can read back the value 0x50 for PARTITION_CONFIG at the Linux prompt:

root@verdin-imx8mp-06965633:/var/rootdirs/home/torizon# mmc extcsd read /dev/mmcblk2 | grep -A2 PARTITION_CONFIG
    Boot configuration bytes [PARTITION_CONFIG: 0x50]
    Boot Partition 2 enabled
    No access to boot partition

When I change the boot partition to 2 from the Linux prompt with

mmc bootpart enable 2 0 /dev/mmcblk2

PARTITION_CONFIG has the value 0x10. To understand the difference, we need to understand the bit settings of PARTITION_CONFIG:

  • Bits 0-2 – partition access: 0 = no access to boot partition; 1 = read/write access to boot partition 1; 2 = read/write access to boot partition 2. Current value: 0.

  • Bits 3-5 – partition enable: 0 = boot not enabled; 1 = boot partition 1 enabled; 2 = boot partition 2 enabled; 7 = user area enabled for boot. Current value: 1

  • Bit 6 – acknowledge: 0 = no boot acknowledge; 1 = boot acknowledge during boot. Current value: 0.

The value 0x50 means boot partition 2 and boot acknowledge enabled. The value 0x10 means boot partition 2 and boot acknowledge disabled.

We get the correct value 0x50 at the Linux prompt with this command:

mmc bootpart enable 2 1 /dev/mmcblk2

The second number (now 1 instead of 0) sets the boot acknowledge. Now, changing the boot partition also works properly from the Linux prompt.

Cheers, Burkhard

1 Like

Hi Burkhard,

Thanks for letting us know! I’ll make an internal ticket for us to improve this situation on the Installer side since it should be resetting the eMMC registers to a state that ensures the proper booting of the device.

Also, please let us know the results of your tests as well.

Cheers,

Rogerio