Skip to content

sysflash: Correct ALL_AVAILABLE_SLOTS when MCUBOOT is not image 2 #444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 69 commits into
base: main
Choose a base branch
from

Conversation

ball-hayden
Copy link

Consider an nRF5340 application with the following sysbuild config:

SB_CONFIG_BOOTLOADER_MCUBOOT=y
SB_CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y

SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y

SB_CONFIG_SECURE_BOOT_APPCORE=y
SB_CONFIG_SECURE_BOOT_NETCORE=y

SB_CONFIG_NETCORE_APP_UPDATE=y
SB_CONFIG_MCUBOOT_NRF53_MULTI_IMAGE_UPDATE=y
SB_CONFIG_MCUBOOT_MODE_OVERWRITE_ONLY=y

In this case, we have a total of 3 updatable images (app, net, mcuboot).

MCUBOOT_IMAGE_NUMBER = 2 (i.e. CONFIG_UPDATEABLE_IMAGE_NUMBER = 2), as the app secondary partition is reused for MCUBoot secondary.

CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER = 2 as the net core image has index 1.

In this case, we should fall through to the definition of ALL_AVAILABLE_SLOTS that caters for 2 updatable images.

carlescufi and others added 30 commits May 14, 2025 13:47
Use the generic commit-tags action to provide sauce tag checks.

Signed-off-by: Carles Cufi <[email protected]>
(cherry picked from commit 64da058)
Removes the `add_subdirectory`
of nrfxlib it will still check that the nrfxlib is located outside
the mcuboot directory.

Signed-off-by: Sigvart Hovland <[email protected]>
Signed-off-by: Andrzej Puzdrowski <[email protected]>
Signed-off-by: Martí Bolívar <[email protected]>
Signed-off-by: Emil Obalski <[email protected]>
Signed-off-by: Andrzej Puzdrowski <[email protected]>
Signed-off-by: Håkon Øye Amundsen <[email protected]>
Signed-off-by: Ioannis Glaropoulos <[email protected]>
Signed-off-by: Torsten Rasmussen <[email protected]>
Signed-off-by: Jamie McCrae <[email protected]>
Signed-off-by: Dominik Ermel <[email protected]>
(cherry picked from commit 6558dff)
Add prj_minimal.conf, a Kconfig fragment to be used for minimally
sized image production. The minimal fragment has been simplified for
only external crypto.

Move partition sizing into Kconfig to be consistent with the method
used by b0.

Using this fragment with prj_minimal.conf makes MCUboot < 16kB for
all nRF devices (9160 still needs 32kB partition).

Ref: NCSDK-6704
Signed-off-by: Stephen Stauts <[email protected]>
Signed-off-by: Martí Bolívar <[email protected]>
Signed-off-by: Sebastian Bøe <[email protected]>
Signed-off-by: Torsten Rasmussen <[email protected]>
Signed-off-by: Jamie McCrae <[email protected]>
Signed-off-by: Dominik Ermel <[email protected]>
(cherry picked from commit 42fdada)
Adds project configurations for the two systems on the Thingy:91
(PCA-20035) board.

The bootloader that is factory-programmed on thing91 does not support
ECDSA signature type. Hence this commit also sets the signature type
to RSA for applications built for Thingy:91.

Signed-off-by: Bernt Johan Damslora <[email protected]>
Signed-off-by: Sigvart Hovland <[email protected]>
Signed-off-by: Jon Helge Nistad <[email protected]>
Signed-off-by: Balaji Srinivasan <[email protected]>
Signed-off-by: Robert Lubos <[email protected]>
Signed-off-by: Torsten Rasmussen <[email protected]>
Signed-off-by: Jamie McCrae <[email protected]>
Signed-off-by: Marek Pieta <[email protected]>
Signed-off-by: Dominik Ermel <[email protected]>
(cherry picked from commit c4251c7)
The default value of CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT
for nRF52 SOCs has been changed from 0 to 3, but it makes
MCUBoot get stuck on erasing flash pages when swapping two
images. Restore the previous value until the RTC issue is
resolved (see NCSDK-14427)

