MCUBoot runtime error: "Cannot upgrade: not a compatible amount of sectors" with external flash on nrf9160

Hi,

I am using NCS 2.1.2 with the [email protected] (but I have tested with 2.2.0-rc1 and it doesn't change anything). I have attached a simple example which should just place the MCUBoot secondary partition in the external flash with pm_static.yml. I am using the firmware here: https://github.com/simon-iversen/sdk-nrf/tree/d1a11f2c39e3b8fb0af7652e7e720626f0e1298e/samples/nrf9160/http_update/application_update to connect the NOR flash to the nrf91.

This appears to compile fine, but, on bootup I get the following errors printed by the bootloader:

W: Failed reading sectors; BOOT_MAX_IMG_SECTORS=256 - too small?
W: Cannot upgrade: not a compatible amount of sectors

On stepping through the code, it appears that the flash_area_get_sectors function is returning -22 (EINVAL) for the secondary partition on the external flash because flash_area_open is failing with -19 (ENODEV). However, I know that the flash is working fine because (in the second example attached) littlefs on the external flash formats and mounts correctly.

I found in another thread this fix for a similar problem: https://github.com/nrfconnect/sdk-nrf/pull/9169/files# (I unfortunately cannot find the thread again) but I have applied this patch and it does not seem to change anything.

Could you please help me understand what the problem is here?

Thanks,

Jeremy

8156.nrf9160dk_extflash_mcuboot.zip

  • File attached below:

    6076.nrf9160dk_extflash_mcuboot_littlefs.zip

    The DT_CHOSEN line from that patch is already present in 2.2.0-rc1 and the build already has the PM_OVERRIDE config - that one took me many days of time to find on its own ;)

    This is the output from 2.2.0-rc1:

    *** Booting Zephyr OS build v3.2.99-ncs1-rc1 ***
    I: Starting bootloader
    W: Failed reading sectors; BOOT_MAX_IMG_SECTORS=256 - too small?
    W: Cannot upgrade: not a compatible amount of sectors
    I: Bootloader chainload address offset: 0x10000

    Thanks,

    Jeremy

  • Also I noticed that the pm_static.yml doesn't have the same size for the mcuboot_primary and mcuboot_secondary partitions. I guess the "share_size" directive is either being ignored or doesn't do what I expect it to do, and I can't find any documentation on it (I just took it from the autogenerated partitions.yml).

    I have attached a fixed version of the test project for reference, the only change is the partition size in pm_static.yml

    nrf9160dk_extflash_updated.zip

    Thanks,

    Jeremy

  • One other thing I forgot to add: I deleted the pm_static.yml file and added to prj.conf:

    CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y

    But still see the same output. The secondary partition is definitely being put in the external flash though with the fix you linked to:

    mcuboot:
      address: 0x0
      end_address: 0xc000
      placement:
        before:
        - mcuboot_primary
      region: flash_primary
      size: 0xc000
    mcuboot_pad:
      address: 0x10000
      end_address: 0x10200
      placement:
        align:
          start: 0x8000
        before:
        - mcuboot_primary_app
      region: flash_primary
      size: 0x200
    mcuboot_primary:
      address: 0x10000
      end_address: 0x100000
      orig_span: &id001
      - mcuboot_pad
      - app
      - tfm
      region: flash_primary
      size: 0xf0000
      span: *id001
    mcuboot_primary_app:
      address: 0x10200
      end_address: 0x100000
      orig_span: &id002
      - app
      - tfm
      region: flash_primary
      size: 0xefe00
      span: *id002
    mcuboot_secondary:
      address: 0x0
      device: DT_CHOSEN(nordic_pm_ext_flash)
      end_address: 0xf0000
      placement:
        align:
          start: 0x4
      region: external_flash
      share_size:
      - mcuboot_primary
      size: 0xf0000

  • Hi Jeremy,

    I suspect that I know what your error is.

    You need to have a child_image/mcuboot/boards/nrf9160dk_nrf9160.overlay file to set the devicetree for the external flash in mcuboot as well.

    It has to be nrf9160dk_nrf9160.overlay  and not nrf9160dk_nrf9160_ns.overlay because mcuboot runs in the secure world.

    To test this, I created  project which enables mcuboot with external flash for the nRF9160DK.
    The configurations of this project is a bit messy, but I did not want to delete any which I commented out.
    This is because I got all the configurations here from Marshall in this answer.

    Board: [email protected]
    nRF Connect SDK: v2.2.0-rc1
    Enable external flash for the nRF9160: Simons sample
    Project:nrf9160_external_flash_mcuboot.zip

    Does this work for you?

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd,

    Thanks! I have it working now. It seems that there were a few issues here:

    1. The DT_CHOSEN issue that is fixed in 2.2.0-rc1

    2. For the mcuboot build, it doesn't search for board overlays in the "boards" directory, only in "child_image/boards". I did have a secure overlay in the boards dir, but it didn't pick that up.

    3. If you don't have the *exact* same size partition for mcuboot_primary and mcuboot_secondary partitions (even if the secondary is much bigger than necessary) then mcuboot gives the error "W: Cannot upgrade: not a compatible amount of sectors". So if you define mcuboot_secondary in the pm_static.yml file, you must also define mcuboot_primary otherwise the PM could change the partition size without you knowing.

    It seems point 1 is already fixed. For point 2, can I suggest adding something to the documentation about this? For point 3, even though it is incorrect to have different partition sizes, I do think it is a bug that compilation is successful, seeing as it can never work anyway, and this problem can be checked at compile time. What does the "share_size" directive in pm_static.yml do if not require them to be the same? Like this:

    mcuboot_secondary:
      address: 0x0
      device: MX25R64
      end_address: 0x100000
      placement:
        align:
          start: 0x4
      region: external_flash
      share_size:
      - mcuboot_primary
      size: 0x100000

    except that "share_size" doesn't appear to actually do anything.

    I really appreciate your help on this!

    Thanks,

    Jeremy

Related