west build generates large EMPTY partitions

I am trying to make a build with a slightly modified copy of the Zephyr button example on a nrf9160 board with a upgradable bootloader.

The following command can build our firmware:

west build --build-dir build/SG1500-board-tester --board ${BOARD}_ns SG1500-board-tester --pristine -- \
-DCONFIG_SECURE_BOOT=y \
-DCONFIG_BOOTLOADER_MCUBOOT=y \
-DCONFIG_BUILD_S1_VARIANT=y \
-Db0_CONF_FILE=prj_minimal.conf \
-Dmcuboot_CONF_FILE=${HOME}/ncs/v2.0.2/bootloader/mcuboot/boot/zephyr/prj_minimal.conf \
-DCONF_FILE:STRING="${BUILD_ROOT}/SG1500-board-tester/prj.conf"

I added 2 partitions by making a pm_static.yml:

data_partition_flash:
  address: 0xf0000
  end_address: 0x100000
  region: flash_primary
  size: 0x10000
data_partition_sram:
  address: 0x20020000
  end_address: 0x20040000
  region: sram_primary
  size: 0x20000

Compiling this result in BO size:

Memory region         Used Size  Region Size  %age Used
           FLASH:       12240 B        32 KB     37.35%
            SRAM:       37088 B      47896 B     77.43%
        IDT_LIST:          0 GB         2 KB      0.00%

For mcuboot this results in:

Memory region         Used Size  Region Size  %age Used
           FLASH:       18916 B        32 KB     57.73%
            SRAM:       18120 B      47896 B     37.83%
        IDT_LIST:          0 GB         2 KB      0.00%

This seems to work fine but the partition_manager_report reserved show that a lot of memeory is wasted: too much space is reserved for the bootloaders and it has very large EMPTY_X regions:

+--------------------------------------------------+
+---0x0: b0_container (0x8000 - 32kB)--------------+
| 0x0: b0 (0x8000 - 32kB) |
+---0x8000: s0 (0x8200 - 32kB)---------------------+
| 0x8000: s0_pad (0x200 - 512B) |
+---0x8200: s0_image (0x8000 - 32kB)---------------+
| 0x8200: mcuboot (0x8000 - 32kB) |
+--------------------------------------------------+
| 0x10200: EMPTY_0 (0x7e00 - 31kB) |
+---0x18000: s1 (0x8200 - 32kB)--------------------+
| 0x18000: s1_pad (0x200 - 512B) |
| 0x18200: s1_image (0x8000 - 32kB) |
+--------------------------------------------------+
| 0x20200: EMPTY_1 (0x7e00 - 31kB) |
+---0x28000: mcuboot_primary (0x60000 - 384kB)-----+
+---0x28000: tfm_secure (0x8200 - 32kB)------------+
| 0x28000: mcuboot_pad (0x200 - 512B) |
+---0x28200: app_image (0x5fe00 - 383kB)-----------+
+---0x28200: mcuboot_primary_app (0x5fe00 - 383kB)-+
| 0x28200: tfm (0x8000 - 32kB) |
+---0x30200: tfm_nonsecure (0x57e00 - 351kB)-------+
| 0x30200: app (0x57e00 - 351kB) |
+--------------------------------------------------+
| 0x88000: mcuboot_secondary (0x60000 - 384kB) |
| 0xe8000: EMPTY_2 (0x8000 - 32kB) |
| 0xf0000: data_partition_flash (0x10000 - 64kB) |
+--------------------------------------------------+

otp (0x2f4 - 756B):
+------------------------------------+
| 0xff8108: provision (0x280 - 640B) |
| 0xff8388: otp (0x74 - 116B) |
+------------------------------------+

