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

How do I change the application/bootloader start address?

My ultimate issue is trying to get a bootloader working on custom hardware with an nRF52832. The bootloader is mostly the base UART DFU bootloader from the Nordic SDK, with a few customizations to work with our hardware. I've been able to get the bootloader up and running by using the following flash set up that I have for the application: FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x5a000. However, when I try to change the start address (e.g. to FLASH (rx) : ORIGIN = 0x25000, LENGTH = 0x5b000), the bootloader no longer appears to run. Similarly, I can use Eclipse to step into the debug code of the bootloader when it starts at 0x26000, but not at 0x25000.

To try to eliminate as many variables as possible, I also tried changing the start address of one of the SDK examples and running it on an nRF52 dev kit. In the same way as the bootloader on custom hardware, building the ble_central/ble_app_blinky_c produces an hex file that will run successfully on the dev kit, while building it with the start address changed to 0x25000 produces a hex file that will not run successfully. Below is a diff of my complete changes to the blinky example.

diff --git a/examples/ble_central/ble_app_blinky_c/pca10040/s132/armgcc/ble_app_blinky_c_gcc_nrf52.ld b/examples/ble_central/ble_app_blinky_c/pca10040/s132/armgcc/ble_app_blinky_c_gcc_nrf52.ld
index 1cdf99f61..f4c14ecb0 100644
--- a/examples/ble_central/ble_app_blinky_c/pca10040/s132/armgcc/ble_app_blinky_c_gcc_nrf52.ld
+++ b/examples/ble_central/ble_app_blinky_c/pca10040/s132/armgcc/ble_app_blinky_c_gcc_nrf52.ld
@@ -5,7 +5,7 @@ GROUP(-lgcc -lc -lnosys)

 MEMORY
 {
-  FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x5a000
+  FLASH (rx) : ORIGIN = 0x25000, LENGTH = 0x5b000
   RAM (rwx) :  ORIGIN = 0x20001d70, LENGTH = 0xe290
 }

In both the custom code/hardware and stock SDK/dev kit situations I'm using GCC as my compiler and SDK 15.2.0, with softdevice s132_nrf52_6.1.0_softdevice.hex. My programming procedure in each case is:

nrfjprog -f nrf52 --eraseall
nrfjprog -f nrf52 --chiperase --program <path_to_softdevice>
nrfjprog -f nrf52 --sectorerase --program <application or bootloader>.hex
nrfjprog -f nrf52 --reset

What am I missing about changing the starting address of either the application or the bootloader? What configuration needs to be done to get an application and bootloader running together?

Thanks.

