I can't use mcuboot to boot a firmware on my external flash

Hi,

I am trying to use mcuboot to load a version that is stored in my external flash, and I cannot get it to boot. My project is being built using sysbuild and my target is an nrf9161 with an external flash connected through SPI. Tests have been made where the flash could be read from the main application, so physical connections between the memory and the processor should not be an issue for this problem. The SDK version I am using is still the 2.9.1.

The process I am following is that I am building a version which I code using the VERSION file with a version higher than the program I plan to run on the processor. I generate the zephyr.signed.bin file like that and I write it on the flash.

Then, I build another version with a lower version number coded in the VERSION file, and I flash the merged.hex on the processor.

Each version has a print at the beginning where I check if the version that is running is the flashed one or the one that I wrote on the flash, and all the time I am seeing the one that I actively flash on the processor directly. The external flash does have the version because I could read the flash with my J-Link and I could confirm that the version was stored.

I have used the following configuration out of the devacademy examples.

sysbuild.conf:

# Activate the MCUBOOT bootloader for sysbuild
SB_CONFIG_BOOTLOADER_MCUBOOT=y

# STEP 3.1 - MCUboot should use external flash
SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y
# STEP 3.1 - For SPI, we need to set this
SB_CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y

SB_CONFIG_BOOT_SIGNATURE_TYPE_RSA=y
SB_CONFIG_MCUBOOT_MODE_OVERWRITE_ONLY=y

SB_CONFIG_PARTITION_MANAGER=y
SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y

sysbuild/mcuboot/prj.conf:

CONFIG_PM=n

CONFIG_MAIN_STACK_SIZE=10240
CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h"

CONFIG_BOOT_SWAP_SAVE_ENCTLV=n
CONFIG_BOOT_ENCRYPT_IMAGE=n

CONFIG_BOOT_UPGRADE_ONLY=n
CONFIG_BOOT_BOOTSTRAP=n

# Configurations added for mcuboot
CONFIG_BOOT_UPGRADE_ONLY=n
CONFIG_MCUBOOT_DOWNGRADE_PREVENTION=n
CONFIG_BOOT_BOOTSTRAP=n

CONFIG_PM_EXTERNAL_FLASH_BASE=0x0
CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y
CONFIG_GPIO=y
CONFIG_FLASH=y
CONFIG_SPI=y
CONFIG_SPI_NOR=y
CONFIG_SPI_NOR_SFDP_DEVICETREE=y
CONFIG_NORDIC_QSPI_NOR=n
# required by SPI driver
CONFIG_MULTITHREADING=y

CONFIG_FPROTECT=y
# This must be increased to accommodate the bigger images.
CONFIG_BOOT_MAX_IMG_SECTORS=256
CONFIG_LOG=y
CONFIG_MCUBOOT_UTIL_LOG_LEVEL_DBG=y
### Decrease footprint by ~4 KB in comparison to CBPRINTF_COMPLETE=y
CONFIG_CBPRINTF_NANO=y
CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=0
### Use the minimal C library to reduce flash usage
CONFIG_MINIMAL_LIBC=y

# Increase the monotonic firmware version before building a firmware update
CONFIG_FW_INFO=y
CONFIG_FW_INFO_FIRMWARE_VERSION=1

I also added to the sysbuild/mcuboot/app.overlay the external flash:

// The external flash must be added to the mcuboot overlay
&spi_main {
    ext_flash: w25q16@1 {
        compatible = "jedec,spi-nor";
        status = "okay";
        reg = <1>;
        spi-max-frequency = <800000>;
        size = <16777216>;
        has-dpd;
        t-enter-dpd = <10000>;
        t-exit-dpd = <35000>;
    };
};

/ {
    chosen {
        zephyr,code-partition = &boot_partition;
        nordic,pm-ext-flash = &ext_flash;
    };
};

I also tried to use it without the &spi_main definition here and just adding the flash to the chosen and the behavior was the same.

