Not enough free space to run swap upgrade - understanding the numbers

Hi,

Recently in our application we hit the following problem that has been already raised on the DevZone (we use NCS 2.4.1):

[00:00:00.471,313] <wrn> mcuboot: Not enough free space to run swap upgrade
[00:00:00.471,343] <wrn> mcuboot: required 86016 bytes but only 77824 are available

This happens when attempting to upgrade mcuboot image with the signed_by_mcuboot_and_b0_s1_image_update.bin (we have b0 NSIB enabled), but to my understanding this could happen with the application image as well.

I'm aware of the following issue:

https://github.com/zephyrproject-rtos/zephyr/issues/58103

and the resolution that was integrated with sysbuild (only).

https://github.com/zephyrproject-rtos/zephyr/pull/64586

https://github.com/zephyrproject-rtos/mcuboot/commit/4c7942e58c5458ce3c4e50d3169e0f865910fe87

This seems well justified considering the mcuboot's overhead required for swap with move (1 extra sector to be able to move image and some metadata/trailer):

https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/mcuboot/design.html#swap-without-using-scratch

We ported the 4c7942e58c5458ce3c4e50d3169e0f865910fe87 mcuboot contribution to our project to do some testing. It works, however I'd like to better understand numbers we see because they look weird to me.

I added some extra logs to the mcuboot after porting the aforementioned commit and to the mcuboot's swap_run() function. This is what I got:

bootloader/mcuboot/boot/zephyr/CMakeLists.txt:

MCUBoot bootloader key file: .../child_image/es_key.pem
################# {key_size}:  ###################### 0
################# {boot_magic_size}:  ###################### 16
################# {boot_swap_data_size}:  ###################### 32
################# {boot_status_data_size}:  ###################### 6144
################# {boot_tlv_estimate}:  ###################### 150
################# {write_size}:  ###################### 8
################# {erase_size}:  ###################### 4096
################# {final_required_size}: ###################### 12288
-- Configuring done

mcuboot's swap_run(:

[00:00:00.471,252] <wrn> mcuboot: ##### sector_sz:4096 #####
[00:00:00.471,252] <wrn> mcuboot: ##### trailer_sz:3120 #####
[00:00:00.471,282] <wrn> mcuboot: ##### first_trailer_idx:19 #####
[00:00:00.471,282] <wrn> mcuboot: ##### last_idx:20 #####
[00:00:00.471,313] <wrn> mcuboot: Not enough free space to run swap upgrade
[00:00:00.471,343] <wrn> mcuboot: required 86016 bytes but only 77824 are available

And here comes the mcuboot compilation summary:

Memory region         Used Size  Region Size  %age Used
           FLASH:         77 KB      81408 B     96.86%
             RAM:       28480 B       256 KB     10.86%
        IDT_LIST:          0 GB         2 KB      0.00%

Now, it looks like the calculated final_required_size is 12k, so I's guess, the final slot size needed to accommodate the swap operation and mcuboot metadata should be 77KB + 12KB = 89KB. Why is the real required size then 86K (86016 from the device's console)? I know that the check in the build system only estimates the size of the TLVs but I'd say this is not so relevant and I suspect that it has something to do with the trailer size which is calculated differently by the build system (code from a4eda30f5b0cfd0cf15512be9dcd559239dbfc91 integrated in our project) and the firmware at runtime - interestingly enough, the difference is 3KB, exactly the same as the difference between the calculated and real required size.

BTW. Why does the https://github.com/zephyrproject-rtos/mcuboot/commit/4c7942e58c5458ce3c4e50d3169e0f865910fe87 skip the following when calculating the resulting required size?

    |   Swap info   |  0xff padding (BOOT_MAX_ALIGN minus 1 octet)  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |   Copy done   |  0xff padding (BOOT_MAX_ALIGN minus 1 octet)  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |   Image OK    |  0xff padding (BOOT_MAX_ALIGN minus 1 octet)  |

https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/mcuboot/design.html#image-trailer

To my understanding these fields should be included as well. Do I get something wrong here?

Thanks in advance for any help.

G

Related