This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Unable to find bootable image - MCUBoot

I try to integrate mcuboot and BT DFU into my application. I'm using SDK 1.8.0 and DK board nrf52832.

My problem is, that i got this message "Unable to find bootable image" by mcuboot (investigated via debugger, unfortunatelly  i'm not able to enable logs in that build).
So probably there is problem with partitions or maybe signature of the app.
This is my mcuboot.conf:

CONFIG_MULTITHREADING=y
CONFIG_CONSOLE=n
CONFIG_UART_CONSOLE=n
CONFIG_CONSOLE_HANDLER=n

CONFIG_BOOT_SIGNATURE_TYPE_RSA=y
CONFIG_BOOT_SIGNATURE_KEY_FILE="root-rsa-2048.pem"

And this is pm_static.yml:

app:
  address: 0xc200
  region: flash_primary
  size: 0x31E00
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: 0x32000
  span: *id001
mcuboot_primary_app:
  address: 0xc200
  orig_span: &id002
  - app
  region: flash_primary
  size: 0x3E000
  span: *id002
mcuboot_secondary:
  address: 0x3E000
  region: flash_primary
  size: 0x32000
scratch_storage:
  address: 0x70000
  region: flash_primary
  size: 0xa000
settings_storage:
  address: 0x7a000
  region: flash_primary
  size: 0x6000

And also flash configuration from my .dts:

&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>;
		};
		storage_partition: partition@7a000 {
			label = "storage";
			reg = <0x0007a000 0x00006000>;
		};
	};
};

I'm building and flashing using the simplest way:

west build -b <board_name>
west flash (merged.hex is being flashed)

Before some changes (not important here) everything was working fine, and i was even able to upload images through bluetooth with positive answer. But after few rebuilds it stopped working (probably it was pure luck - this is why i suspect that something may be wrong with partition table).