Signed-off-by: Damian Krolik <[email protected]>
Signed-off-by: Torsten Rasmussen <[email protected]>
Signed-off-by: Jamie McCrae <[email protected]>
Signed-off-by: Dominik Ermel <[email protected]>
(cherry picked from commit c141b8b)
This patch adds board configuration for the Thingy:91 X.

Signed-off-by: Maximilian Deubel <[email protected]>
(cherry picked from commit ed8ed2e)
Partition Manager is an nRF Connect SDK component which uses yaml
files to resolve flash partition placement with a holistic view of the
device.

This component's MCUboot portions began life as upstream mcuboot
PR#430. This added support for being built as a sub image from the
downstream Nordic patch set for a zephyr multi image build
system (mcuboot 430 was combined with effor submitted to upstream
zephyr as PR#13672, which was ultimately reworked after being rejected
for mainline at the ELCE 2019 conference in Lyon).

It has since evolved over time. This is the version that will go into
NCS v1.3. It features:

- page size aligned partitions for all partitions used by mcuboot.
- image swaps without scratch partitions

Add support for configurations where there exists two primary slots
but only one secondary slot, which is shared. These two primary slots
are the regular application and B1. B1 can be either S0 or S1
depending on the state of the device.

Decide where an upgrade should be stored by looking at the vector
table.

Provide update candidates for both s0 and s1. These candidates must be
signed with mcuboot after being signed by b0.

Additional notes:

- we make update.hex without trailer data

  This is needed for serial recovery to work using hex files.
  Prior to this the update.hex got TLV data at the end of the
  partition, which caused many blank pages to be included,
  which made it hard to use in a serial recovery scheme.

  Instead, make update.hex without TLV data at the end,
  and provide a new file test_update.hex which contains
  the TLV data, and can be directly flashed to test the
  upgrade procedure.

- we use a function for signing the application as future-proofing
  for when other components must be signed as well

- this includes an update to single image applications that enables
  support for partition manager; when single image DFU is used, a
  scratch partition is not needed.

- In NCS, image 1 primary slot is the upgrade bank for mcuboot (IE S0 or
  S1 depending on the active slot). It is not required that this slot
  contains any valid data.

- The nRF boards all have a single flash page size, and partition
  manager deals with the size of the update partitions and so on, so we
  must skip a boot_slots_compatible() check to avoid getting an error.

- There is no need to verify the target when using partition manager.

- We lock mcuboot using fprotect before jumping, to enable the secure
  boot property of the system.

- Call fw_info_ext_api_provide() before booting if EXT_API_PROVIDE
  EXT_API is enabled. This is relevant only when the immutable
  bootloader has booted mcuboot.

Signed-off-by: Håkon Øye Amundsen <[email protected]>
Signed-off-by: Øyvind Rønningstad <[email protected]>
Signed-off-by: Sebastian Bøe <[email protected]>
Signed-off-by: Sigvart Hovland <[email protected]>
Signed-off-by: Martí Bolívar <[email protected]>
Signed-off-by: Torsten Rasmussen <[email protected]>
Signed-off-by: Andrzej Głąbek <[email protected]>
Signed-off-by: Robert Lubos <[email protected]>
Signed-off-by: Andrzej Puzdrowski <[email protected]>
Signed-off-by: Emil Obalski <[email protected]>
Signed-off-by: Pawel Dunaj <[email protected]>
Signed-off-by: Ioannis Glaropoulos <[email protected]>
Signed-off-by: Johann Fischer <[email protected]>
Signed-off-by: Vidar Berg <[email protected]>
Signed-off-by: Draus, Sebastian <[email protected]>
Signed-off-by: Trond Einar Snekvik <[email protected]>
Signed-off-by: Jamie McCrae <[email protected]>
Signed-off-by: Joakim Andersson <[email protected]>
Signed-off-by: Georgios Vasilakis <[email protected]>
Signed-off-by: Dominik Ermel <[email protected]>
(cherry picked from commit 7f66ef1)
- Add network core bootloader implementation

  Enables network core updates of nrf53 using MCUBoot by identifying
  images through their start addresses. Also implements the control and
  transfer using the PCD module.

- Add support for multi image DFU using partition manager.

