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

Bootloader settings backup in SDK 15.1.0

Hi

I've migrated some of our code to the SDK 15.1.0. One of the new features in the bootloader seems to cause some problems right now.

I was able t build a project and a new bootloader based on the SDK 15.1.0, but now after a few updates it seems that there is a vaild bootloader settings backup in the flash that always overwrites may new written bootloader settings for a new application. 

Steps to reproduce:

- build secure bootloader and application based on SDK 15.1
- do some updates over DFU
- program a new application by uVision and  write the new build bootloader settings built by the nrfutil.

Now on startup the comment in the log of the bootloader implies that the bootloader settings are considered as invalid and are overwritten by the backup. Is this a common issue? How can it be resolved?

Regards Adrian

Parents
  • Can you cut and paste what you are seeing in the log output to this thread and highlight the area of concern?

  • Hi

    I've prepared a little test that can reproduce the issue. You can find the required test files an the attached test.zip file. The difference between this reproduced case and my problem case is the NRF_DFU_DEBUG setting. Here in this example it is activated and in my case it's not as I'm not a fan of developing with different settings than the end user will have. Setting NRF_DFU_DEBUG would fix my problem, but if possible I'm looking for a good way to solve it without that.

    The test executes the following sequence:
    1) Program a bootloader, softdevice and application to a recovered nRF52 DK that has to be connected to the PC
    2) At this point a RTT viewer is attached. The attached log_1.txt file shows the output of the RTT viewer. In the log we can see that the bootloader settings are backed up to 0x7E000.
    3) Afterwards the nRF52 DK is halted and a new application with the generated correct bootloader settings is programmed.
    4) The next restart of the device shows in the log the output of the file log_2.txt. We can see that at the beginning the written new bootloader settings are overwritten by the restore of the backup. A few lines later we come to the place where the application is checked for validity. The output "CRC check of app failed. Return 1" shows that the restored bootloader settings are now surely not matching the written application. The "Return 1" is a result of the activated NRF_DFU_DEBUG that cases in this case that the application is started even if it is invalid. If NRF_DFU_DEBUG is not set it will return 0 and the application is not started (as it is in my case).

    I see different options to solve this, but which one is the best. As others may struggle over the same behavior I think the problem should be fixed somehow as it is a new unwanted behavior that may confuse a lot of users.

    Regards Adrian

     0> <info> app: Inside main
     0> <debug> app: In nrf_bootloader_init
     0> <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
     0> <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
     0> <warning> nrf_dfu_settings: Restoring settings from backup since the app has tampered with the off-limit parts of the settings page.
     0> <debug> nrf_dfu_settings: Writing settings...
     0> <debug> nrf_dfu_settings: Erasing old settings at: 0x0007F000
     0> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007F000, len=1 pages), queue usage: 0
     0> <debug> nrf_dfu_flash: Flash erase success: addr=0x0007F000, pending 0
     0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007F000, src=0x20006D88, len=440 bytes), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash write success: addr=0x0007F000, pending 0
     0> <debug> app: Enter nrf_bootloader_fw_activate
     0> <info> app: No firmware to activate.
     0> <debug> app: Enter nrf_dfu_app_is_valid
     0> <debug> app: CRC check of app failed. Return 1
     0> <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
     0> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
     0> <debug> app: Running nrf_bootloader_app_start with address: 0x00001000
     0> <debug> app: Disabling interrupts. NVIC->ICER[0]: 0x0
     0> <debug> app: running irq table set
     0> <debug> app: After running irq table set
    

    2604.test.zip

     0> <info> app: Inside main
     0> <debug> app: In nrf_bootloader_init
     0> <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
     0> <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
     0> <debug> nrf_dfu_settings: Settings OK
     0> <debug> app: Enter nrf_bootloader_fw_activate
     0> <info> app: No firmware to activate.
     0> <debug> app: Enter nrf_dfu_app_is_valid
     0> <debug> app: Return true. App was valid
     0> <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
     0> <debug> nrf_dfu_settings: Writing settings...
     0> <debug> nrf_dfu_settings: Erasing old settings at: 0x0007E000
     0> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007E000, len=1 pages), queue usage: 0
     0> <debug> nrf_dfu_flash: Flash erase success: addr=0x0007E000, pending 0
     0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007E000, src=0x20006F40, len=440 bytes), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash write success: addr=0x0007E000, pending 0
     0> <debug> app: Running nrf_bootloader_app_start with address: 0x00001000
     0> <debug> app: Disabling interrupts. NVIC->ICER[0]: 0x0
     0> <debug> app: running irq table set
     0> <debug> app: After running irq table set

  • Hi Adrian,

    I've just started looking at this, but my first question would be to wonder if it is valid to halt the cpu, reflash the application and then simply resume it again as you do at the end of your batch file.  At this point in my flashing routine I restart, not run, the device.

    Note that you can avoid the initial backup by flashing a copy of the bootloader settings into the MBR parameter storage area (which is the bootloader settings backup area) at the same time you load the initial image.  Apparently the MBR has some kind of magic that distinguishes between bootloader settings backups and MBR commands.

  • Note the undocumented change in NRF_DFU_DEBUG in 15.1, it used to just mean "honor debug flag in init packet", now it also means ignore CRC.  I reverted it back to the original behavior in my code base.

  • The problem seems to be here:

        
        
        bool settings_valid        = settings_crc_ok();
        bool settings_backup_valid = settings_backup_crc_ok();
    
        if (settings_valid &&
            settings_backup_valid &&
            !settings_forbidden_parts_equal_to_backup(m_dfu_settings_buffer))
        {
            NRF_LOG_WARNING("Restoring settings from backup since the app has tampered with the "
                            "off-limit parts of the settings page.");
            memcpy(&s_dfu_settings,
                   mp_dfu_settings_backup_buffer,
                   sizeof(nrf_dfu_settings_t));
        }
    

    IE, you have a valid backup that doesn't match the current settings file. You either need to invalidate it by erasing it or program it at the same time. This seems to work for me, please try it:

        REM program new application and the coresponsing bootloader settings
        .\nrfutil settings generate --application nrf52832_xxaa.hex --family NRF52 --application-version 0 --bootloader-version 0 --bl-settings-version 1 "settings.hex"
        .\nrfutil settings generate  --start-address 0x7E000 --application nrf52832_xxaa.hex --family NRF52 --application-version 0 --bootloader-version 0 --bl-settings-version 1 "settings_backup.hex"
        nrfjprog --sectorerase --program nrf52832_xxaa.hex
        nrfjprog --sectorerase --program settings.hex
        nrfjprog --sectorerase --program settings_backup.hex
    
    
    
  • Hi Aaron

    Thanks for the detailed analyzation. I totally agree with your findings and your conclution that the backup needs to be invalidated or written with the download. I adapted your recommendation in my solution and it works perfectly.

    Maybe a short addition concerning the halt of the CPU. I don't use this normally, but in this test i used it to stop the cpu to prevent that it starts after programming before i could setup the RTT viewer. It seems to work, but wouldn't use it normally.

    Regards Adrian

Reply
  • Hi Aaron

    Thanks for the detailed analyzation. I totally agree with your findings and your conclution that the backup needs to be invalidated or written with the download. I adapted your recommendation in my solution and it works perfectly.

    Maybe a short addition concerning the halt of the CPU. I don't use this normally, but in this test i used it to stop the cpu to prevent that it starts after programming before i could setup the RTT viewer. It seems to work, but wouldn't use it normally.

    Regards Adrian

Children
No Data
Related