This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Endless loop in MBR after bootloader update from SDK14.1 to SDK 15.0

We have a project running based on the SDK 14.1 on a nRF52DK with S132 5.0. The used bootloader works as expected and also an update of the bootloader works properly. 

After the release of SDK 15 we tried to implement the update the current bootloader based on SDK 14.1 to a bootloader based on SDK 15.0. We adapted our project to use the SDK 15 bootloader. The bootloader itself is working fine if programmed with j-link, but we are not able to update the existing 14.1 based bootloader with the new built SDK 15.0 bootloader. The update looks normal untill the data has been transfered to the device. But after the reset the device never gets into the bootloader code and is bricked.

By looking deeper into the behavior i found out that the firmware continuously executes code in the range of the MBR (< 0x1000). A dump of the flash also showed some data in the MBR params page.

As far as I know the MBR params page should be cleared after a command ahs completed completely. This also matches the theory that something in the MBR doesn't work.

Here is the start of the MBR Params page (Intel HEX Format):
:10E00000DC17511EAAFFFFFF086A00208C43002086
:10E0100000E007001B03000000000000F9FFFFFF05
:10E02000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00

Questions:

- What can cause the MBR to end in a endless loop?
- Where is the difference between the SDK14.1 bootloader and the SDK15.0 based bootloader that can cause this different behavior?

Regards Adrian

  • Hi,

    Are you doing an upgrade from the unmodified 14.1 bootloader to the unmodified 15.0 bootloader (with exception of key pair used for signing)?

    If not, if for instance the bootloader size has changed then a likely scenario may be that the bootloader starts briefly, thinks that a time costly MBR operation is required, and then reboots into the MBR (so that it looks like MBR is running all of the time, but in reality it is 99 % of the time.)

    Not qute able to parse the MBR Params page, but it looks like a copy or compare operation involving the bootloader.

    I may need hex files and DFU zip file for reproducing, and/or flash hex dumps before and after DFU in order to investigate further. You can create a private ticket and post those there if confidential. (Or we can go private with this thread, if needed. Let me know.)

    Regards,
    Terje

  • Hi Terje

    I've created a private ticket with a reference to this one. The files provided there are not for the public, but I guess the results from the issue will be interesting for other Nordic uses as well.

    Regards Adrian

  • HI,

    Thank you. I suggest that we continue the discussion in the private thread, and when we find a solution you may choose to post it here.

    Regards,
    Terje

  • Hi,

    Performing a bootloader only update from SDK 14.x to SDK 15.0 does not work. This is a rare corner case, as normally one is required to update the SoftDevice along with the bootloader in order to get from SDK 14 to SDK 15.

    There are two cases where you can start a BL only update from SDK 14 to SDK 15:

    1. When one of the bootloaders are ported to use a different SoftDevice, so that both bootloaders requires the same SoftDevice. In that case BL only update becomes a valid option.
    2. If updating to a bootloader where the SoftDevice requirement has been removed, which means BL only update is a valid option.

    In both situations, if you attempt a BL only update it will fail when entering the SDK 15 bootloader for the first time, with symptoms equal or similar to those described in the opening question post.

    We are aware of the issue, and are planning to fix it for next SDK release.

    The initially proposed (not production tested, use at own risk) fix is adding four lines (an "else if" statement) in nrf_bootloader_fw_activation.c of SDK 15.0, so that the beginning of the function bl_activate() reads:

    static uint32_t bl_activate(void)
    {
        uint32_t         ret_val  = NRF_ERROR_INVALID_DATA;
        nrf_dfu_bank_t * p_bank   = &s_dfu_settings.bank_1;
        uint32_t         len      = p_bank->image_size;
        uint32_t         src_addr = s_dfu_settings.progress.update_start_address;
    
        if (p_bank->bank_code == NRF_DFU_BANK_VALID_SD_BL)
        {
            src_addr += s_dfu_settings.sd_size;
            len      -= s_dfu_settings.sd_size;
        }
        else if (src_addr == 0)
        {
            src_addr = nrf_dfu_bank1_start_addr();
        }

    Regards,
    Terje

Related