- Add check for netcore addr if NSIB is enabled so netcore updates works

- boot: zephyr: move thingy53_nrf5340_cpuapp.conf downstream

  Moved the board configuration for Thingy:53 Application Core to the
  nRF Connect SDK MCUboot downstream repository. The configuration file
  contains references to the Kconfig modules that are only available in
  the nRF Connect SDK. The current configuration is set up to work in the
  nRF Connect SDK environment and cannot be used upstream.

- pm: enable ram flash partition using common flag

  This patch makes mcuboot_primary_1 ram-flash partition
  selectable using CONFIG_NRF53_MCUBOOT_PRIMARY_1_RAM_FLASH
  property. This is needed since CONFIG_NRF53_MULTI_IMAGE_UPDATE
  become not only configuration which requires that partition.

- MCUBoot configures USB CDC by its own. There is no need for
  BOARD_SERIAL_BACKEND_CDC_ACM option to configure anything which is
  later overwritten anyway.

  Jira: NCSDK-18596

Signed-off-by: Andrzej Puzdrowski <[email protected]>
Signed-off-by: Emil Obalski <[email protected]>
Signed-off-by: Håkon Øye Amundsen <[email protected]>
Signed-off-by: Ioannis Glaropoulos <[email protected]>
Signed-off-by: Jamie McCrae <[email protected]>
Signed-off-by: Johann Fischer <[email protected]>
Signed-off-by: Kamil Piszczek <[email protected]>
Signed-off-by: Ole Sæther <[email protected]>
Signed-off-by: Sigvart Hovland <[email protected]>
Signed-off-by: Simon Iversen <[email protected]>
Signed-off-by: Torsten Rasmussen <[email protected]>
Signed-off-by: Trond Einar Snekvik <[email protected]>
Signed-off-by: Mateusz Kapala <[email protected]>
Signed-off-by: Dominik Ermel <[email protected]>
(cherry picked from commit 9b50519)
Do some cleanup of nRF peripherals. This is necessary since Zephyr
doesn't have any driver deinitialization functionality, and we'd like
to leave peripherals in a more predictable state before booting the
Zephyr image. This should be re-worked when the zephyr driver model
allows us to deinitialize devices cleanly before jumping to the
chain-loaded image.

Signed-off-by: Andrzej Puzdrowski <[email protected]>
Signed-off-by: Robert Lubos <[email protected]>
Signed-off-by: Torsten Rasmussen <[email protected]>
Signed-off-by: Øyvind Rønningstad <[email protected]>
Signed-off-by: Martí Bolívar <[email protected]>
Signed-off-by: Håkon Øye Amundsen <[email protected]>
Signed-off-by: Ioannis Glaropoulos <[email protected]>
Signed-off-by: Johann Fischer <[email protected]>
Signed-off-by: Trond Einar Snekvik <[email protected]>
Signed-off-by: Torsten Rasmussen <[email protected]>
Signed-off-by: Jamie McCrae <[email protected]>
Signed-off-by: Dominik Ermel <[email protected]>
(cherry picked from commit 3226c3b)
To ensure that MCUBoot does not leak keys or other material through
memory to non-secure side we clear the memory before jumping to the next
image.

Signed-off-by: Sigvart Hovland <[email protected]>
Signed-off-by: Dominik Ermel <[email protected]>
Signed-off-by: Ole Sæther <[email protected]>
(cherry picked from commit 5dab1bf)
When mcuboot_secondary is on external flash, the image header cannot
dircetly be accessed via secondary_fa->fa_off. Instead the provided
function boot_img_hdr() is used now.
Additionally a similar issue is present when trying to read the address
of the reset handler. For this flash_area_read() is used now.

With this patch is possible to have the update partiton
mcuboot_secondary on external flash and update a updatable
bootloader (mcuboot) in s0 and/or s1.

Signed-off-by: Christian Taedcke <[email protected]>
Signed-off-by: Ole Sæther <[email protected]>
Signed-off-by: Sigvart Hovland <[email protected]>
Signed-off-by: Dominik Ermel <[email protected]>
(cherry picked from commit 6a56543)
The XIP image, 2, does not have reset vector.

