Using MCUBoot with nRF5340

Hello,

I try to figure out, how to correctly setup MCUboot for an nrf5340, so that:

  • Application is updatable
  • BT Stack is updatable
  • Firmware Updates are encrypted and signed
  • Updates are stored in external flash memory
  • No need to update the bootloader itself
  • Updates are stored on the external flash by some application specific protocol.

For that task, I upgraded our project to nrfconnect/sdk-nrf version v2.7.99-cs2. My current understanding is, that I want to use Sysbuild and have to define a static partition. I haven't found any comprehensive documentation, that defines exactly, which partitions are required for the given setup. So, I search for something in the examples, that could come close to my setup. The result of this example `pm_static.yml` looks like this:

app:
  address: 0x10200
  region: flash_primary
  size: 0xdfe00
mcuboot:
  address: 0x0
  region: flash_primary
  size: 0x10000
mcuboot_pad:
  address: 0x10000
  region: flash_primary
  size: 0x200
mcuboot_primary:
  address: 0x10000
  region: flash_primary
  size: 0xe0000
  span: [mcuboot_pad, app]
mcuboot_primary_app:
  address: 0x10200
  region: flash_primary
  size: 0xdfe00
  span: [app]
settings_storage:
  address: 0xf0000
  region: flash_primary
  size: 0x10000
mcuboot_primary_1:
  address: 0x0
  size: 0x40000
  device: nordic_ram_flash_controller
  region: ram_flash
mcuboot_secondary:
  address: 0x00000
  size: 0xe0000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  region: external_flash
mcuboot_secondary_1:
  address: 0xe0000
  size: 0x40000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  region: external_flash
external_flash:
  address: 0x120000
  size: 0x6e0000
  device: DT_CHOSEN(nordic_pm_ext_flash)
  region: external_flash
pcd_sram:
  address: 0x20000000
  size: 0x2000
  region: sram_primary

However, in the resulting `partition_manager_report`:

  external_flash (0x800000 - 8192kB): 
+------------------------------------------------+
| 0x0: mcuboot_secondary (0xe0000 - 896kB)       |
| 0xe0000: mcuboot_secondary_1 (0x40000 - 256kB) |
| 0x120000: external_flash (0x6e0000 - 7040kB)   |
+------------------------------------------------+

  flash_primary (0x100000 - 1024kB): 
+--------------------------------------------------+
| 0x0: mcuboot (0x10000 - 64kB)                    |
+---0x10000: mcuboot_primary (0xe0000 - 896kB)-----+
| 0x10000: mcuboot_pad (0x200 - 512B)              |
+---0x10200: mcuboot_primary_app (0xdfe00 - 895kB)-+
| 0x10200: app (0xdfe00 - 895kB)                   |
+--------------------------------------------------+
| 0xf0000: settings_storage (0x10000 - 64kB)       |
+--------------------------------------------------+

  otp (0x2fc - 764B): 
+------------------------------+
| 0xff8100: otp (0x2fc - 764B) |
+------------------------------+

  sram_primary (0x80000 - 512kB): 
+-----------------------------------------------+
| 0x20000000: pcd_sram (0x2000 - 8kB)           |
| 0x20002000: sram_primary (0x6e000 - 440kB)    |
| 0x20070000: rpmsg_nrf53_sram (0x10000 - 64kB) |
+-----------------------------------------------+

the partition `mcuboot_primary_1` is simply missing (and later the compilation of `nrf/modules/mcuboot/hooks/nrf53_hooks.c` fails with an undeclared symbol `PM_MCUBOOT_PRIMARY_1_ADDRESS`. 

I found this warning in the DTS parsing:

warning: FLASH_SIMULATOR (defined at drivers/flash/Kconfig.simulator:6) was assigned the value 'y'
but got the value 'n'. Check these unsatisfied dependencies: DT_HAS_ZEPHYR_SIM_FLASH_ENABLED (=n).
See http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_FLASH_SIMULATOR and/or look up
FLASH_SIMULATOR in the menuconfig/guiconfig interface.

The referenced documentation just contains the sentence: "Enable the flash simulator."

What do I have to do, to use MCUBoot? 

Is there any comprehensive documentation, that clearly states, what is required to completely configure the bootloader?

  • Hello,

    I've created a demo based on the peripheral_lbs sample, please see attached below.

    Demo sample

    peripheral_lbs_enc_fota.zip

    Disclaimers

    - DFU with encrypted images is not a feature that has been tested or validated by Nordic ( nRF52840 + NCS + MCUBoot, CC310-enabled image encryption? ) .

    - The cmake signing script does not sign encrypt the netcore image. This can be fixed by patching relevant cmake script.

    - The application_dfu.zip generated by the build contains signed but not encrypted images. Use the /build/peripheral_lbs_fota_enc/zephyr/zephyr.signed.encrypted.bin binary instead (application image). The netcore image which is signed but not encrypted is called signed_by_mcuboot_and_b0_ipc_radio.bin and is located in build/.

    - I have not done any extensive testing of this demo, just verified that I was able to update the appcore FW.

    Best regards,

    Vidar

  • Thank you! I will go through that example.

    An other, very annoying observation I made: In the corse to, basically "try and error", figuring out some settings that fixes build errors, I found, that the build is not reproducible!

    Currently, I have a state, where I completely delete the build folder, start the build with `--pristine` added to the `west build` command and get alternating, two different errors. The one error, is the error above, while building the application.After I received that error, I delete the build folder again and rerun the build command. Every second time, I receive a linker error, while linking the application (a missing symbol, probably not defined due to the first issue).

    As the second error is a linker error, this can not be any effect from parallel build, where the order of build steps could change. I disable the usage of `ccache`, but the behavior does not change. :-/

  • I'm not sure if I have experienced the same. Could you please try and see if you experience the same with the sample I provided? The linker error for PM_MCUBOOT_PRIMARY_1_ADDRESS will be raised if the flash RAM partition is missing.

  • I'm not even able to trigger the error above. My `pm_static.yml` works in your example, albeit the resulting partition_manager_report look different. I guess, I have to revisit every switch and configuration bit and make two clean builds with every change.

    Largest difference, I see is that my build does not include the `b0n` (which I think is required for the update of the bluetooth HCI controller on the radio core).

  • Yes, B0n is required for netcore DFU. It is enabled through the SB_CONFIG_SECURE_BOOT_NETCORE symbol in sysbuild.conf

Related