MCUboot flash overflow

Hello,
I am encountering a flash overflow issue in MCUboot when enabling external flash over SPI. After configuring SPI memory in the .conf file and adding external flash support in the .dts file, the bootloader's memory usage increases. This leads to a compilation error, with the flash memory exceeding the allocated size by 7 kB. Below are the details of my setup.

Environment:

  • NCS Version: 2.7.0
  • Default MCUboot Size: 48 kB
  • Current MCUboot Memory Usage:
    • Without external flash (SPI/QSPI): ~43 kB
    • With external SPI flash defined (not used, only internal flash utilized in ): Overflow by 7 kB

Configurations and Files:

1. Device Tree (.dts)

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
chosen {
zephyr,sram = &sram0;
zephyr,flash = &flash0;
zephyr,code-partition = &slot0_partition;
nordic,pm-ext-flash = &mx25l12833f;
};
&spi1 {
compatible = "nordic,nrf-spim";
status = "okay";
pinctrl-0 = <&spi1_default>;
pinctrl-1 = <&spi1_sleep>;
pinctrl-names = "default", "sleep";
cs-gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
mx25l12833f: mx25l12833f@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <8000000>;
sfdp-bfp = [
e5 20 19 00 /* SFDP Header */
ff 00 ff 00 /* Erase Command, Write Granularity */
eb 44 55 ff /* 4KB Erase Command, Page Size */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

2. Partition Manager (pm_static.yml)

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
external_flash:
address: 0x0
size: 0x1000000 # 16 MB
device: DT_CHOSEN(nordic_pm_ext_flash)
region: external_flash
app:
address: 0xc200
region: flash_primary
size: 0xE0E00
mcuboot:
address: 0x0
region: flash_primary
size: 0xc000
mcuboot_pad:
address: 0xc000
region: flash_primary
size: 0x200 # 48 KB
mcuboot_primary:
address: 0xc000
orig_span: &id001
- mcuboot_pad
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

3. Application Configuration (prj.conf)

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# FLASH usage optimization
CONFIG_SIZE_OPTIMIZATIONS=y
CONFIG_COMPILER_OPT="-DNDEBUG"
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_REBOOT=y
CONFIG_THREAD_NAME=y
# FPU
CONFIG_FPU=y
CONFIG_FP_HARDABI=y
CONFIG_GPIO=y
CONFIG_SPI=y
CONFIG_SERIAL=y
CONFIG_WATCHDOG=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

4. MCUboot Configuration (mcuboot.conf)

Fullscreen
1
2
3
4
5
CONFIG_MULTITHREADING=y
CONFIG_CONSOLE=n
CONFIG_UART_CONSOLE=n
CONFIG_CONSOLE_HANDLER=n
CONFIG_FLASH=y
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


Problem: Defining external SPI flash in the configuration (even without actively using it for MCUboot) causes the bootloader size to increase by ~9 kB. This results in a compilation error due to flash memory overflow by ~7 kB. I suspect the issue lies in additional driver inclusion or configuration conflicts caused by enabling SPI flash.

Even with configuration of memory layout like below without using external memory for mcuboot, defining external memory over SPI in .dts causes flash overflow:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
&flash0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
boot_partition: partition@0 {
label = "mcuboot";
reg = <0x000000000 0xC000>;
};
slot0_partition: partition@C000 {
label = "image-0";
reg = <0x0000C000 0x77000>;
};
slot1_partition: partition@83000 {
label = "image-1";
reg = <0x00083000 0x77000>;
};
storage_partition: partition@FA000 {
label = "storage";
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
app:
address: 0xc200
region: flash_primary
size: 0x77E00
mcuboot:
address: 0x0
region: flash_primary
size: 0xc000
mcuboot_pad:
address: 0xc000
region: flash_primary
size: 0x200
mcuboot_primary:
address: 0xc000
orig_span: &id001
- mcuboot_pad
- app
region: flash_primary
size: 0x77000
span: *id001
mcuboot_primary_app:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Questions:

  1. What could be causing this significant increase in MCUboot memory usage?
  2. Are there optimization steps or alternative configurations to mitigate this flash memory usage?
Parents
  • The memory footprint of the bootloader increases significantly when having the secondary mcuboot slot placed in external flash as it requires the bootloader to include the SPI NOR driver and to be configured with multithreading. However, since the secondary slot is placed in internal flash in your case, this should not be needed. 

    Do you need CONFIG_MULTITHREADING to be enabled in your case?

  • In mcuboot I don't need CONFIG_MULTITHREADING but after disabling it I have compile errors: build/mcuboot/zephyr/include/generated/syscalls/kernel.h:1120: undefined reference to `z_impl_k_sem_give'

    So do I have to do something else ? In my main application I need CONFIG_MULTITHREADING cause I'm using mulitple threads.

  • Bartosz22 said:
    for now I can't change mcuboot size because I will have problems with updating old devices with 48kB bootloader.

    Sorry, I didn't realize you had two partition files. I was looking at the last one you posted. However, since the existing MCUboot bootloader is immutable and can't be upgraded, you won't be able to change the partition layout. The old bootloader will still look for the secondary slot in internal flash.

  • Sorry I wrote it wrong, I have few devices on NCS 1.8.0 with external flash and mcuboot 48kB because the same setup on NCS 1.8.0 fits into 48kB but on NCS 2.7.0 doesn't. So I have two questions:
    - what's the difference between NCS 1.8.0 and 2.7.0 that on older version mcuboot with external flash fits into 48kB ?
    - what do you suggest to do or are there any options to fit external memory to 48kB mcuboot ? 

  • Thanks for the clarification. I wrongfully assumed that the original bootloader did not use external flash. There have been a lot of changes since v1.8.0, both in Zephyr and MCuboot project, some of which may have increaed the memory footprint. Could you try running a diff on the generated .config file located in build/mcuboot/zephyr/ from the old and new projects to check if any additional features are enabled in the new version?

  • There are a lot differences here are the .config files:

    - NCS 1.8.0:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #
    # MCUboot-specific configuration options
    #
    # CONFIG_BOOT_USE_MIN_PARTITION_SIZE is not set
    CONFIG_PM_PARTITION_SIZE_MCUBOOT_SCRATCH=0x1e000
    CONFIG_PM_PARTITION_SIZE_MCUBOOT_PAD=0x200
    CONFIG_PM_PARTITION_SIZE_MCUBOOT=0xE0000
    CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL=y
    CONFIG_BOOT_ERASE_PROGRESSIVELY=y
    # CONFIG_BOOT_IMAGE_ACCESS_HOOKS is not set
    CONFIG_MCUBOOT=y
    CONFIG_BOOT_USE_MBEDTLS=y
    CONFIG_NRFXLIB_CRYPTO=y
    # CONFIG_NRF_CC310_BL is not set
    #
    # MCUBoot settings
    #
    # CONFIG_SINGLE_APPLICATION_SLOT is not set
    # CONFIG_BOOT_SIGNATURE_TYPE_NONE is not set
    CONFIG_BOOT_SIGNATURE_TYPE_RSA=y
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    -NCS 2.7.0:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #
    # MCUboot-specific configuration options
    #
    # CONFIG_BOOT_USE_MIN_PARTITION_SIZE is not set
    CONFIG_PM_PARTITION_SIZE_MCUBOOT_SCRATCH=0x1e000
    CONFIG_PM_PARTITION_SIZE_MCUBOOT_PAD=0x200
    CONFIG_PM_PARTITION_SIZE_MCUBOOT=0xE0000
    CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL=y
    CONFIG_BOOT_ERASE_PROGRESSIVELY=y
    # CONFIG_BOOT_IMAGE_ACCESS_HOOKS is not set
    # CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY is not set
    CONFIG_MCUBOOT=y
    CONFIG_BOOT_USE_MBEDTLS=y
    CONFIG_NRFXLIB_CRYPTO=y
    # CONFIG_NRF_CC310_BL is not set
    #
    # MCUBoot settings
    #
    # CONFIG_SINGLE_APPLICATION_SLOT is not set
    # CONFIG_BOOT_SIGNATURE_TYPE_NONE is not set
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Please give me some suggestions if you find something that I could change and will reduce memory size.

Reply Children
  • Also I have one more question cause when I add external flash in devicetree:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    &spi1 {
    compatible = "nordic,nrf-spim";
    status = "okay";
    pinctrl-0 = <&spi1_default>;
    pinctrl-1 = <&spi1_sleep>;
    pinctrl-names = "default", "sleep";
    cs-gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
    mx25l12833f: mx25l12833f@0 {
    compatible = "jedec,spi-nor";
    reg = <0>;
    spi-max-frequency = <8000000>;
    sfdp-bfp = [
    e5 20 19 00 /* 1st DWORD: SFDP Header */
    ff 00 ff 00 /* 2nd DWORD: Erase Command, Write Granularity */
    eb 44 55 ff /* 3rd DWORD: 4KB Erase Command, Page Size */
    ff ff ff ff /* 4th DWORD: Other Command Set */
    ff 00 00 00 /* 5th DWORD: Fast Read Commands */
    00 00 00 00 /* 6th DWORD: Extended Addressing */
    00 00 00 00 /* 7th DWORD: Other Settings */
    00 00 00 00 /* 8th DWORD: Reserved/Other */
    ];
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    and change memory layout to version without external flash:
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    app:
    address: 0xc200
    region: flash_primary
    size: 0x77E00
    mcuboot:
    address: 0x0
    region: flash_primary
    size: 0xc000
    mcuboot_pad:
    address: 0xc000
    region: flash_primary
    size: 0x200
    mcuboot_primary:
    address: 0xc000
    orig_span: &id001
    - mcuboot_pad
    - app
    region: flash_primary
    size: 0x77000
    span: *id001
    mcuboot_primary_app:
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    &flash0 {
    partitions {
    compatible = "fixed-partitions";
    #address-cells = <1>;
    #size-cells = <1>;
    boot_partition: partition@0 {
    label = "mcuboot";
    reg = <0x000000000 0xC000>;
    };
    slot0_partition: partition@C000 {
    label = "image-0";
    reg = <0x0000C000 0x77000>;
    };
    slot1_partition: partition@83000 {
    label = "image-1";
    reg = <0x00083000 0x77000>;
    };
    storage_partition: partition@FA000 {
    label = "storage";
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    I disable SPI and SPI_NOR in mcuboot.conf, everything compiles but it doesn't start on my board, if I remove external flash from .dts then the code runs ok. What could be the reason ? 

  • It seems like the main relevant difference is that the new version enables CONFIG_LOG. Disabling this should free up some space. 

    Diff:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    --- v1.8.0_config 2024-11-20 15:30:17.907344987 +0100
    +++ v2.7.0_config 2024-11-20 15:30:49.603068415 +0100
    @@ -8,6 +8,7 @@
    CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL=y
    CONFIG_BOOT_ERASE_PROGRESSIVELY=y
    # CONFIG_BOOT_IMAGE_ACCESS_HOOKS is not set
    +# CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY is not set
    CONFIG_MCUBOOT=y
    CONFIG_BOOT_USE_MBEDTLS=y
    CONFIG_NRFXLIB_CRYPTO=y
    @@ -22,22 +23,23 @@
    CONFIG_BOOT_SIGNATURE_TYPE_RSA_LEN=2048
    # CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 is not set
    # CONFIG_BOOT_SIGNATURE_TYPE_ED25519 is not set
    -# CONFIG_MCUBOOT_CLEANUP_ARM_CORE is not set
    +CONFIG_MCUBOOT_CLEANUP_ARM_CORE=y
    CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h"
    # CONFIG_BOOT_HW_KEY is not set
    CONFIG_BOOT_VALIDATE_SLOT0=y
    +CONFIG_BOOT_PREFER_SWAP_MOVE=y
    # CONFIG_BOOT_SWAP_USING_SCRATCH is not set
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    I also confirmed here that it is still possible to enable the SPI NOR driver in the bootloader and make it fit into the 48K region:

    peripheral_lbs_spi_dfu.zip

  • Thanks, I will take a look at this.