Signed-off-by: Dominik Ermel <[email protected]>
(cherry picked from commit 0bc7d0b)
Puts the flash simulation configurtion into cache variables that can
be used by other applications and CMake code to know specifics on
the simulated flash details

Signed-off-by: Jamie McCrae <[email protected]>
(cherry picked from commit 0452d2e)
This removes the `return;` to ensure that the application is booted even
if EXT_ABI is not provided to the application because it does not
include `FW_INFO`.

Added a bit more description to the error messages when FW_INFO is not
found and EXT_ABI is not able to be provided to the next image.

Ref. NCSDK-24132

Signed-off-by: Sigvart Hovland <[email protected]>
(cherry picked from commit 62aa9fb)
For nRF53, the only existing version number metadata is stored in the
`firmware_info` structure in the network core. This utilizes PCD to read
out the version number and compares it against the version number found
in the secondary slot for the network core.

Ref. NCSDK-21379

Signed-off-by: Sigvart Hovland <[email protected]>
(cherry picked from commit 62468f9)
Change disables GPIO interrupt support in Zephyr GPIO driver,
which is not obligatory for MCUboot.
This is needed to reduce memory footprint.

Signed-off-by: Nikodem Kastelik <[email protected]>
(cherry picked from commit de6763b)
Added configuration which allows to build MCUboot for
nrf54l15pdk_nrf54l15_cpuapp with external flash used for
the secondary slot.

Signed-off-by: Andrzej Puzdrowski <[email protected]>
(cherry picked from commit ae86489)
Seems multi-image dependencies are not supported for multi-image in
NCS yet. This is a workaround which reverts some lines to restore
previous MCUboot behavior, so that Immutable bootloader + MCUBoot type
builds will work.

Ref. NCSDK-8681

Signed-off-by: Sigvart Hovland <[email protected]>
(cherry picked from commit b1f6a8c)
Fixes a missing PCD define check, an image might have the
network core partition layout set but if PCD support is not
enabled then it should not assume that PCD support is part
of mcuboot.

Signed-off-by: Jamie McCrae <[email protected]>
(cherry picked from commit 3ed9b1e)
This adds support for using both NSIB and the multi-image configuration
in MCUboot. Before this was not possible due to upgradable bootloader
support through NSIB was using the `UPDATEABLE_IMAGE_NUMBER`
configuration to update the updateable bootloader.

In this commit we change from using `FLASH_AREA_IMAGE_PRIMARY` to get
the flash area ID to using the bootloader state where we set the flash
area ID of the free updatable bootloader slot if the image is intended
for this slot.

Ref. NCSDK-19223
Ref. NCSDK-23305

Signed-off-by: Sigvart Hovland <[email protected]>
(cherry picked from commit 05b8643)
Making sysflash.h and pm_sysflash.h more readable.

Signed-off-by: Dominik Ermel <[email protected]>
(cherry picked from commit 93222ac)
The commit modifies pm_sysflash.h to add support for three
application images.

Ref. NCSDK-19223

Signed-off-by: Dominik Ermel <[email protected]>
Signed-off-by: Sigvart Hovland <[email protected]>
(cherry picked from commit ee86874)
Added procedure which clean-up content of all the secondary slot
which contains valid header but couldn't be assigned to any of
supported primary images.
This behavior is needed when configuration allows to use one secondary
slot for collecting image for multiple primary slots.

Signed-off-by: Andrzej Puzdrowski <[email protected]>
(cherry picked from commit 02c770e)
FPROTECT is not suppored yet for nrf54l15.

Signed-off-by: Grzegorz Chwierut <[email protected]>
Signed-off-by: Gerard Marull-Paretas <[email protected]>
(cherry picked from commit 30df7db)
Move ifdefs just to not add code for cleanup unusable
slot when direct xip mode is enabled to avoid warnings.

Signed-off-by: Grzegorz Chwierut <[email protected]>
(cherry picked from commit 54afcb2)
Added DTS with partitioning which involves external flash
as place for slo1_partition.

Signed-off-by: Andrzej Puzdrowski <[email protected]>
(cherry picked from commit bfa61d8)
This patch supplements the configuration for external flash so
MCUboot can be build with FILE_SUFFIX="ext_flash" for the nrf54l15pdk
instead of explicitly configuration specification.

