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 Reply Children
  • Hi Abhijith,

    looks like this is working. At least, this builds and I also expect it to work at runtime.

    Thank you very much,

    Torsten

  • Hi,

    sorry, it's me again. I figured out, that `CONFIG_MCUBOOT_BOOTUTIL_LIB` requires also, `CONFIG_IMG_MANAGER` to be set to `y`, otherwise, `zephyr/subsys/dfu/CMakeLists.txt` is not added as subdirectory in the CMake configuration step.

    `CONFIG_IMG_MANAGER` has a dependency to `CONFIG_STREAM_FLASH`:

    warning: IMG_MANAGER (defined at subsys/dfu/Kconfig:10) was assigned the value 'y' but got the value
    'n'. Check these unsatisfied dependencies: STREAM_FLASH (=n). See
    http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_IMG_MANAGER and/or look up IMG_MANAGER in
    the menuconfig/guiconfig interface. The Application Development Primer, Setting Configuration
    Values, and Kconfig - Tips and Best Practices sections of the manual might be helpful too.
    

    After also adding that configuration, I ended up again with a compilation error:

    /../../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"
          |  ^~~~~
    

    When adding `CONFIG_BOOT_SWAP_USING_MOVE=y` to the configuration, then KConfig complains about the undefined configuration symbol:

    prj.conf:84: 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 '/.../zephyr-workspace/zephyr/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_defconfig'
    Merged configuration '/.../zephyr-workspace/lovelace-pod-firmware/prj.conf'
    Merged configuration '/.../zephyr-workspace/lovelace-pod-firmware/build/lovelace-pod-firmware/zephyr/.config.sysbuild'

    In the end, I really don't need `boot_write_img_confirmed_multi()` from `zephyr/subsys/dfu/boot/mcuboot.c`, as this function really does nothing else, but to call `boot_set_confirmed_multi()` from the MCUBoot subtree.

    It would probably helpful, if the dependencies that are encoded in some parts of the CMake and C code, would also be reflected in the Kconfig configuration.

    Any idea, what I could try next?

    best regards

    Torsten

    BTW: Removing that `#error` preprocessor statement in `mcuboot_config.h` would solve that issue for me. Maybe, you could check with some of the developers, if that text is really necessary?

  • Hello,

    Torsten Robitzki said:
    Maybe, you could check with some of the developers, if that text is really necessary?

    Glad to hear it's working! I can check internally to see if removing the #error directive in mcuboot_config.h is necessary.

    But have you tested the MCUboot mechanism after removing the #error? I recommend checking if the device boots into the new image and doesn't revert to the old one (maybe try rebooting the device a few times).

    Kind Regards,

    Abhijith

    .

  • Yes, after the first reboot, the log messages from MCUBoot suggest, that it performs a test swap installation and after confirming the image, and a next reboot, the image is not switched back. If I skip the confirmation, the image get switched back after rebooting.

    Removing the offensive line of code, was just a test. I really would hate to have clones of all the zephyr and nordic repositories for all this kind of hacks. When possible, I would love to see that change in one of the next releases, so that I could just upgrade to the next version or, of cause, having some other solution, that would make that code change unnecessary.

    best regards

    Torsten

Related