sram_primary (0x40000 - 256kB):
+---------------------------------------------------+
+---0x20000000: sram_secure (0x10000 - 64kB)--------+
| 0x20000000: tfm_sram (0x10000 - 64kB) |
+---0x20010000: sram_nonsecure (0x10000 - 64kB)-----+
+---0x20010000: nrf_modem_lib_sram (0x44e8 - 17kB)--+
| 0x20010000: nrf_modem_lib_ctrl (0x4e8 - 1kB) |
| 0x200104e8: nrf_modem_lib_tx (0x2000 - 8kB) |
| 0x200124e8: nrf_modem_lib_rx (0x2000 - 8kB) |
+---------------------------------------------------+
| 0x200144e8: sram_primary (0xbb18 - 46kB) |
| 0x20020000: data_partition_sram (0x20000 - 128kB) |
+---------------------------------------------------+

I have no former experience using zephyr so i have no clue why this happens, so please can somebody explain:

  1. what are those empty reqions used for? How can they be made minimal?
  2. the wasted space looks like an alignment issue.
    1. why is the reserved space for the bootloaders much larger then the bootloader code size?
    2. How can i change this so no memory will be wasted?
Parents
  • Hi,

    The SPU splits the flash into 32kB regions.

    Looking at your flash partitioning, you have the first region taken by the b0.

    Then, you have s0_pad, which does not take a whole region.

    MCUBoot, which resides in s0_image takes a whole region, and then the next region, s1_image needs to start at the boundary of a new region. This causes the first empty region.

    We have a similar situation for s1. The s1_pad takes less than one region, while s1_image takes exactly one region. This causes another empty region to be placed before we get to the application images, mcuboot_primary and mcuboot_secondary.

    Because mcuboot_primary and mcuboot_secondary must be of equal size, we now have an uneven number of regions used, and 3 regions left in total. Your data_partition_flash partition uses the last 2 of these regions, leaving a single region left unused.

    I am not aware of any good way of reducing the first two empty regions. However, the third empty region (EMPTY_2) can be used as an extra partition, or you can increase the size of the data_partition_flash partition.

    Best regards,

    Didrik

  • Thanks.

    Unfortunately wasting this much memory is not an option for us.

    We only think we need the upgradable bootloader be able to update the encryption/signing keys of FOTA images. Do we indeed need an upgradeble bootloader for that or can that be done in another way?

  • maarten v said:
    We only think we need the upgradable bootloader be able to update the encryption/signing keys of FOTA images. Do we indeed need an upgradeble bootloader for that or can that be done in another way?

    Yes, having an upgradable bootloader is the only way to do it securely.

    There are a couple of other possibilities though:

    1. If you can reduce the size of the data_flash_partition with 32kB, that will give the application 32kB, and remove the EMPTY_2 partition (one 32kB goes to the primary slot, the other 32kB goes to the secondary slot).

    2. If you add an external flash, you can move the secondary slot to the external flash. This will let you double the size and add 32kB for the application (the extra 32kB comes from the EMPTY_2 partition), and if you also move the data_flash_partition to the external flash, you free up another 64kB for the application.

    3. I don't know how well this will work in practice, but at least in theory, you might be able to modify CONFIG_PM_PARTITION_SIZE_MCUBOOT and CONFIG_PM_PARTITION_SIZE_MCUBOOT_PAD, so their sum is <= 32kB, while still fitting all the information they need. If you manage that, that should remove the need for the EMPTY_0 and EMPTY_1 partitions.

  • Thank you for the clarification.

    I already found CONFIG_PM_PARTITION_SIZE_MCUBOOT and CONFIG_PM_PARTITION_SIZE_MCUBOOT_PAD and the EMPTY_0 and EMPTY_1 partitions are now minimal.

    I understand now, the mcuboot_primary and mcuboot_secondary will get the same size resulting in an empty_2 partition. So i can either reduce or enlarge the data_partition_flash by 32k to get rid of the EMPTY_2 partition. Ill try that later.

Reply
  • Thank you for the clarification.

    I already found CONFIG_PM_PARTITION_SIZE_MCUBOOT and CONFIG_PM_PARTITION_SIZE_MCUBOOT_PAD and the EMPTY_0 and EMPTY_1 partitions are now minimal.

    I understand now, the mcuboot_primary and mcuboot_secondary will get the same size resulting in an empty_2 partition. So i can either reduce or enlarge the data_partition_flash by 32k to get rid of the EMPTY_2 partition. Ill try that later.

Children
No Data
Related