Signed-off-by: Andrzej Puzdrowski <[email protected]>
(cherry picked from commit b576e6f)
This patch disbales MCUBoot logging and enables
serial recovery for the Thingy:91.

Signed-off-by: Maximilian Deubel <[email protected]>
Signed-off-by: Bernt Johan Damslora <[email protected]>
(cherry picked from commit a920249)
Mcuboot's boot banner should not be used if NCS boot banner is enabled.

Signed-off-by: Robert Lubos <[email protected]>
(cherry picked from commit 01baf69)
By the upstream patch the vt get now the pointer to the copy
of the arm_vector instead of original.

This patch fixes address of the firmware which is to be taken by
the fw_info_find.

Signed-off-by: Andrzej Puzdrowski <[email protected]>
(cherry picked from commit 52cc9b4)
nvlsianpu and others added 2 commits May 21, 2025 11:19
pointer to the image ARM vector table should be placed out of
stack which is being reconfigured before vt is used for branch
to the application. This caused transient boot failure when
CONFIG_LTO=y.

Moved vt to static data scope.

Signed-off-by: Andrzej Puzdrowski <[email protected]>
(cherry picked from commit 264f6ee)
Enable LTO to cut down the MCUboot size for nrf54l15

Signed-off-by: Dominik Ermel <[email protected]>
(cherry picked from commit 671513c)
@de-nordic de-nordic requested a review from a team June 3, 2025 18:23
Copy link
Contributor

@de-nordic de-nordic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit message missing [nrf noup] tagging.

@de-nordic de-nordic requested a review from a team June 6, 2025 07:39
…image 2

Consider an nRF5340 application with the following sysbuild config:

```
SB_CONFIG_BOOTLOADER_MCUBOOT=y
SB_CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y

SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y

SB_CONFIG_SECURE_BOOT_APPCORE=y
SB_CONFIG_SECURE_BOOT_NETCORE=y

SB_CONFIG_NETCORE_APP_UPDATE=y
SB_CONFIG_MCUBOOT_NRF53_MULTI_IMAGE_UPDATE=y
SB_CONFIG_MCUBOOT_MODE_OVERWRITE_ONLY=y
```

In this case, we have a total of 3 updatable images (app, net, mcuboot).

`MCUBOOT_IMAGE_NUMBER = 2` (i.e. `CONFIG_UPDATEABLE_IMAGE_NUMBER = 2`),
as the app secondary partition is reused for MCUBoot secondary.

`CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER = 2` as the net core image has
index 1.

In this case, we should fall through to the definition of
`ALL_AVAILABLE_SLOTS` that caters for 2 updatable images.
@ball-hayden ball-hayden force-pushed the pm-sysflash-netcore branch from dbf1826 to 5458fb4 Compare June 6, 2025 08:16
Copy link

sonarqubecloud bot commented Jun 6, 2025

@ball-hayden ball-hayden requested a review from de-nordic June 6, 2025 08:18
Copy link
Contributor

@nordicjm nordicjm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what this is trying to fix but it does not look valid, there are 2 images which the application sees, that is application and network core, for MCUboot itself it has it's own update slot, and that is already handled by this code in the same file:

#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1
#ifdef CONFIG_NCS_IS_VARIANT_IMAGE
#define MCUBOOT_S0_S1_SLOTS PM_S0_ID, PM_MCUBOOT_SECONDARY_ID,
#else
#define MCUBOOT_S0_S1_SLOTS PM_S1_ID, PM_MCUBOOT_SECONDARY_ID,
#endif
#else
#define MCUBOOT_S0_S1_SLOTS
#endif

...

static inline uint32_t __flash_area_ids_for_slot(int img, int slot)
{
    static const int all_slots[] = {
        ALL_AVAILABLE_SLOTS
        MCUBOOT_S0_S1_SLOTS
    };
    return all_slots[img * 2 + slot];
};

therefore the change here does not make sense

@ball-hayden
Copy link
Author

ball-hayden commented Jun 10, 2025

Thank you @nordicjm.