Parents
  • Hi Kathleen,

     the S132 v6.1.0 SoftDevice requires 152 kB (0x26000 bytes) of program memory, starting from 0x0000 ( This is included the MBR, see Memory resource map and usage for the memory layout). So when you are setting the application or bootloader start address to 0x25000, you are effectively overwritting the SoftDevice. Hence setting any start address higher than 0x26000 should work fine for both the bootloader and the application. 

    Best regards
    Bjørn 

  • So that explains why 0x25000 won't work as a start address, but I also can't run the blinky example with the following configuration: FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0x59000. Any idea what might be going on here?

  • No, I am not able to debug with that configuration. I have been able to debug the bootloader with the FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x5a000 configuration.

  • I think the issue is that the length value is to large as ORIGIN+LENGTH is 0x81000. The bootloader should stop at the start of the MBR Params page at 0x7E000, i.e. LENGTH = 0x78000 - ORIGIN = 0x57000.

    I tested the following setting with the bootlaoder in SDK v15.2.0 and I had no issues. 

     FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0x57000

  • I've noticed that my custom bootloader isn't setting the bootloader start address in the UICR registers. Is there anything specific in the project setup that signals nrfjprog that a given application is a bootloader and thus that the UICR registers should be set? I'm using the same ld file for my bootloader as for the example in the SDK, so maybe I'm missing something in the makefile?

  • Hi Kathleen,
    as long as you have the following memory regions and sections set in your linker script

    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0x57000
      RAM (rwx) :  ORIGIN = 0x200057b8, LENGTH = 0xa848
      mbr_params_page (r) : ORIGIN = 0x0007E000, LENGTH = 0x1000
      bootloader_settings_page (r) : ORIGIN = 0x0007F000, LENGTH = 0x1000
      uicr_mbr_params_page (r) : ORIGIN = 0x10001018, LENGTH = 0x4
      uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4
    }
    
    SECTIONS
    {
      .mbr_params_page(NOLOAD) :
      {
        PROVIDE(__start_mbr_params_page = .);
        KEEP(*(SORT(.mbr_params_page*)))
        PROVIDE(__stop_mbr_params_page = .);
      } > mbr_params_page
      .bootloader_settings_page(NOLOAD) :
      {
        PROVIDE(__start_bootloader_settings_page = .);
        KEEP(*(SORT(.bootloader_settings_page*)))
        PROVIDE(__stop_bootloader_settings_page = .);
      } > bootloader_settings_page
      .uicr_mbr_params_page :
      {
        PROVIDE(__start_uicr_mbr_params_page = .);
        KEEP(*(SORT(.uicr_mbr_params_page*)))
        PROVIDE(__stop_uicr_mbr_params_page = .);
      } > uicr_mbr_params_page
      .uicr_bootloader_start_address :
      {
        PROVIDE(__start_uicr_bootloader_start_address = .);
        KEEP(*(SORT(.uicr_bootloader_start_address*)))
        PROVIDE(__stop_uicr_bootloader_start_address = .);
      } > uicr_bootloader_start_address
    }

    specifically the uicr_bootloader_start_address section, then you should be fine. Could you search through your .map file and see if uicr_bootloader_start_address section is included in the generated binary?

  • I've got this line  under Memory Configuration:

    uicr_bootloader_start_address 0x10001014         0x00000004         r

    And this later on in the map file:

    .uicr_bootloader_start_address
                    0x10001014        0x0
                    [!provide]                PROVIDE (__start_uicr_bootloader_start_address = .)
     *(SORT_BY_NAME(.uicr_bootloader_start_address*))
                    [!provide]                PROVIDE (__stop_uicr_bootloader_start_address = .)

Reply Children
  • After looking into the allocation in the map file, it became apparent that the issue I was seeing was due to the bootloader sections not being allocated properly. While the sections in the linker script do need to be added, this is only part of what's needed.

    As opposed to the examples given in the SDK, my build configuration file (CMakeLists.txt using cmake and ninja to build) was designed in a minimalistic way, including only bootloader_main.c and one support file, with the Nordic files available as a separate library. The bootloader sections are utilized in components/libraries/bootloader/dfu/nrf_dfu_settings.c and components/libraries/bootloader/nrf_bootloader_info.c. As bootloader_main.c was not referencing these files explicitly, they were not being included in the build and were not being given space in the bootloader map. Adding these files to the bootloader target explictly caused them to be allocated and enabled the bootloader to boot.

    So the change I needed to make to the project was to go from this executable setup:

    set (EXE_NAME "bootloader")
    add_executable(bootloader
        $<TARGET_OBJECTS:nrf5_sdk_retarget> # This allows linking in the "retargetted versions of _read and _write
                                            # for printf/scanf instead of linking the libnosys implementation.
        ${APP_ROOT}/bootloader_main.c
        ${APP_ROOT}/shipBoot.c
    )

    To this one:

    set (EXE_NAME "bootloader")
    add_executable(bootloader
        $<TARGET_OBJECTS:nrf5_sdk_retarget> # This allows linking in the "retargetted versions of _read and _write
                                            # for printf/scanf instead of linking the libnosys implementation.
        ${APP_ROOT}/bootloader_main.c
        ${APP_ROOT}/shipBoot.c
    	# There are a few bootloader sections which need to be allocated in the
    	# final build. The following files add variables in the given sections,
    	# resulting in their allocation in the map file.
    	${NRF5_SDK_ROOT}/components/libraries/bootloader/dfu/nrf_dfu_settings.c
    	${NRF5_SDK_ROOT}/components/libraries/bootloader/nrf_bootloader_info.c
    )

Related