When I generate both the merged.hex as the zephyr.signed.bin I also use this config in the main application to sign the firmwares:

CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/root-rsa-2048.pem"

I am also trying to make debug prints on the mcuboot files to try to find out if there is any problem while trying to authenticate, but I have not been able to make any newer logging prints on my console.

There is probably something on the overall configuration that I am missing or any step that I unconsciously missed, so any advice can be useful.

Thank you very much,

Daniel

Parents
  • Hi Daniel,

    I don't see any issues with the configurations you've posted. Are you testing with a nRF9161 DK? In that case, you should have debug logging over UART enabled by default in mcuboot.

    If you are loading the firmware image (zephyr.signed.bin) directly to external flash via your debugger, you must also include the MCUboot image trailer to signal the bootloader that it should swap the image. (The trailer is usually created by the application after it has received the image). To make the zephyr.signed.bin file from the build output include the trailer, you can add either CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS="--pad" or CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS="--confirm" to your prj.conf file.

    Note: to check the content of your signed binary, you can run "imgtool  dumpinfo zephyr.signed.bin" from your terminal.

    Best regards,

    Vidar

  • Hi Vidar,

    Thank you for your quick response. I am testing with a custom board which has an NRF9161 connected through SPI to a flash memory.

    I just applied your suggestion with CONFIG_MCUBOOT_EXTRA_IMGTOOL_ARGS="--confirm" to the prj.conf file of my application (not to the mcuboot/prj.conf), but it still has not worked yet.

    The output I get when I program the nrf9161 is as follows:

    *** Booting nRF Connect SDK v2.9.1-60d0d6c8d42d ***
    *** Using Zephyr OS v3.7.99-ca954a6216c9 ***
    Attempting to boot slot 0.
    Attempting to boot from address 0x8200.
    I: Trying to get Firmware version
    I: Verifying signature against key 0.
    I: Hash: 0x7c...a0
    I: Firmware signature verified.
    Firmware version 1
    I: Setting monotonic counter (version: 1, slot: 0)
    I: w25q16@1: SFDP v 1.6 AP ff with 2 PH
    I: PH0: ff00 rev 1.6: 16 DW @ 80
    I: w25q16@1: 2 MiBy flash
    I: PH1: ff84 rev 1.0: 2 DW @ d0
    *** Booting My Application v2.1.0-dev-12e5ee106034 ***
    *** Using nRF Connect SDK v2.9.1-60d0d6c8d42d ***
    *** Using Zephyr OS v3.7.99-ca954a6216c9 ***
    I: Starting bootloader
    I: Image index: 0, Swap type: none
    I: Bootloader chainload address offset: 0x38000
    All pins have been configured as non-secure
    Booting TF-M v2.1.0
    [Sec Thread] Secure image initializing!
    TF-M Float ABI: Hard
    Lazy stacking enabled

    It looks like it knows that there is something to check on the external flash, since I get some messages from it, but it does not use it to boot.

    I get the following information when I apply the imgtool dumpinfo zephyr.signed.bin command:

    #### Image header (offset: 0x0) ############################
    magic:              0x96f3b83d
    load_addr:          0x0
    hdr_size:           0x200
    protected_tlv_size: 0x0
    img_size:           0x5cc64
    flags:              0x0
    version:            4.1.2+0

    .......

    #### Image trailer (offset: unknown) #######################
    (Note: some fields may not be used, depending on the update
    strategy)

    swap status: (len: unknown)
    enc. keys:   Image not encrypted
    swap size:   unknown
    swap_info:   INVALID (0xff)
    copy_done:   INVALID (0xff)
    image_ok:    SET (0x1)

    After this there was a boot magic field but I thought that it is not necessary to share in this message.

    Is there anything here that does not seem correct?

    Thank you very much,

    Daniel

    EDIT: I am also showing what I have set as a pm_static.yaml:

    mcuboot_secondary:
      region: external_flash
      address: 0x00000
      size: 0xe0000
  • Hi Daniel,

    Thanks for the additional info. It looks like the check here: https://github.com/nrfconnect/sdk-mcuboot/blob/9d9d524407df6da0815c79c5b9cf645f1ce25592/boot/bootutil/src/bootutil_public.c#L456  is failing in the bootloader, but it is not clear why from the configuration you posted. Can you please post the generated partitions.yml file from your build folder as well? 

    Best regards,

    Vidar

