MCUBoot, Zephyr, and static partition manager

Hi!
We are currently migrating our SD-based SDK code to Zephyr, on nrf52833 boards.

While we have finally been able to get MCUBoot (CONFIG_BOOTLOADER_MCUBOOT=y) to run with a static partition file, we consistently get the following log on runtime, and the app is never started:

00> *** Booting Zephyr OS build v3.2.99-ncs1 ***
00> I: Starting bootloader
00> W: Failed reading sectors; BOOT_MAX_IMG_SECTORS=128 - too small?
00> W: Cannot upgrade: not a compatible amount of sectors
00> E: Unable to find bootable image

I have a few questions regarding this:

  1. I have created the partition manager file (pm_static.yml) from the original build of our project, and added partitions to match our dts overlay (both are at bottom). The default setup causes s.t. the bootloader. which is much smaller than the default of 0xC000 = 48 KB for MCUboot, to sit apart from the mcuboot_pad and the app more than needed (see picture from nrfConnect Programmer below). What is the correct way to work with this?
  2. If I try to remove the mcuboot_pad totally, I consistently receive a failure of the static partition manager on build: "Partition manager failed: End of last partition is after last valid address". Why is this? Is the pad a must?
  3. In the default partition manager (As you can see below), alignment is consistently used ("align: start: 0x1000"). Is there a specific reason for this?
  4. The big one - what is the reason that the aforementioned mcuboot print is received?

Thanks ahead of time!

Roi

pm_static.yml:

app:
  address: 0xc200
  end_address: 0x3e000
  region: flash_primary
  size: 0x31e00
mcuboot:
  address: 0x0
  end_address: 0xc000
  placement:
    before:
    - mcuboot_primary
  region: flash_primary
  size: 0xc000
mcuboot_pad:
  address: 0xc000
  end_address: 0xc200
  placement:
    align:
      start: 0x1000
    before:
    - mcuboot_primary_app
  region: flash_primary
  size: 0x200
mcuboot_primary:
  address: 0xc000
  end_address: 0x3e000
  orig_span: &id001
  - mcuboot_pad
  - app
  region: flash_primary
  sharers: 0x1
  size: 0x32000
  span: *id001
mcuboot_primary_app:
  address: 0xc200
  end_address: 0x3e000
  orig_span: &id002
  - app
  region: flash_primary
  size: 0x31e00
  span: *id002
mcuboot_secondary:
  address: 0x3e000
  end_address: 0x70000
  placement:
    after:
    - mcuboot_primary
    align:
      start: 0x1000
  region: flash_primary
  share_size:
  - mcuboot_primary
  size: 0x32000
scratch_partition:
  address: 0x70000
  end_address: 0x7a000
  placement:
    align:
      start: 0x1000
  region: flash_primary
  size: 0xa000
settings_storage:
  address: 0x7a000
  end_address: 0x7c000
  placement:
    align:
      start: 0x1000
  region: flash_primary
  size: 0x2000
storage_partition:
  address: 0x7c000
  end_address: 0x80000
  placement:
    align:
      start: 0x1000
  region: flash_primary
  size: 0x4000
sram_primary:
  address: 0x20000000
  end_address: 0x20020000
  region: sram_primary
  size: 0x20000
