This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Upgraded firmware image not confirmed by MCUBoot DFU

Hello,

We are building an OTA firmware update mechanism that relies on MCUBoot and the DFU Target API. We take the implementation of fota_download as an example.

Currently our code is based on nRF Connect SDK 1.5.0. We are able to transmit a firmware image via Bluetooth and to write it into the flash memory of the target device.

Then the device is able to reboot into the new firmware image, but the new image cannot be validated. As a consequence, the device boots into the old image at next reboot. Indeed, the method boot_write_img_confirmed() returns error -5 (-EIO).

Our upgrade process is detailed below. The firmware image transferred is app_update.bin.

In the "old" firmware, the DFU process calls the following API methods:

  1. dfu_target_img_type() is called to get the type of the image: it returns DFU_TARGET_IMAGE_TYPE_MCUBOOT as expected.
  2. dfu_target_init() is called with the image type and size, and returns no error as expected.
  3. dfu_target_write() is called several times without error until the firmware is fully transmitted.
  4. dfu_target_done(true) is called upon successful transfer.
  5. sys_reboot(SYS_REBOOT_COLD) is called to reboot the device.
  6. MCUBoot copies the new image into slot 0 and boots into it.

In the "new" firmware, we do the following operations:

  1. boot_is_img_confirmed() is called and returns false as expected, since the new image is not confirmed yet.
  2. boot_write_img_confirmed() is called to confirm the new image, but returns the error -5 (-EIO)

In both the old and new firmware projects, the prj.conf files contain the following options:

# Bootloader
CONFIG_BOOTLOADER_MCUBOOT=y
# Device firmware upgrade
CONFIG_DFU_TARGET=y
CONFIG_DFU_TARGET_MCUBOOT=y
CONFIG_FLASH=y
CONFIG_IMG_ERASE_PROGRESSIVELY=y
CONFIG_IMG_MANAGER=y
CONFIG_MCUBOOT_IMG_MANAGER=y

I observed the error occurring in boot_write_img_confirmed() and found the following information.

Internally, boot_write_img_confirmed() calls boot_set_confirmed(), which returns 4 (BOOT_EBADVECT), because the field image of struct boot_swap_state has value BOOT_MAGIC_BAD. If we follow further, we end up in the method boot_magic_decode(), called by boot_read_swap_state(), which compares an area read from the flash with the MAGIC field of an array of constant values referred to as boot_img_magic, the MAGIC field of the image trailer.

It turns out that the values of the flash area that are compared by boot_magic_decode() are indeed completely different from the MAGIC field that must be present in the image trailer.

I suspect that the cause of the problem lies in the signing process of the new firmware, but I can't figure out what is taken care of automatically by the west build command and what needs to be done explicitly. For now we would just like to get the upgrade working with the MCUBoot developer key.

In west sign documentation, it is written that building and signing can be done in one step by setting "some Kconfig options".

I tried different combinations of the following options but didn't have more success:
CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE=y
CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS="--pad"
CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="/path/to/ncs/1.x.x/bootloader/mcuboot/root-rsa-2048.pem"
CONFIG_SIGN_IMAGES=y
Something that also bothers me is that no file zephyr/zephyr.signed.confirmed.bin or .hex is generated when CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE is enabled.

Despite different attempts, I can't figure out what prevents the updated firmware to be validated. I suspect a misconfiguration of the building/signing process that causes the image trailer to be invalid. Could you provide some insight to help us find a solution ? Thank you very much.

Kind regards,

Anthony

Parents Reply Children
  • Hey Esisk, yes I figured out the problem by using static partitions as suggested by Heidi. In addition to my reply above, here are the Kconfig options that I used:

    # Bootloader
    CONFIG_BOOTLOADER_MCUBOOT=y
    # Device firmware upgrade
    CONFIG_DFU_TARGET=y
    CONFIG_DFU_TARGET_MCUBOOT=y
    CONFIG_FLASH=y
    CONFIG_IMG_ERASE_PROGRESSIVELY=y
    CONFIG_IMG_MANAGER=y
    CONFIG_MCUBOOT_IMG_MANAGER=y
    CONFIG_SIGN_IMAGES=y

    The CONFIG_MCUBOOT_ options were not needed to confirm the image successfully. Still, now we need to configure the build system to sign the firmware with our own keys.

Related