Reply Children
  • Hi Vidar,

    That could be an issue, I will debug that further.

    As for my generated partitions yml file, it is as follows:

    EMPTY_0:
      address: 0x1c000
      end_address: 0x20000
      placement:
        before:
        - s1_pad
      region: flash_primary
      size: 0x4000
    EMPTY_1:
      address: 0x34000
      end_address: 0x38000
      placement:
        before:
        - mcuboot_pad
      region: flash_primary
      size: 0x4000
    EMPTY_2:
      address: 0xfa000
      end_address: 0x100000
      placement:
        after:
        - settings_storage
      region: flash_primary
      size: 0x6000
    app:
      address: 0x40000
      end_address: 0xf8000
      region: flash_primary
      size: 0xb8000
    app_image:
      address: 0x38200
      end_address: 0xf8000
      orig_span: &id001
      - tfm
      - app
      region: flash_primary
      size: 0xbfe00
      span: *id001
    b0:
      address: 0x0
      end_address: 0x8000
      placement:
        after:
        - start
      region: flash_primary
      size: 0x8000
    b0_container:
      address: 0x0
      end_address: 0x8000
      orig_span: &id002
      - b0
      region: flash_primary
      size: 0x8000
      span: *id002
    external_flash:
      address: 0xe0000
      end_address: 0x200000
      region: external_flash
      size: 0x120000
    mcuboot:
      address: 0x8200
      end_address: 0x1c000
      placement:
        align:
          end: 0x1000
        before:
        - mcuboot_primary
      region: flash_primary
      sharers: 0x1
      size: 0x13e00
    mcuboot_pad:
      address: 0x38000
      end_address: 0x38200
      placement:
        align:
          start: 0x8000
        before:
        - mcuboot_primary_app
      region: flash_primary
      sharers: 0x2
      size: 0x200
    mcuboot_primary:
      address: 0x38000
      end_address: 0xf8000
      orig_span: &id003
      - app
      - mcuboot_pad
      - tfm
      region: flash_primary
      size: 0xc0000
      span: *id003
    mcuboot_primary_app:
      address: 0x38200
      end_address: 0xf8000
      orig_span: &id004
      - app
      - tfm
      region: flash_primary
      size: 0xbfe00
      span: *id004
    mcuboot_secondary:
      address: 0x0
      end_address: 0xe0000
      region: external_flash
      size: 0xe0000
    mcuboot_sram:
      address: 0x20000000
      end_address: 0x20008000
      orig_span: &id005
      - tfm_sram
      region: sram_primary
      size: 0x8000
      span: *id005
    nonsecure_storage:
      address: 0xf8000
      end_address: 0xfa000
      orig_span: &id006
      - settings_storage
      region: flash_primary
      size: 0x2000
      span: *id006
    nrf_modem_lib_ctrl:
      address: 0x20008000
      end_address: 0x200084e8
      inside:
      - sram_nonsecure
      placement:
        after:
        - tfm_sram
        - start
      region: sram_primary
      size: 0x4e8
    nrf_modem_lib_rx:
      address: 0x2000a568
      end_address: 0x2000c568
      inside:
      - sram_nonsecure
      placement:
        after:
        - nrf_modem_lib_tx
      region: sram_primary
      size: 0x2000
    nrf_modem_lib_sram:
      address: 0x20008000
      end_address: 0x2000c568
      orig_span: &id007
      - nrf_modem_lib_ctrl
      - nrf_modem_lib_tx
      - nrf_modem_lib_rx
      region: sram_primary
      size: 0x4568
      span: *id007
    nrf_modem_lib_tx:
      address: 0x200084e8
      end_address: 0x2000a568
      inside:
      - sram_nonsecure
      placement:
        after:
        - nrf_modem_lib_ctrl
      region: sram_primary
      size: 0x2080
    otp:
      address: 0xff8388
      end_address: 0xff83fc
      region: otp
      size: 0x74
    provision:
      address: 0xff8108
      end_address: 0xff8388
      region: otp
      size: 0x280
    s0:
      address: 0x8000
      end_address: 0x1c000
      orig_span: &id008
      - s0_pad
      - mcuboot
      region: flash_primary
      size: 0x14000
      span: *id008
    s0_image:
      address: 0x8200
      end_address: 0x1c000
      orig_span: &id009
      - mcuboot
      region: flash_primary
      size: 0x13e00
      span: *id009
    s0_pad:
      address: 0x8000
      end_address: 0x8200
      placement:
        after:
        - b0_container
        align:
          start: 0x8000
      region: flash_primary
      share_size:
      - mcuboot_pad
      size: 0x200
    s1:
      address: 0x20000
      end_address: 0x34000
      orig_span: &id010
      - s1_pad
      - s1_image
      region: flash_primary
      size: 0x14000
      span: *id010
    s1_image:
      address: 0x20200
      end_address: 0x34000
      placement:
        after:
        - s1_pad
        - s0
      region: flash_primary
      share_size:
      - mcuboot
      size: 0x13e00
    s1_pad:
      address: 0x20000
      end_address: 0x20200
      placement:
        after:
        - s0
        align:
          start: 0x8000
      region: flash_primary
      share_size:
      - mcuboot_pad
      size: 0x200
    settings_storage:
      address: 0xf8000
      end_address: 0xfa000
      inside:
      - nonsecure_storage
      placement:
        align:
          start: 0x8000
        before:
        - end
      region: flash_primary
      size: 0x2000
    sram_nonsecure:
      address: 0x20008000
      end_address: 0x20040000
      orig_span: &id011
      - sram_primary
      - nrf_modem_lib_ctrl
      - nrf_modem_lib_tx
      - nrf_modem_lib_rx
      region: sram_primary
      size: 0x38000
      span: *id011
    sram_primary:
      address: 0x2000c568
      end_address: 0x20040000
      region: sram_primary
      size: 0x33a98
    sram_secure:
      address: 0x20000000
      end_address: 0x20008000
      orig_span: &id012
      - tfm_sram
      region: sram_primary
      size: 0x8000
      span: *id012
    tfm:
      address: 0x38200
      end_address: 0x40000
      inside:
      - mcuboot_primary_app
      placement:
        before:
        - app
      region: flash_primary
      size: 0x7e00
    tfm_nonsecure:
      address: 0x40000
      end_address: 0xf8000
      orig_span: &id013
      - app
      region: flash_primary
      size: 0xb8000
      span: *id013
    tfm_secure:
      address: 0x38000
      end_address: 0x40000
      orig_span: &id014
      - mcuboot_pad
      - tfm
      region: flash_primary
      size: 0x8000
      span: *id014
    tfm_sram:
      address: 0x20000000
      end_address: 0x20008000
      inside:
      - sram_secure
      placement:
        after:
        - start
      region: sram_primary
      size: 0x8000
  • The Secondary slot is set larger than the primary slot, and they are meant to have the same size. This could explain why the slots are not read. Though I would have expected a warning about this in the debug log. Maybe you need to increase the log level.

    d.ovetrigo said:
    EDIT: I am also showing what I have set as a pm_static.yaml:

    If you remove this and do a pristine build to allow the partition manager to size the partition, then try again, does it work?

Related