MCUboot Direct-XIP, always boots the primary partition

Hi

I am trying to modify the MCUboot image to meet the requirements of the project one of the rquirements is to boot the application directly from the secondary partition, I found the Direct-XIP configuration that does that exactly so I enable it at first it worked, the MCUboot image's "prj.conf" looked like this:

CONFIG_MCUBOOT_LOG_LEVEL_DBG=y
CONFIG_BOOT_SWAP_USING_MOVE=n
CONFIG_BOOT_DIRECT_XIP=y

later I made some modifications directly to the SDK since I needed to update the secondary partition's image so that the DFU service of the Bluetooth connection could overwrite the image, because the service detected that the image was never swapped and it will just restart the device without upgrading the image. To solve this I erased the Trailer of the secondary partition's image.

At some point (not sure when) the MCUboot stopped booting the secondary's partition image (the devices doesn't get stuck, it just boots the primary partition's image) even when the Log says that the image in the secondary partition is newer and that it will be booting it (the address send to the function "do_boot" is the address of the secondary partition).

I tried going back in all my changes but the error is still present.

Right now I have been debugging the booting process after the partition has been selected and it seems that both partitions have the same MSP (Main Stack Pointer) so that might be why the primary partition is booted even when the secondary partition is selected.

I also found that I might need to use a file that has the word "secondary" in its name when writing an image in the secondary partition, I suppose that this one has the correct MSP to boot the image in the secondary partition, but I cannot see it in the "build" folder, while searching for this file found the configuration "CONFIG_BOOT_BUILD_DIRECT_XIP_VARIANT" on the application's "prj.conf" but this configuration is of the SDK version 2.0.X and I am using the SDK version 1.8.0.

What should I do so that I can get the correct image for the secondary partition (I would like to avoid the migration of the SDK if posible) or what should I configure in the MCUboot so that it can be booted?

Thanks,
Erasmo

  • Hi Erasmo,

    I have some questions for clarification:

    1. Have you run eraseall on your chip during your testing?
    2. Can you post the changes you made to the nRF Connect SDK? (For example paste the contents of "git diff" into a text document and insert it here)
    3. Can you elaborate a bit more on why you erased the trailer to fix the issue in the first place?

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd,

    Answering your questions in the same order:
    1. Yes, I have run the eraseall before and even during the flash command with the flag "--erase"

    2. I have actually undone all the changes I made to the nRF Connect SDK

    .../v1.8.0/bootloader/mcuboot ((v1.7.99-ncs4))
    $ git status
    HEAD detached at refs/heads/manifest-rev
    nothing to commit, working tree clean
    

    and the error is still present, in the application's project I configured the values:

    CONFIG_BOOTLOADER_MCUBOOT=y
    CONFIG_MCUBOOT_IMAGE_VERSION="0.1"

    and on the MCUboot image's configuration overlay file I set the values:

    CONFIG_MCUBOOT_LOG_LEVEL_DBG=y
    CONFIG_BOOT_SWAP_USING_MOVE=n
    CONFIG_BOOT_DIRECT_XIP=y

    Here the application's log that shows what the problem:

    // ========== Flashed the MCUboot and the application imagge with the --erase flag ========
    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    I: Starting Direct-XIP bootloader
    I: Primary   slot: version=0.1.0+0
    I: Image 0 Secondary slot: Image not found
    I: Image 0 loaded from the primary slot
    I: Bootloader chainload address offset: 0xc000
    *** Booting Zephyr OS build v2.7.0-ncs1  *** 
    [00:00:00.004,791] <inf> : Executing application version {0.1} 
    [00:00:00.039,550] <inf> : BLE library successfully initialized
    [00:00:00.044,311] <inf> : BLE MAC address loaded, addr=C54DC37971B4
    [00:00:00.050,476] <inf> : BLE Advertising process successfully started
    [00:00:05.519,927] <inf> : BLE device connected
    // Started sending the new image through the Bluetooth's DFU service
    [00:00:21.366,058] <inf> mcuboot_util: Swap type: none
    [00:00:21.637,207] <inf> mcuboot_util: Swap type: none
    [00:00:21.637,329] <inf> mcuboot_util: Swap type: none
    // finished the DFU process and the device restarted automatically
    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    I: Starting Direct-XIP bootloader
    I: Primary   slot: version=0.1.0+0
    I: Secondary slot: version=0.4.0+0
    I: Image 0 loaded from the secondary slot
    I: Bootloader chainload address offset: 0x74000 // This is the offset of the secondary partition
    *** Booting Zephyr OS build v2.7.0-ncs1  ***
    [00:00:00.004,821] <inf> : Executing application version {0.1} // As you can see the message is printing the version of theprimary partition's image
    [00:00:00.039,550] <inf> : BLE library successfully initialized
    [00:00:00.044,311] <inf> : BLE MAC address loaded, addr=C54DC37971B4
    [00:00:00.050,476] <inf> : BLE Advertising message successfully started

    This is how I print the application's first log message

    LOG_INF("Executing application version {%s}", CONFIG_MCUBOOT_IMAGE_VERSION);

    3. Just to be clear I didn't erase the trailer to fix the secondary partition's booting error. The thing is that I send the "app_update.bin" to my smartphone, then use the "nRF Connect" application to connect to the device through Bluetooth and do the DFU process. The problem here was that I couldn't overwrite the image in the secondary partition, for example:

    Lets say that in the primary partition I have the image version 2 and the secondary partition is empty, the primary partition is booted, then I do the DFU process and write the image version 1 in the secondary partition, the device restarts and since the secondary partition has a lower version than the primary partition the later is booted. After that I try to send the image version 3 through the DFU process so that it will overwrite the image version 1 that it's in the secondary partition but the during the process it reads that the image in the secondary partition is pending to be swapped, so it restarts the device so that the MCUboot do the swapping process but since I have enable the Direct-XIP configuration in the MCUboot image it will never swap the partitions' images and the swap state won't be updated so every time I try the DFU process it will read the same status and it will just restart the device, meaning I can only write an image in the secondary partition once and I cannot overwrite it.

    I debugged the MCUboot swapping process to see what values of the image's header and trailer modified during the process. On of them was the erasing the image's trailer. So what I did was to open the flash area of the secondary partition and then erase the trailer sector with the same function that the swap process used, this are the two functions I used to do this:

    struct boot_loader_state *state; // parameter of the function
    flash_area_open(FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state)), &fap);
    swap_erase_trailer_sectors(state, fap);

    this change did make it possible to overwrite the image in the secondary partition through the Bluetooth's DFU process.

    Regards

    Erasmo

  • You should be aware that the image you put in the secondary slot should be built for that exact address. For example an app_update.bin file might be built for addr. 0x1000 and have the reset addr 0x1100. If you then put this binary file in addr 0x2000 (and reset addr should be 0x2100), it will still see 0x1100 and try to jump there to start code execution.

    Does this make sense? Do you think this is the core of your issue?

    Best regards,

    Simon

  • Yes, that makes sense to me and I also though that might be the issue.

    Is there a configuration that I can use to change the reset address and set it to point at the secondary partition ? or how could I make it boot from the secondary partition directly?

    Regards,

    Erasmo

Related