What is the proper way to generate an image that is confirmed with MCUBoot

Hei!

I am currently working on a project where we have implemented FOTA and I have had a lot of issues with flashing fresh boards with the complete firmware package.

Our project has a "self test" procedure, so it will check if the currently running image is confirmed, do the self-test, which confirms the image, and then reboot.

What I have experienced is that flashing a brand new chip with the merged.hex file will cause an infinite reboot loop. I think I have concluded that the issue is with the MCUBoot trailer not being included in the merged.hex file. I have modded the CMake files in the nRF Connect SDK to create a confirmed image by adding the --confirm flag to the target which creates the test update.

Flashing first the merged.hex, then the app_test_update.hex, which now is padded and confirmed, fixes this issue.

Is there a way that I can generate a fully confirmed image with the nRF Connect SDK?

We are using v1.9.1 of the SDK.

  • I have the same issue, and have tried using the `CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE` flag but the image still cannot be confirmed. It appears that the trailer magic is not set, and the `boot_write_img_confirmed()` API treats an unset magic as already confirmed.

    I had filed an MCUBoot issue to resolve this, but it hasn't seen any action: github.com/.../1436

    I
     am using v2.0.0 SDK

  • Hi,

    When you build an application with MCUboot you will get an autogenerated signed image, app_signed.hex. So you can just program the chip with this instead of merged.hex. You can find an overview of the different files that are generated here: Using MCUboot in nRF Connect SDK.

    Best regards,

    Marte

  • Hmm, but the app_signed.hex is still not a confirmed image?

    It is signed, yes, but the image trailer is still not included so the image is not set as confirmed by MCUBoot.

    I have managed to create the confirmed image manually, using this script:

    python ../bootloader/mcuboot/scripts/imgtool.py sign \
    		--key path/to/signing_key.pem \
    		--header-size 0x200 \
    		--align 4 --version x.y.z+0 \
    		--pad-header --slot-size 0x70000 --confirm \
    		build/zephyr/mcuboot_primary_app.hex \
    		build/zephyr/app_confirmed.hex
    
    python ../zephyr/scripts/mergehex.py -o build/zephyr/merged_and_confirmed.hex --overlap=replace \
    		build/zephyr/merged.hex build/zephyr/app_confirmed.hex
    

    But this requires me to add additional steps to the build process, which is undesirable.

    Especially since there seems to be a flag that should do this automatically.

  • MCUBoot does not write the image trailer either, so using the app_signed.hex still causes the same issues as I described in the original post.

  • This is the output from MCUBoot after flashing merged.hex, then app_signed.hex:

    *** Booting Zephyr OS build v2.7.99-ncs1-1  ***
    [00:00:00.226,409] <inf> mcuboot: Starting bootloader
    [00:00:00.227,630] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.228,118] <inf> mcuboot: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.228,546] <inf> mcuboot: Boot source: none
    [00:00:00.228,942] <inf> mcuboot: Swap type: none
    [00:00:00.622,161] <inf> mcuboot: Bootloader chainload address offset: 0x10000
    [00:00:00.622,497] <inf> mcuboot: Jumping to the first image slot
    *** Booting Zephyr OS build v2.7.99-ncs1-1  ***
    [00:00:00.226,409] <inf> mcuboot: Starting bootloader
    [00:00:00.227,630] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.228,118] <inf> mcuboot: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.228,546] <inf> mcuboot: Boot source: none
    [00:00:00.228,942] <inf> mcuboot: Swap type: none
    [00:00:00.622,100] <inf> mcuboot: Bootloader chainload address offset: 0x10000
    [00:00:00.622,467] <inf> mcuboot: Jumping to the first image slot
    *** Booting Zephyr OS build v2.7.99-ncs1-1  ***
    [00:00:00.226,379] <inf> mcuboot: Starting bootloader
    [00:00:00.227,600] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.228,088] <inf> mcuboot: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.228,515] <inf> mcuboot: Boot source: none
    [00:00:00.228,881] <inf> mcuboot: Swap type: none
    [00:00:00.621,673] <inf> mcuboot: Bootloader chainload address offset: 0x10000
    [00:00:00.622,039] <inf> mcuboot: Jumping to the first image slot
    *** Booting Zephyr OS build v2.7.99-ncs1-1  ***
    [00:00:00.226,440] <inf> mcuboot: Starting bootloader
    [00:00:00.227,661] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.228,149] <inf> mcuboot: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.228,576] <inf> mcuboot: Boot source: none
    [00:00:00.228,942] <inf> mcuboot: Swap type: none
    [00:00:00.621,673] <inf> mcuboot: Bootloader chainload address offset: 0x10000
    [00:00:00.622,009] <inf> mcuboot: Jumping to the first image slot
    

    This is the output using my generated image:

    *** Booting Zephyr OS build v2.7.99-ncs1-1  ***
    [00:00:00.362,670] <inf> mcuboot: Starting bootloader
    [00:00:00.363,891] <inf> mcuboot: Primary image: magic=good, swap_type=0x1, copy_done=0x3, image_ok=0x1
    [00:00:00.364,379] <inf> mcuboot: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.364,807] <inf> mcuboot: Boot source: primary slot
    [00:00:00.368,591] <inf> mcuboot: Swap type: none
    [00:00:00.761,627] <inf> mcuboot: Bootloader chainload address offset: 0x10000
    [00:00:00.761,993] <inf> mcuboot: Jumping to the first image slot

Related