Fixing the "known issue" Partitioning limitation with MCUboot swap move

The subject issue is documented here as "NCSDK-20567: Partitioning limitation with MCUboot swap move":


This issue has been open for while. 

These two DevZone tickets refer to this issue and mention the impact is that you can use only around 95% of the flash space:
1. https://devzone.nordicsemi.com/f/nordic-q-a/112343/mcuboot-image-in-the-primary-slot-is-not-valid-unable-to-find-bootable-image

2. https://devzone.nordicsemi.com/f/nordic-q-a/107599/mcuboot-sign-image-possible-wrong-slot-size/475558

Here are my questions:

1. In the Workaround description, there is a formula to calculate the approximate size limitation. What CONFIG item is referred to for mcuboot_primary_size?  I am not able to figure out how to use that equation to result in a value of approximately 95% of the "Region Size" for the application image indicated in the build log.

2. Why is "additional" margin suggested?  Can that margin be quantified?

3. Are there still plans to fix this?  A lot of internal flash space seems to be wasted due to this issue.

4. When the fix is available, do you think the fix can be patched by us to an earlier NCS version, such as NCS 2.6?

  • I think we are mistaking binary with mcuboot image, these are different things:

    the top one is binary, that is the thing build logs size form; the bottom one is image, that is uploaded to the device.
    Once your image is signed there is additional information added to it, and build log does not show that info.
    For experiment I have appended my binary with enough data to fill, after signing, entire slot - 2 * 4096 bytes, and that worked fine. But I have been using equal slot sizes, that is why I have to subtract on slot for move area and one for trailer rounded up to one slot.
    In primary slot trailer may not be written in the same page as the swapped in image is.

    In secondary slot trailer may be written to the same page as uploaded, because there is no "move" page between trailer and image.
    The move page needs to be erased independently, so it can not be either part of image nor trailer.
    But that image will be swapped to the primary slot, and at that point that slot has to be able to

    It seems that you have CONFIG_BOOT_MAX_IMG_SECTORS=256, the nrf5340 has a 4096B page and 4B write block, 974848 primary slot.

    The 974848 takes 238 slots, so 238 * 3 * 4 + 80 = 2936 ~= 4096
    So primary slot can take max 974848  - 2 * 4096 = 966656

    Please check your PM_MCUBOOT_SECONDARY_SIZE, because it seems that this is significantly shorter. The trailer equation will only work with the secondary slot, because here the trailer can touch the last page of binary, something it can not do in primary slot.

  • Hi   - I work with  , trying to catch up on this thread...

    Q1) What do you mean when you say: "Please check your PM_MCUBOOT_SECONDARY_SIZE, because it seems that this is significantly shorter."? Shorter than what?

    In partitions.yml, I see mcuboot_secondary: size: 0xee000 (974848 bytes).

    Just to make sure I'm understanding correctly:

    1) Primary Slot Size: has to contain the image + trailer + 1 page for move page

    2) BOOT_MAX_IMG_SECTORS must be larger than: ( Largest Image Slot Size ) / Erase Page Size

    3) Erase Page Size = 4kBytes for the NRF5340

    4) Trailer Size (bytes) = ( BOOT_MAX_IMG_SECTORS * Block Size ) * 3 + 80

    So for the nRF5340:

    5) We start with a primary image slot size = 974848 bytes (0xEE000)

    6) BOOT_MAX_IMG_SECTORS >= 238 = 974848 / 4096

    7) Given that the trailer is 4096 bytes, this gives us a useable space of 966656 bytes. 

    Q2) However, because of the MCUBOOT pad, should we actually start with 974336 bytes as the primary image slot size? That is address space of 0x10200 to 0xFE000.

    Q3) Also, why is there not a general recommended BOOT_MAX_IMG_SECTORS configuration for any nRF5340 project? Would 256 always be the recommended number of sectors?

    Thank you!

    Tristan

  • 1) Primary Slot Size: has to contain the image + trailer + 1 page for move page
    Yes, trailer is rounded to N pages, where page is 4096 bytes (min for hardware)

    2) BOOT_MAX_IMG_SECTORS must be larger than: ( Largest Image Slot Size ) / Erase Page Size
    Yes. Because BOOT_MAX_IMG_SECTORS determines size of swap log size. You are swapping BOOT_MAX_IMG_SECTORS  at most, which is slot size/page size

    3) Erase Page Size = 4kBytes for the NRF5340
    Yes,; when external mem is used, the bigger size is used, but it can not be less than physical limitation of any of memories (4k is min for nrf53/nrf52)

    4) Trailer Size (bytes) = ( BOOT_MAX_IMG_SECTORS * Block Size ) * 3 + 80

    Block size == Write block size (4 bytes); yes, but rounded up to pages. MCUboot has to copy/erase by pages.

    5) We start with a primary image slot size = 974848 bytes (0xEE000)

    OK

    6) BOOT_MAX_IMG_SECTORS >= 238 = 974848 / 4096

    ok

    7) Given that the trailer is 4096 bytes, this gives us a useable space of 966656 bytes.

    should

    Q2) However, because of the MCUBOOT pad, should we actually start with 974336 bytes as the primary image slot size? That is address space of 0x10200 to 0xFE000.

    No.The pad is just shifting application image by the size required for image header, but header is part of the image that is being moved around. This thing is for compiler/linker to figure out where code actually should start. After you build application the 0x200 bytes are added in front of by imgtool when image is signed. There is another chunk of data added at the end in form of TLV that store info like signature. The real size that is swapped between slots is what you see as app_update.bin (or zephyr.signed.bin), not the thing that build reports in the end.

    Q3) Also, why is there not a general recommended BOOT_MAX_IMG_SECTORS configuration for any nRF5340 project? Would 256 always be the recommended number of sectors?

    Generally 256 is ok if size of slot is < 1MiB. As you can see this has to round up to a page anyway, and 256 logs take up to 3072 so plenty more space to fit the rest of trailer. The space gets shorter when using encryption (because keys are also dropped there), in which case you may wan to cut the the BOOT_MAX_IMG_SECTORS to actual size, to not take another page.

    The best way to test your setup is build your app, check size difference between signed and unsigned. Then add, to the end of binary, enough bytes to fill the slot, save the header (0x200), the difference checked above and - 2* 4096 in pages. Now when you sign what you have you should have signed binary of size of slot - 2* 4096 bytes; that thing should correctly upload to device and swap into primary slot.

Related