Please see https://devzone.nordicsemi.com/f/nordic-q-a/113100/nrf5340-mcuboot-issue-with-multi-image-update-when-sb_config_secure_boot_appcore-is-enabled/537541 for reproduction steps for the issue this is trying to solve.

Without the change, ALL_AVAILABLE_SLOTS ends up being just the app core image slots and does not include the net core image slots.

This is because the conditions on line 34 hold (MCUBOOT_IMAGE_NUMBER == 2 && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1), so we end up ignoring FLASH_AREA_IMAGE_1_SLOTS.

@ball-hayden ball-hayden requested a review from nordicjm June 11, 2025 19:16
@nordicjm
Copy link
Contributor

In this case, we have a total of 3 updatable images (app, net, mcuboot).

MCUBOOT_IMAGE_NUMBER = 2 (i.e. CONFIG_UPDATEABLE_IMAGE_NUMBER = 2), as the app secondary partition is reused for MCUBoot secondary.

I cannot replicate this, taking zephyr/samples/subsys/mgmt/mcumgr/smp_svr and configuring for nrf5340dk/nrf5340/cpuapp with -DSB_CONFIG_NETCORE_EMPTY=y -DSB_CONFIG_NETCORE_APP_UPDATE=y -DSB_CONFIG_SECURE_BOOT_APPCORE=y -DSB_CONFIG_SECURE_BOOT_NETCORE=y -DSB_CONFIG_MCUBOOT_NRF53_MULTI_IMAGE_UPDATE=y yields SB_CONFIG_MCUBOOT_UPDATEABLE_IMAGES=2 and SB_CONFIG_MCUBOOT_ADDITIONAL_UPDATEABLE_IMAGES=1 which means MCUboot gets CONFIG_UPDATEABLE_IMAGE_NUMBER=3, CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER=0, CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER=1 and CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER=2 which means in the .h file it would follow this:

...
#if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1
#ifdef CONFIG_NCS_IS_VARIANT_IMAGE
#else
#define MCUBOOT_S0_S1_SLOTS PM_S1_ID, PM_MCUBOOT_SECONDARY_ID,
...
#elif (MCUBOOT_IMAGE_NUMBER == 2) || (MCUBOOT_IMAGE_NUMBER == 3 && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1)
#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS \
                            FLASH_AREA_IMAGE_1_SLOTS  
...
static inline uint32_t __flash_area_ids_for_slot(int img, int slot)
{
    static const int all_slots[] = {
        ALL_AVAILABLE_SLOTS
        MCUBOOT_S0_S1_SLOTS
    };
    return all_slots[img * 2 + slot];
};

so as can be seen, all 3 images are present and set

Copy link
Contributor

@nordicjm nordicjm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change does not make sense

@ball-hayden
Copy link
Author

ball-hayden commented Jun 13, 2025

Let me expand some macros to demonstrate.

Our desired end result is the following, as we have 2 images to update with MCUboot - the app image (image number 0) and the net image (image number 1) - and the MCUboot image itself (image number 2):

static inline uint32_t __flash_area_ids_for_slot(int img, int slot)
{
    static const int all_slots[] = {
	PM_MCUBOOT_PRIMARY_ID, PM_MCUBOOT_SECONDARY_ID,
        PM_MCUBOOT_PRIMARY_1_ID, PM_MCUBOOT_SECONDARY_1_ID,
	PM_S0_ID, PM_MCUBOOT_SECONDARY_ID,
    };
    return all_slots[img * 2 + slot];
};

From

#define MCUBOOT_IMAGE_NUMBER CONFIG_UPDATEABLE_IMAGE_NUMBER

In the application image, MCUBOOT_IMAGE_NUMBER expands to CONFIG_UPDATEABLE_IMAGE_NUMBER, which expands to 2.

Separately, CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER also expands to 2.

If we expand

#if (MCUBOOT_IMAGE_NUMBER == 1) || (MCUBOOT_IMAGE_NUMBER == 2 && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1)

We get:

#if (2 == 1) || (2 == 2 && 2 != -1)

This falls through to

#define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS

