How to confirm image installed by MCU boot

Hi,

I still try to configure Nordic-Zepyr build for a nrf5340, with a BLE stack and MCUBoot as the bootloader. The application will receive image updates over MQTT and store them in external flash memory.

According to your documentation (https://docs.nordicsemi.com/bundle/ncs-latest/page/mcuboot/design.html), MCUBOOT_SWAP_USING_MOVE seems to be the state of the art algorithm for MCUBoot to install new images. I was able to get that up and running. Next step now, is to let the newly installed firmware confirm the installation, so that the bootloader will not rollback the installation with the next reset.

It looks like the necessary modifications of the image headers or trailers are implemented in `boot_write_img_confirmed()` to confirm the new image. 

How do I have to configure my application, so that I can use this library function? The `normal` CMake way seems to be straight forward and I would just have to add the bootutil library (defined in mcuboot/boot/bootutil/CMakeLists.txt) to my application target. With Zephyr, mcuboot/boot/bootutil/zephyr/CMakeLists.txt seems to apply here and it looks like I should add CONFIG_MCUBOOT_BOOTUTIL_LIB=y to my application configuration.

According to Kconfig.mcuboot:

menuconfig MCUBOOT_BOOTUTIL_LIB
	bool "MCUboot utility library"
	help
	  Enable MCUboot utility library which implements functions
	  required by the chain-loaded application and the MCUboot.

But, that does results in build error (complaining about CONFIG_BOOT_SWAP_USING_MOVE being not set), when compiling `bootloader/mcuboot/boot/bootutil/src/bootutil_public.c`:

In file included from /Users/todi/bloomlife/zephyr-workspace/bootloader/mcuboot/boot/bootutil/zephyr/../../zephyr/include/sysflash/pm_sysflash.h:13,
                 from /Users/todi/bloomlife/zephyr-workspace/bootloader/mcuboot/boot/bootutil/zephyr/../../zephyr/include/sysflash/sysflash.h:10,
                 from /Users/todi/bloomlife/zephyr-workspace/bootloader/mcuboot/boot/bootutil/src/bootutil_public.c:43:
/Users/todi/bloomlife/zephyr-workspace/bootloader/mcuboot/boot/bootutil/zephyr/../../zephyr/include/mcuboot_config/mcuboot_config.h:75:2: error: #error "CONFIG_BOOT_SWAP_USING_MOVE not set"
   75 | #error "CONFIG_BOOT_SWAP_USING_MOVE not set"
      |  ^~~~~

Or, when I explicitly set CONFIG_BOOT_SWAP_USING_MOVE, an error is issued during the configuration phase of the build, complaining about the unknown BOOT_SWAP_USING_MOVE configuration option:

/Users/todi/bloomlife/zephyr-workspace/lovelace-pod-firmware/prj.conf:82: warning: attempt to assign the value 'y' to the undefined symbol BOOT_SWAP_USING_MOVE
Parsing /Users/todi/bloomlife/zephyr-workspace/zephyr/Kconfig
Loaded configuration '/Users/todi/bloomlife/zephyr-workspace/zephyr/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_defconfig'
Merged configuration '/Users/todi/bloomlife/zephyr-workspace/lovelace-pod-firmware/prj.conf'
Merged configuration '/Users/todi/bloomlife/zephyr-workspace/lovelace-pod-firmware/build/lovelace-pod-firmware/zephyr/.config.sysbuild'

error: Aborting due to Kconfig warnings

CMake Error at /Users/todi/bloomlife/zephyr-workspace/zephyr/cmake/modules/kconfig.cmake:395 (message):
  command failed with return code: 1
Call Stack (most recent call first):
  /Users/todi/bloomlife/zephyr-workspace/nrf/cmake/modules/kconfig.cmake:29 (include)
  /Users/todi/bloomlife/zephyr-workspace/zephyr/cmake/modules/zephyr_default.cmake:132 (include)
  /Users/todi/bloomlife/zephyr-workspace/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:66 (include)
  /Users/todi/bloomlife/zephyr-workspace/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
  CMakeLists.txt:29 (find_package)


-- Configuring incomplete, errors occurred!

This is the relevant part of the prj.config file:

CONFIG_MCUBOOT_BOOTUTIL_LIB=y
CONFIG_BOOT_SWAP_USING_MOVE=y

When I try to instead add `SB_CONFIG_BOOT_SWAP_USING_MOVE=y` to sysbuild.conf, I get the very same error.

/Users/todi/bloomlife/zephyr-workspace/lovelace-pod-firmware/sysbuild.conf:22: warning: attempt to assign the value 'y' to the undefined symbol BOOT_SWAP_USING_MOVE
Parsing /Users/todi/bloomlife/zephyr-workspace/zephyr/share/sysbuild/Kconfig
Loaded configuration '/Users/todi/bloomlife/zephyr-workspace/lovelace-pod-firmware/build/_sysbuild/empty.conf'
Merged configuration '/Users/todi/bloomlife/zephyr-workspace/lovelace-pod-firmware/sysbuild.conf'

error: Aborting due to Kconfig warnings

What do I have to do, to use that library?

best regards and thanks in advance,

Torsten

Nordic SDK version used: v2.7.99-cs2

Parents
  • Hello Torsten,

    Sorry for getting back to you so late. I took a long vacation and resumed work this week. Usually, some of my colleagues would take over in my absence, but I guess we were very understaffed during the Christmas period, which caused this case to remain pending for a long time.

    Regarding your issue:

    • CONFIG_BOOT_SWAP_USING_MOVE=y: The use of Swap is not recommended as MCUBoot does not support image swapping (test swaps) for the network core due to the way RAM and PCD interact during reversion.
    • CONFIG_BOOT_UPGRADE_ONLY: The simultaneous update of multiple images does not support network core image reversion, so you need to disable application image reversion.

    The application core can be reverted, but doing so breaks the network core upon reversal, as the reversion process overwrites the network core with the content currently in the RAM that PCD uses. To enable this, define the CONFIG_USE_NRF53_MULTI_IMAGE_WITHOUT_UPGRADE_ONLY Kconfig option in the project-level Kconfig file. Once defined, you can activate it by setting CONFIG_USE_NRF53_MULTI_IMAGE_WITHOUT_UPGRADE_ONLY.

    Refer Simultaneous multi-image DFU with nRF5340

    Kind Regards,

    Abhijith

Reply
  • Hello Torsten,

    Sorry for getting back to you so late. I took a long vacation and resumed work this week. Usually, some of my colleagues would take over in my absence, but I guess we were very understaffed during the Christmas period, which caused this case to remain pending for a long time.

    Regarding your issue:

    • CONFIG_BOOT_SWAP_USING_MOVE=y: The use of Swap is not recommended as MCUBoot does not support image swapping (test swaps) for the network core due to the way RAM and PCD interact during reversion.
    • CONFIG_BOOT_UPGRADE_ONLY: The simultaneous update of multiple images does not support network core image reversion, so you need to disable application image reversion.

    The application core can be reverted, but doing so breaks the network core upon reversal, as the reversion process overwrites the network core with the content currently in the RAM that PCD uses. To enable this, define the CONFIG_USE_NRF53_MULTI_IMAGE_WITHOUT_UPGRADE_ONLY Kconfig option in the project-level Kconfig file. Once defined, you can activate it by setting CONFIG_USE_NRF53_MULTI_IMAGE_WITHOUT_UPGRADE_ONLY.

    Refer Simultaneous multi-image DFU with nRF5340

    Kind Regards,

    Abhijith

Children
  • Hi  ,

    no problem, we are also very busy at the moment. I've added this issue to our ticket system and it might take some time, before someone is able to work on this further.

    thanks 

    Torsten

  • Hi Menon ,

    I tried to apply your solution. I inserted `CONFIG_USE_NRF53_MULTI_IMAGE_WITHOUT_UPGRADE_ONLY=y` into `prj.conf`. Trying to add that to `sysbuild.conf` resulted in an error. I'm not sure, what you mean by "project-level Kconfig file" (same applies to CONFIG_USE_NRF53_MULTI_IMAGE_WITHOUT_UPGRADE_ONLY).

    Now, the bootloader fails with the log message `mcuboot: Image in the secondary slot is not valid!` with the first image slot (application).

    I tried both, the signed and the signed and encrypted image. The image header and trailer seem to be ok (verfied with a debugger and I get the "magic=good" log message, that confirms the image trailer). I also confirmed, that the bootloader is reading the image correctly by attaching a logic analyser to the flash memory and looking at the traces.

    Using imgtool to verify the signed image, works. Using imgtool to verify the signed and encrypted image fails! I don't know, if that is on purpose or not. The image header for the signed and encrypted image looks like this:

    Printing content of signed image: zephyr.signed.encrypted.bin

    #### Image header (offset: 0x0) ############################
    magic: 0x96f3b83d
    load_addr: 0x0
    hdr_size: 0x200
    protected_tlv_size: 0x0
    img_size: 0xba1a0
    flags: ENCRYPTED_AES128 (0x4)
    version: 0.1.42+0
    ############################################################
    #### Payload (offset: 0x200) ###############################
    | |
    | FW image (size: 0xba1a0 Bytes) |
    | |
    ############################################################
    #### TLV area (offset: 0xba3a0) ############################
    magic: 0x6907
    area size: 0x10c
    ---------------------------------------------
    type: SHA256 (0x10)
    len: 0x20
    data: 0x07 0x46 0x19 0xbd 0x1f 0x8d 0xde 0xee
    0x38 0xde 0x79 0x93 0x0f 0x94 0x8a 0x45
    0x7b 0x62 0xd7 0xab 0x86 0x39 0x7b 0x6a
    0x5c 0xa6 0xfb 0x7a 0x03 0xf0 0xcd 0x71
    ---------------------------------------------
    type: KEYHASH (0x1)
    len: 0x20
    data: 0x3e 0xb0 0x2c 0xc0 0xb5 0xdc 0x6e 0x94
    0x9d 0x26 0xb3 0xad 0x4d 0x10 0xa2 0x62
    0x94 0xd9 0xf4 0x3e 0x5f 0x49 0xaf 0x89
    0x11 0xb0 0x21 0x81 0xe1 0x9d 0x99 0x2d
    ---------------------------------------------
    type: ECDSASIG (0x22)
    len: 0x47
    data: 0x30 0x45 0x02 0x21 0x00 0xf7 0x49 0x32
    0x8c 0x61 0x2d 0xd0 0x40 0xd4 0x66 0x49
    0x2d 0xad 0xc4 0x91 0xa0 0xb2 0xb9 0x84
    0x2d 0x92 0xd2 0x30 0x36 0x25 0xcc 0xcf
    0x3b 0xb4 0xa3 0xce 0xab 0x02 0x20 0x62
    0xa6 0x7e 0xe9 0xfd 0x18 0xd7 0x03 0xce
    0xe8 0x83 0x97 0x6c 0x4f 0x9b 0x03 0x75
    0xea 0xa4 0x46 0x2c 0x9f 0x6b 0x27 0x7e
    0x8d 0x11 0x20 0x84 0xec 0x67 0x43
    ---------------------------------------------
    type: ENCEC256 (0x32)
    len: 0x71
    data: 0x04 0x86 0x1c 0xba 0x9a 0x6d 0x7e 0xc2
    0x08 0x4c 0xe2 0xcb 0x75 0xac 0x74 0xb8
    0xf5 0x89 0x11 0xdf 0xf9 0x5d 0xd6 0xc6
    0x73 0x7e 0x34 0xc2 0xd8 0xb5 0x7a 0x82
    0x39 0x4f 0xb9 0xd0 0x0b 0xd9 0x60 0x46
    0x7c 0x43 0x40 0x4f 0x0b 0x8c 0x9f 0x46
    0x15 0xa5 0x4a 0x22 0xf7 0x2e 0xa3 0x20
    0xcf 0x6e 0x2a 0x6d 0x60 0x30 0x48 0x79
    0x8f 0xc1 0xab 0x27 0x7b 0x25 0xf2 0xd1
    0x7d 0x96 0x19 0xe1 0x59 0xaf 0x6d 0x49
    0x77 0x3e 0x17 0x03 0x0c 0x0d 0xbc 0xd0
    0x0e 0xfe 0xaa 0x53 0xef 0x1c 0x1e 0x51
    0x34 0xce 0x6b 0x72 0xa2 0xad 0xd5 0x44
    0x1d 0xf9 0xd0 0x77 0x51 0x9f 0xc2 0x7a
    0xaf
    ############################################################
    #### End of Image ##########################################
    dumpinfo has run successfully

    According to the debugger, the correct private key is stored in the bootloader (in bootutil_enc_key).

    What can be the issue here? How to get even more details as to what causes the failure?

    Thanks in advance and best regards

    Torsten

Related