dts overlay:
/delete-node/ &storage_partition;
&flash0 {

partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;

boot_partition: partition@0 {
label = "mcuboot";
reg = <0x00000000 0xC000>;
};
slot0_partition: partition@c000 {
label = "image-0";
reg = <0x0000C000 0x32000>;
};
slot1_partition: partition@3e000 {
label = "image-1";
reg = <0x0003E000 0x32000>;
};
scratch_partition: partition@70000 {
label = "image-scratch";
reg = <0x00070000 0xA000>;
};
settings_partition: partition@7a000 {
label = "settings";
reg = <0x0007A000 0x00002000>;
};
storage_partition: partition@7c000 {
label = "storage";
reg = <0x0007c000 0x00004000>;
};
};
};
mcuboot.conf (merged via edit to CMakeLists):
CONFIG_DISABLE_FLASH_PATCH=y
CONFIG_BOOT_SIGNATURE_KEY_FILE="/mcuboot/skey.pem"
CONFIG_UART_CONSOLE=n
CONFIG_LOG_BACKEND_UART=n
CONFIG_LOG=y
CONFIG_LOG_MODE_MINIMAL=y
CONFIG_PRINTK=n
CONFIG_LOG_PRINTK=n
CONFIG_STDOUT_CONSOLE=n
CONFIG_RTT_CONSOLE=y
CONFIG_BOOT_BANNER=y
CONFIG_USE_SEGGER_RTT=y
Parents
  • Hi,

    I took the liberty to clean up your post using Insert->Code.

    For us to help you with this in the best possible way, please list the following information:

    • SDK Version
    • Development Kit Version
    • Do you use custom hardware or code?

    Tip:
    VS Code -> Memory Report -> Partitions is handy for looking at MCUboot partitioning.
    I took your configurations and added them to the hello world example. v2.2.0, nrf52833dk_nrf52833.
    Then from Actions->Memory Report->Partitions:

    Alternatively, I personally prefer the command line: "west build -t partition_manager_report":

    Now, onto your questions:

    I have created the partition manager file (pm_static.yml) from the original build of our project, and added partitions to match our dts overlay (both are at bottom). The default setup causes s.t. the bootloader. which is much smaller than the default of 0xC000 = 48 KB for MCUboot, to sit apart from the mcuboot_pad and the app more than needed (see picture from nrfConnect Programmer below). What is the correct way to work with this?

    You can change the size of the MCUboot partition in the static partitioning.
    From the build log, we can see how much space your MCUboot image is using:

    Memory region         Used Size  Region Size  %age Used
               FLASH:       34652 B        48 KB     70.50%
                 RAM:       23808 B       128 KB     18.16%
            IDT_LIST:          0 GB         2 KB      0.00%

    I suggest you try configuring MCUboot to use less space and then set the partition to 32KiB (0x8000).
    Yes, changing the partition size means you must manually move all the other partitions.
    See the prj.conf of the machine learning example for tips on decreasing the footprint.

    FYI: Do not give up on static partitioning, though. If you use a single bootloader, static partitioning is mandatory.

    If I try to remove the mcuboot_pad totally, I consistently receive a failure of the static partition manager on build: "Partition manager failed: End of last partition is after last valid address". Why is this? Is the pad a must?

    I think the pad is where MCUboot stores metadata about images.
    So yes, you must use mcuboot_pad.

    In the default partition manager (As you can see below), alignment is consistently used ("align: start: 0x1000"). Is there a specific reason for this?

     Is it possible to change the flash page size of nrf52

    For the FICR.INFO.CODEPAGESIZE for nrf5340, it says it should be 0x1000. I kind of would expect the same in FICR.CODEPAGESIZE for the nrf52833, but it is not. Unsure if it is possible to change it or if this is a documentation bug.
    However, I think it is a good idea to align it with 0x1000 either way, as I think most of our partitioning does this by default, and it can be argued using 0x1000 alignment will make the project more portable.

    The big one - what is the reason that the aforementioned mcuboot print is received?

    In my experience, the error  "W: Failed reading sectors; BOOT_MAX_IMG_SECTORS=128 - too small?" can mean two things:

    1. CONFIG_BOOT_MAX_IMG_SECTORS is too small. Try setting this to 256 in mcuboot.conf.
    2. The external flash driver has not been initialized for MCUboot.
      Have you configured Using external flash memory partitions, and more specifically, External flash memory partitions?

    Regards,
    Sigurd Hellesvik

  • OK, but if I remove the flash redefinition entirely, the settings_partition will no longer exist, and I will not be able to choose it for settings in "chosen"

  • I will have a look at how to do that, but first:

    Quick question: What do you intend to use settings for?
    NVS? Bluetooth? Something else?

    Regards,
    Sigurd Hellesvik

  • From Bluetooth Persistent storage:

    CONFIG_BT_SETTINGS=y
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    CONFIG_NVS=y
    CONFIG_SETTINGS=y

    I also find these configurations in many of our Bluetooth samples

    If I build the hello world sample with these configurations:

    CONFIG_BOOTLOADER_MCUBOOT=y
    CONFIG_BT=y
    
    CONFIG_BT_SETTINGS=y
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    CONFIG_NVS=y
    CONFIG_SETTINGS=yONFIG_SETTINGS=y
    

    I get the following partition_manager_report:

      flash_primary (0x100000 - 1024kB): 
    +-------------------------------------------------+
    | 0x0: mcuboot (0xc000 - 48kB)                    |
    +---0xc000: mcuboot_primary (0x79000 - 484kB)-----+
    | 0xc000: mcuboot_pad (0x200 - 512B)              |
    +---0xc200: mcuboot_primary_app (0x78e00 - 483kB)-+
    | 0xc200: app (0x78e00 - 483kB)                   |
    +-------------------------------------------------+
    | 0x85000: mcuboot_secondary (0x79000 - 484kB)    |
    | 0xfe000: settings_storage (0x2000 - 8kB)        |
    +-------------------------------------------------+
    
      sram_primary (0x40000 - 256kB): 
    +--------------------------------------------+
    | 0x20000000: sram_primary (0x40000 - 256kB) |
    +--------------------------------------------+
    

    I see that with this, I can still not select it as chosen.

    But I think you do not need to choose it, as Bluetooth LE will use this to store its persistent data at that point automatically.

    Does that fix your issue?

    Regards,
    Sigurd Hellesvik

  • I fear not - because I am still receiving "bt_settings: settings_subsys_init failed (err -45)"

Reply Children
Related