FLASH_AREA_IMAGE_0_SLOTS expands to PM_MCUBOOT_PRIMARY_ID, PM_MCUBOOT_SECONDARY_ID.

This leaves us with __flash_area_ids_for_slot expanding to:

static inline uint32_t __flash_area_ids_for_slot(int img, int slot)
{
    static const int all_slots[] = {
	PM_MCUBOOT_PRIMARY_ID, PM_MCUBOOT_SECONDARY_ID,
	PM_S0_ID, PM_MCUBOOT_SECONDARY_ID,
    };
    return all_slots[img * 2 + slot];
};

This results in MBUboot looking at the MCUBoot secondary slot while deciding whether it should update the net core, rather than looking at PM_MCUBOOT_SECONDARY_1_ID.

@ball-hayden
Copy link
Author

I cannot replicate this, taking zephyr/samples/subsys/mgmt/mcumgr/smp_svr and configuring for nrf5340dk/nrf5340/cpuapp with -DSB_CONFIG_NETCORE_EMPTY=y -DSB_CONFIG_NETCORE_APP_UPDATE=y -DSB_CONFIG_SECURE_BOOT_APPCORE=y -DSB_CONFIG_SECURE_BOOT_NETCORE=y -DSB_CONFIG_MCUBOOT_NRF53_MULTI_IMAGE_UPDATE=y

Using NETCORE_EMPTY isn't really a fair test - the failure case is that the net core image doesn't update, so you wouldn't see this with an empty netcore image.

Please try with ipc_radio as the net core image, adding a VERSION file so you can see the version number change in the logs.

You should see that the process looks like it succeeds, but if you observe the MCUBoot logs you will see that image 1 (the net core image) did not swap when it should have, and the version printed by the net core will not have changed.

@ball-hayden
Copy link
Author

ball-hayden commented Jun 13, 2025

It looks like our main disagreement is over the value of CONFIG_UPDATEABLE_IMAGE_NUMBER.

https://github.com/nrfconnect/sdk-nrf/blob/8854d47ddf22b08e9a0b564fa56f6ffb1579bbf0/sysbuild/CMakeLists.txt#L172-L174

forces this to SB_CONFIG_MCUBOOT_UPDATEABLE_IMAGES.