Parents
  • I added the exact same pm_static.yml file and the same prj.conf to the hello_world sample. In addition I enabled CONFIG_BOOTLOADER_MCUBOOT=y in hello_world/prj.conf. It ran without any errors.

    Test it yourself here. I used nrf52dk_nrf52832 and NCS v1.9.0-rc1:

    hello_world_with_mcuboot.zip

    Can you test it yourself and see if you get it to work?

    So based on the information/files you've given me, I'm not sure what may cause it to fail. Could you look at the sample hello_world_with_mcuboot I uploaded and see how that differs from your sample?

      i'm not able to enable logs in that build

    The reason you don't see any logs from mcuboot, is because you disable the (uart)console:

    CONFIG_CONSOLE=n
    CONFIG_UART_CONSOLE=n
    CONFIG_CONSOLE_HANDLER=n

    When I commented these out I was able to get mcuboot serial log to work.

    One question, do you get "Unable to find bootable image" after performing a DFU, or do you get it just when trying to boot the main application?

    Best regards,

    Simon

  • Thanks for quick answer :)

    Problem occurs after regular "west flash" (flashing merged.hex).
    I will now try the example you provided and compare it to my own. In this time, i also attach my zephyr app prj.conf.
    I did some optimization here to save space, maybe I cut too much, please take a look:
    (these setting are for BT DFU application)

    CONFIG_SIZE_OPTIMIZATIONS=y
    
    CONFIG_GPIO=y
    CONFIG_PWM=y
    CONFIG_ADC=y
    CONFIG_NRFX_TIMER0=y
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    
    CONFIG_BT=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_DEVICE_NAME="nordic"
    
    CONFIG_BT_SMP=y
    CONFIG_BT_LBS=y
    
    # Enable mcumgr.
    CONFIG_MCUMGR=y
    
    # Enable most core commands.
    CONFIG_MCUMGR_CMD_IMG_MGMT=y
    CONFIG_MCUMGR_CMD_OS_MGMT=y
    
    # Ensure an MCUboot-compatible binary is generated.
    CONFIG_BOOTLOADER_MCUBOOT=y
    
    # Allow for large Bluetooth data packets.
    CONFIG_BT_L2CAP_TX_MTU=252
    CONFIG_BT_BUF_ACL_RX_SIZE=256
    
    # Enable the Bluetooth (unauthenticated) and shell mcumgr transports.
    CONFIG_MCUMGR_SMP_BT=y
    CONFIG_MCUMGR_SMP_BT_AUTHEN=n
    
    # Some command handlers require a large stack.
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    
    CONFIG_SPI=n
    CONFIG_I2C=n
    CONFIG_BOOT_BANNER=n
    CONFIG_CONSOLE=n
    CONFIG_UART_CONSOLE=n
    CONFIG_STDOUT_CONSOLE=n
    CONFIG_PRINTK=n
    CONFIG_EARLY_CONSOLE=n
    CONFIG_TIMESLICING=n
    CONFIG_MINIMAL_LIBC_MALLOC=n
    CONFIG_LOG=n
    CONFIG_ASSERT=n
    
    # Disable Bluetooth features not needed
    CONFIG_BT_DEBUG_NONE=y
    CONFIG_BT_ASSERT=n
    CONFIG_BT_DATA_LEN_UPDATE=n
    CONFIG_BT_PHY_UPDATE=n
    CONFIG_BT_GATT_CACHING=n
    CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS=n
    CONFIG_BT_HCI_VS_EXT=n
    CONFIG_BT_CTLR_PRIVACY=n
    CONFIG_BT_CTLR_PHY_2M=n


  • Dymek117, I will try to reproduce using your steps

    I'm using hello_world_with_mcuboot.zip for all the steps below

    Dymek117 said:
    But if I do Pristine Build (without modifying bootloader .config) bootloader will no longer load application.

    Okay, let me test this. Let's do a pristine build and see if I can reproduce the issue.

    I'm starting now without any build folder. I'm using NCS v1.8.0. I placed the sample hello_world_with_mcuboot inside nrf/samples/

    These are the folders present in my sample

    CMakeLists.txt  README.rst  child_image  pm_static.yml  prj.conf  sample.yaml  src

    Then I do a pristine build, as you mentioned:

    west build -b nrf52dk_nrf52832 -d build -p

    I then flash it to the nRF52 DK using west flash (will automatically flash build folder with name 'build') and I get the following output:

    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Swap type: none
    I: Bootloader chainload address offset: 0xc000
    I: Jumping to the first image slot
    ÿ*** Booting Zephyr OS build v2.7.0-ncs1  ***
    Hello World! nrf52dk_nrf52832

    So it seems like doing a pristine build works fine here.

    However, maybe you already had a build folder present when you ran pristine build, I will test that as well

    I delete the build folder using rm -rf build, and this is the content of the sample to start with:

    CMakeLists.txt  README.rst  child_image  pm_static.yml  prj.conf  sample.yaml  src

    Let's run a normal build, to generate the build folder:

    west build -b nrf52dk_nrf52832 -d build

    I tried to flash it and everything worked fine, the sample booted.

    Then I tried to do a pristine build

    Dymek117 said:
    I do Pristine Build (without modifying bootloader .config)

    I followed the advice above, by not touching anything. This is the content inside nrf/samples/hello_world now:

    CMakeLists.txt  README.rst  build  child_image  pm_static.yml  prj.conf  sample.yaml  src

    Then I ran the pristine build:

    west build -b nrf52dk_nrf52832 -d build -p

    It worked fine, I got this output:

    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Swap type: none
    I: Bootloader chainload address offset: 0xc000
    I: Jumping to the first image slot
    ÿ*** Booting Zephyr OS build v2.7.0-ncs1  ***
    Hello World! nrf52dk_nrf52832
    

    I'm using west version 0.12.0, cmake version 3.20.5 and ninja version 1.9.0

    pip3 show -f west
    Name: west
    Version: 0.12.0
    .
    .
    .
    cmake --version
    cmake version 3.20.5
    .
    .
    ninja --version
    1.9.0

    The operating system is Windows 11

    Can you try to follow the exact same steps above with the same sample. If I have misunderstood your steps please tell me. If you run the same steps as me but with a different (failing) result, I would be interested to know more about your environment. What version of the different tools are you using and what OS are you using?

    I think the problem you see is that the hash value the bootloader expects is different from the hash value calculated from the application, this can happen if you modify the main application (which will cause the hash value to be different) and rebuild that, without rebuilding the mcuboot (so it won't get the new updated hash value). However, west build and west pristine build should rebuild both mcuboot as well as the main image when the main image changes (I just tested this).

    I was able to reproduce your behaviour however using these commands:

    • west build -b nrf52dk_nrf52832 -d build1
    • modify main.c
    • west build -b nrf52dk_nrf52832 -d build2
    • dir
      • CMakeLists.txt README.rst build build1 build2 child_image pm_static.yml prj.conf sample.yaml src
    • nrfjprog --eraseall
    • nrfjprog -f NRF52 --sectorerase --verify --program build1/mcuboot/zephyr/zephyr.hex
    • nrfjprog -f NRF52 --sectorerase --verify --program build2/ncs/zephyr/app_signed.hex
    • nrfjprog -f NRF52 --reset

    Got the following output:

    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    W: Failed reading image headers; Image=0
    E: Unable to find bootable image

    But this result is expected and not a bug, since I built mcuboot and the main image using from different build folders

    Thomas Fänge, I will look into your steps next week

    Best regards,

    Simon

  • Thanks for deep investigation Simon.

    First difference I see between our setups is that I dont have child_image directory. My mcuboot.conf is on the same level that prj.conf. But "mcuboot" directory is present in /build/ after successful build. Do you think it may cause any difference? (or maybe lack of child_image dir is symptom of some mistakes in configuration, where does this dir come from?)

    Also, small difference about mcuboot is in our cmake files, i set overlay config for mcuboot, like here:

    list(APPEND mcuboot_OVERLAY_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.conf")

    And I see that this is not present in your example, how does build system know to apply settings from child_image/mcuboot.conf? Is this some kind of default location?

    Looking on above differences and your investigation I suspect that my mcuboot is not always being re-generated and rebuilt. But I have no idea why :(

    Thanks.

  • Hi Simon,


    For your information, I'm building in a Ubuntu (18.04) environment and using West version 0.10.1:

        $ west --version
        West version: v0.10.1

    I can't really find something in the output when I build (prestine or not), but I saw that in the build/ncs/mcuboot/zephyr/.config it differs between the two builds (prestine build or not):

    (The 'build' directory contains a prestine build (i.e. after "rm -rf build"), and no_build is a renamed build-directory after a second build, i.e. after "touch" and build again)

        $ diff build/ncs/mcuboot/zephyr/.config no_build/ncs/mcuboot/zephyr/.config
        265,266c265,266
        < # CONFIG_PARTITION_MANAGER_ENABLED is not set
        < # CONFIG_FLASH_MAP_CUSTOM is not set
        ---
        > CONFIG_PARTITION_MANAGER_ENABLED=y
        > CONFIG_FLASH_MAP_CUSTOM=y

    Ie. these two configs are not set in the prestine build, but in the second build they are set - that is the only difference in the .config file between the two builds.

    Edit!
    I found another difference in the file build/ncs/mcuboot/zephyr/dev_handles.c.
    In the prestine build (after rm -rf) the last entry looks like this:

    /* 10 : /soc/spi@40023000/mx25u1633f@0:
    * - /soc/gpio@50000000
    * - /soc/gpio@50000300
    * - /soc/spi@40023000
    */
    const device_handle_t __aligned(2) __attribute__((__section__(".__device_handles_pass2")))
    __devicehdl_DT_N_S_soc_S_spi_40023000_S_mx25u1633f_0[] = { 5, 6, 9, DEVICE_HANDLE_ENDS, DEVICE_HANDLE_ENDS, DEVICE_HANDLE_ENDS };

    In the second build, it has changed to:

    /* 10 : /soc/spi@40023000/mx25u1633f@0:
    * - /soc/gpio@50000000
    * - /soc/gpio@50000300
    * - /soc/spi@40023000
    */
    const device_handle_t __aligned(2) __attribute__((__section__(".__device_handles_pass2")))
    __devicehdl_DT_N_S_soc_S_spi_40023000_S_mx25u1633f_0[] = { 6, 5, 9, DEVICE_HANDLE_ENDS, DEVICE_HANDLE_ENDS, DEVICE_HANDLE_ENDS };

    Again, no other difference in this file ...

    Cheers,
    Thomas

  • Dymek117

    Dymek117 said:
    My mcuboot.conf is on the same level that prj.conf.
    Dymek117 said:

    Also, small difference about mcuboot is in our cmake files, i set overlay config for mcuboot, like here:

    list(APPEND mcuboot_OVERLAY_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/mcuboot.conf")

    I tried to modify my sample according to the above, check it out here:

    hello_world_with_mcuboot_v2.zip

    Then did a pristine build using NCS v1.8.0:

    west build -b nrf52dk_nrf52832 -d build_v12_pristine -p

    and it worked fine:

    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Swap type: none
    I: Bootloader chainload address offset: 0xc000
    I: Jumping to the first image slot
    ÿ*** Booting Zephyr OS build v2.7.0-ncs1  ***
    Hello World! nrf52dk_nrf52832

    I tested this with both west v0.12.0 and v0.10.1

    Can you upload the project you're using as a zipped file and provide a detailed step-by-step guide on how to reproduce the issue. Could you let me know what west version you're using as well as the OS? You're using NCS v1.8.0, right?

  • Simon, basing on your post with step-by-step described build process I fixed this issue.

    Final solution was to create /child_image/ directory and place mcuboot.conf inside this dir.
    Then, no additional instructions for this file is needed in cmakelist, it is included by default.
    I have no idea why id does matter, but after this small change pristine build is booting fine.

    I'm using SDK 1.8.0 on Windows 10. My west version v0.12.0.

Reply
  • Simon, basing on your post with step-by-step described build process I fixed this issue.

    Final solution was to create /child_image/ directory and place mcuboot.conf inside this dir.
    Then, no additional instructions for this file is needed in cmakelist, it is included by default.
    I have no idea why id does matter, but after this small change pristine build is booting fine.

    I'm using SDK 1.8.0 on Windows 10. My west version v0.12.0.

Children
  • Okay, I'm happy it got resolved!

    Let me try to look into the issue you encounter Online Thomas Fänge

    ecsfang said:

    I can't really find something in the output when I build (prestine or not), but I saw that in the build/ncs/mcuboot/zephyr/.config it differs between the two builds (prestine build or not):

    (The 'build' directory contains a prestine build (i.e. after "rm -rf build"), and no_build is a renamed build-directory after a second build, i.e. after "touch" and build again)

        $ diff build/ncs/mcuboot/zephyr/.config no_build/ncs/mcuboot/zephyr/.config
        265,266c265,266
        < # CONFIG_PARTITION_MANAGER_ENABLED is not set
        < # CONFIG_FLASH_MAP_CUSTOM is not set

    I'm using this application hello_world_with_mcuboot_v2.zip

    I've installed west v0.10.1 to another location. and downgraded NCS to v1.7.0, as it seems that's what you're using.

    This is the content of the sample folder to start with:

    CMakeLists.txt  README.rst  mcuboot.conf  pm_static.yml  prj.conf  sample.yaml  src

    First I check the west version

    C:/msys64/mingw64/bin/west --version
    West version: v0.10.1

    Then I do a pristine build:

    C:/msys64/mingw64/bin/west build -b nrf52dk_nrf52832 -d build_v10_pristine -p

    Then I created the build folder you refer to as "no_build "

    C:/msys64/mingw64/bin/west build -b nrf52dk_nrf52832 -d build_v10_no_build

    touch CMakeLists.txt 

    C:/msys64/mingw64/bin/west build -b nrf52dk_nrf52832 -d build_v10_no_build

    Eventually I did a diff between the generated mcuboot folders

    diff build_v10_pristine/mcuboot/zephyr/.config build_v10_no_build/mcuboot/zephyr/.config

    But I got no result, which means they have the same content

    I have not yet installed Dual Boot Linux Ubuntu on my new computer, but I will do it soon and test this on Ubuntu as well.

    However, could you try the following:

    • Update to NCS v1.8.0 and the associated west v0.12.0?
      • If you install it through the Toolchain Manager, all the correct tools will be installed automatically
    • Check how you include the mcuboot config folder. Try to add it to child_image/mcuboot.conf

    Best regards,

    Simon

  • Hi Simon!

    Thanks for your response!

    Sorry - I had mixed up my files! It didn't help with creating a child_image etc, it still only works for me after the second build ... :(

    I can also confirm that if I create a "child_image/mcuboot.conf"-file:

      xxx/src/ncs/child_image$ ll
      -rw-r--r-- 1 sefangeth domain_users 1307 feb 14 14:40 mcuboot.conf

    then it works!

    The configuration for mcuboot we have is normally placed in an overlay file, pointed to from the CMakeFile.txt:

      list(APPEND mcuboot_OVERLAY_CONFIG "$ENV{VSLN_NCS_ROOT}/vt2-overlays/vt2-mcuboot-overlay.conf")

    So, it seems as if the overlay-file is not used when compiling for the first time (i.e. after deleting the build directory). In the example above - the mcuboot.conf is identical to the vt2-mcuboot-overlay.conf.

    Can that be explained - or is the child_image approach to be preferred?

    Best regards,
    Thomas

  • Hi again,

    First sorry for the confusion ...

    I'm trying to see what differs between the two builds, and one thing I noticed is in the build/ncs/CMakeCache.txt file.

    When it fails, it more or less only differs in the following line:

    mcuboot_OVERLAY_CONFIG:INTERNAL=
      /xx/vsln-ncs/vt2-overlays/vt2-mcuboot-overlay.conf
      /xx/ncs/nrf/subsys/partition_manager/partition_manager_enabled.conf


    When it works it looks like this:

    mcuboot_OVERLAY_CONFIG:INTERNAL=
      /xx/vsln-ncs/vt2-overlays/vt2-mcuboot-overlay.conf
      /xx/ncs/nrf/subsys/partition_manager/partition_manager_enabled.conf
      ; /xx/vsln-ncs/vt2-overlays/vt2-mcuboot-overlay.conf
      /xx/ncs/nrf/subsys/partition_manager/ext_flash_mcuboot_secondary.conf

    And the .config only differs for mcuboot as I showed in a previous entry:

    $ diff build/ncs/mcuboot/zephyr/.config fail_build/ncs/mcuboot/zephyr/.config
      265,266c265,266
      < CONFIG_PARTITION_MANAGER_ENABLED=y
      < CONFIG_FLASH_MAP_CUSTOM=y
      ---
      > # CONFIG_PARTITION_MANAGER_ENABLED is not set
      > # CONFIG_FLASH_MAP_CUSTOM is not set

    So, it seems as if the config somehow is not correctly setup during a prestine build. The vt2-mcuboot-overlay.conf is included twice, and the ext_flash_mcuboot_secondary is only included in the working build.

    The ext_flash_mcuboot_secondary.conf is included in the CMakeFile.txt for the mcuboot, in the file ncs/nrf/modules/mcuboot/CMakeLists.txt:

      if (CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY)
        # By passing this value we don't require the user to pass any overlay files
        # to the MCUboot child image for storing the secondary partition in
        # external flash.
        add_overlay_config(
          mcuboot
          ${ZEPHYR_NRF_MODULE_DIR}/subsys/partition_manager/ext_flash_mcuboot_secondary.conf
    )
      endif()

    And CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY seems to be configured in the subsys/partition_manager/ext_flash_mcuboot_secondary.conf file, which seems odd since then we have a circular reference ... (the config is set in the file included if the config is set ...) ?

    And that is the only content of the file ncs/nrf/subsys/partition_manager/ext_flash_mcuboot_secondary.conf:

      CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY
    =y

    I can't see that this config is set anywhere else ...

    Could that be that the MCUBOOT_SECONDARY somehow is not included in the first build, but in the second build the buildsystem gets that the MCUBOOT_SECONDARY should be included ... at least that how I interpret the CMakeCache.txt contents ... that could explain why the bootloader doesn't find the image in the first build.

    Best regards,
    Thomas

    ---

Related