SB_CONFIG_MCUBOOT_UPDATEABLE_IMAGES defaults to 2 (https://github.com/nrfconnect/sdk-nrf/blob/8854d47ddf22b08e9a0b564fa56f6ffb1579bbf0/sysbuild/Kconfig.mcuboot#L98)

If I set this to 3, as you suggest, I get the following compilation error:

Compiler Error
In file included from /Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/sysflash.h:10,
                 from /Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/bootutil/src/bootutil_priv.h:33,
                 from /Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/bootutil/src/loader.c:42:
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h: In function '__flash_area_ids_for_slot':
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:21:37: error: 'PM_MCUBOOT_PRIMARY_2_ID' undeclared (first use in this function); did you mean 'PM_MCUBOOT_PRIMARY_1_ID'?
   21 | #define FLASH_AREA_IMAGE_2_SLOTS    PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID,
      |                                     ^~~~~~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:46:29: note: in expansion of macro 'FLASH_AREA_IMAGE_2_SLOTS'
   46 |                             FLASH_AREA_IMAGE_2_SLOTS \
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:55:9: note: in expansion of macro 'ALL_AVAILABLE_SLOTS'
   55 |         ALL_AVAILABLE_SLOTS
      |         ^~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:21:37: note: each undeclared identifier is reported only once for each function it appears in
   21 | #define FLASH_AREA_IMAGE_2_SLOTS    PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID,
      |                                     ^~~~~~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:46:29: note: in expansion of macro 'FLASH_AREA_IMAGE_2_SLOTS'
   46 |                             FLASH_AREA_IMAGE_2_SLOTS \
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:55:9: note: in expansion of macro 'ALL_AVAILABLE_SLOTS'
   55 |         ALL_AVAILABLE_SLOTS
      |         ^~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:21:62: error: 'PM_MCUBOOT_SECONDARY_2_ID' undeclared (first use in this function); did you mean 'PM_MCUBOOT_SECONDARY_1_ID'?
   21 | #define FLASH_AREA_IMAGE_2_SLOTS    PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID,
      |                                                              ^~~~~~~~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:46:29: note: in expansion of macro 'FLASH_AREA_IMAGE_2_SLOTS'
   46 |                             FLASH_AREA_IMAGE_2_SLOTS \
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:55:9: note: in expansion of macro 'ALL_AVAILABLE_SLOTS'
   55 |         ALL_AVAILABLE_SLOTS
      |         ^~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:22:37: error: 'PM_MCUBOOT_PRIMARY_3_ID' undeclared (first use in this function); did you mean 'PM_MCUBOOT_PRIMARY_1_ID'?
   22 | #define FLASH_AREA_IMAGE_3_SLOTS    PM_MCUBOOT_PRIMARY_3_ID, PM_MCUBOOT_SECONDARY_3_ID,
      |                                     ^~~~~~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:47:29: note: in expansion of macro 'FLASH_AREA_IMAGE_3_SLOTS'
   47 |                             FLASH_AREA_IMAGE_3_SLOTS
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:55:9: note: in expansion of macro 'ALL_AVAILABLE_SLOTS'
   55 |         ALL_AVAILABLE_SLOTS
      |         ^~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:22:62: error: 'PM_MCUBOOT_SECONDARY_3_ID' undeclared (first use in this function); did you mean 'PM_MCUBOOT_SECONDARY_1_ID'?
   22 | #define FLASH_AREA_IMAGE_3_SLOTS    PM_MCUBOOT_PRIMARY_3_ID, PM_MCUBOOT_SECONDARY_3_ID,
      |                                                              ^~~~~~~~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:47:29: note: in expansion of macro 'FLASH_AREA_IMAGE_3_SLOTS'
   47 |                             FLASH_AREA_IMAGE_3_SLOTS
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~
/Users/hayden/development/PlayerData/live_gateway/bootloader/mcuboot/boot/zephyr/include/sysflash/pm_sysflash.h:55:9: note: in expansion of macro 'ALL_AVAILABLE_SLOTS'
   55 |         ALL_AVAILABLE_SLOTS
      |         ^~~~~~~~~~~~~~~~~~~

This makes sense, as there are no flash slots for image 2 - image 2 is MCUboot, so should be sharing the other partitions, as you've said earlier.

It's worth calling out that CONFIG_UPDATEABLE_IMAGE_NUMBER is different between the app image and mcuboot.

This means some of the functions from bootutil_public.h behave differently to how we might expect.

@ball-hayden
Copy link
Author

Change does not make sense

Yes. The whole thing does not make sense. I was very confused. I'm still very confused. The indirection is massive, and it took me several days to come to the proposed solution.

@nvlsianpu
Copy link
Contributor

@ball-hayden this looks like an issue on DFU application side - as reverse of staging image for update made the difference.
The activation of each image (i do believe this is image test or image confirm command) set dedicated flag(s) in image trailer (mcuboot's image control data) in FLASH. These fields are read by MCUboot just after the reboot. Looks like somewhy these fields values are different when image activation order is changed (which is a bug).

@ball-hayden
Copy link
Author

I'm glad you've been able to see the issue @nvlsianpu.

I still feel like from the application image the images are being incorrectly reported, but I'm happy to accept suggestions for different approaches here.

@ball-hayden
Copy link
Author

For context, I've used both the nRF Connect app (on iOS and Android) and https://pypi.org/project/smpclient/ while debugging this.

The higher-level MCUMgr Image Group definitely thinks it has set both image 0 and 1 to the test slot, but when MCUBoot is reading the image trailers it finds that image 0 is set to test, but image 1 is not.

@nvlsianpu
Copy link
Contributor

@ball-hayden Issue is somewhere in libraries used by the application. I confirmed this with Nordic verification team. Known workaround is sequence of image activation you already discovered.

@nvlsianpu
Copy link
Contributor

We will take action for fixing the bug.

@ball-hayden
Copy link
Author

ball-hayden commented Aug 3, 2025

@nvlsianpu do you have an update to share on fixing the bug please?

@ball-hayden
Copy link
Author

@rlubos I think the diff has got confused here - was that intentional?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.