52840 SDK v17.1 Linker Errors Building DFU Bootloader

I am working on a 52840 platform DFU bootloader.

I get linker errors I cant seem to fix:

undefined reference to `crc32_compute', 

Bootloader/nrf_bootloader_info.o:C:\dev\\sdk\components\libraries\bootloader/nrf_bootloader_info.c:57: undefined reference to `_vectors'

in function `Reset_Handler': undefined reference to `nRFInitialize'

undefined reference to `nrfx_spi_init'

Lots of other errors not shown.

I attached flash placement file.

I'm using SEGGER IDE v5.42a

<!DOCTYPE Linker_Placement_File>
<Root name="Flash Section Placement">
  <MemorySegment name="FLASH" start="$(FLASH_PH_START)" size="$(FLASH_PH_SIZE)">
    <ProgramSection load="no" name=".reserved_flash" start="$(FLASH_PH_START)" size="$(FLASH_START)-$(FLASH_PH_START)" />
    <ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START)" />
    <ProgramSection alignment="4" load="Yes" name=".init" />
    <ProgramSection alignment="4" load="Yes" name=".init_rodata" />
    <ProgramSection alignment="4" load="Yes" name=".text" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_const_data" inputsections="*(SORT(.log_const_data*))" address_symbol="__start_log_const_data" end_symbol="__stop_log_const_data" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".dfu_trans" inputsections="*(SORT(.dfu_trans*))" address_symbol="__start_dfu_trans" end_symbol="__stop_dfu_trans" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".svc_data" inputsections="*(.svc_data*)" address_symbol="__start_svc_data" end_symbol="__stop_svc_data" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_ble_observers" inputsections="*(SORT(.sdh_ble_observers*))" address_symbol="__start_sdh_ble_observers" end_symbol="__stop_sdh_ble_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_req_observers" inputsections="*(SORT(.sdh_req_observers*))" address_symbol="__start_sdh_req_observers" end_symbol="__stop_sdh_req_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_state_observers" inputsections="*(SORT(.sdh_state_observers*))" address_symbol="__start_sdh_state_observers" end_symbol="__stop_sdh_state_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_stack_observers" inputsections="*(SORT(.sdh_stack_observers*))" address_symbol="__start_sdh_stack_observers" end_symbol="__stop_sdh_stack_observers" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".sdh_soc_observers" inputsections="*(SORT(.sdh_soc_observers*))" address_symbol="__start_sdh_soc_observers" end_symbol="__stop_sdh_soc_observers" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections" address_symbol="__start_nrf_sections" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_dynamic_data"  inputsections="*(SORT(.log_dynamic_data*))" runin=".log_dynamic_data_run"/>
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".fs_data"  inputsections="*(.fs_data*)" runin=".fs_data_run"/>
    <ProgramSection alignment="4" load="Yes" name=".dtors" />
    <ProgramSection alignment="4" load="Yes" name=".ctors" />
    <ProgramSection alignment="4" load="Yes" name=".rodata" />
    <ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
    <ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
    <ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
    <ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".nrf_balloc" inputsections="*(.nrf_balloc*)" address_symbol="__start_nrf_balloc" end_symbol="__stop_nrf_balloc" />
  </MemorySegment>
  <MemorySegment name="RAM1" start="$(RAM_PH_START)" size="$(RAM_PH_SIZE)">
    <ProgramSection load="no" name=".reserved_ram" start="$(RAM_PH_START)" size="$(RAM_START)-$(RAM_PH_START)" />
    <ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START)" address_symbol="__app_ram_start__"/>
    <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run" address_symbol="__start_nrf_sections_run" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".log_dynamic_data_run" address_symbol="__start_log_dynamic_data" end_symbol="__stop_log_dynamic_data" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".fs_data_run" address_symbol="__start_fs_data" end_symbol="__stop_fs_data" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run_end" address_symbol="__end_nrf_sections_run" />
    <ProgramSection alignment="4" load="No" name=".fast_run" />
    <ProgramSection alignment="4" load="No" name=".data_run" />
    <ProgramSection alignment="4" load="No" name=".tdata_run" />
    <ProgramSection alignment="4" load="No" name=".bss" />
    <ProgramSection alignment="4" load="No" name=".tbss" />
    <ProgramSection alignment="4" load="No" name=".non_init" />
    <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
    <ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack"  address_symbol="__StackLimit" end_symbol="__StackTop"/>
    <ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
  </MemorySegment>
  <MemorySegment name="bootloader_settings_page" start="0x0007F000" size="0x1000">
    <ProgramSection alignment="4" keep="Yes" load="No" name=".bootloader_settings_page" address_symbol="__start_bootloader_settings_page" end_symbol="__stop_bootloader_settings_page" start = "0x0007F000" size="0x1000" />
  </MemorySegment>
  <MemorySegment name="mbr_params_page" start="0x0007E000" size="0x1000">
    <ProgramSection alignment="4" keep="Yes" load="No" name=".mbr_params_page" address_symbol="__start_mbr_params_page" end_symbol="__stop_mbr_params_page" start = "0x0007E000" size="0x1000" />
  </MemorySegment>
  <MemorySegment name="uicr_bootloader_start_address" start="0x10001014" size="0x4">
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_bootloader_start_address" address_symbol="__start_uicr_bootloader_start_address" end_symbol="__stop_uicr_bootloader_start_address" start = "0x10001014" size="0x4" />
  </MemorySegment>
  <MemorySegment name="uicr_mbr_params_page" start="0x10001018" size="0x4">
    <ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_mbr_params_page" address_symbol="__start_uicr_mbr_params_page" end_symbol="__stop_uicr_mbr_params_page" start = "0x10001018" size="0x4" />
  </MemorySegment>
</Root>

Parents
  • Hi,

    It seems like you are missing some important files (nRFInitialize for instance is in the startup file, so that would be ses_startup_nrf52840.s if using the nRF52840 and Segger Embedded STudio ). I suggest you refer to a bootloader example to see all the files that are needed (or even better, start your project by copying an example and modifying that, instead of starting from scratch if that is what you have done).

  • I have done as you suggested - started a new bootloader project based on secure_bootloader_ble_s140_pca10056 Segger IDE solution. I built it but it fails due to linker errors:

    Rebuilding ‘secure_bootloader_ble_s140_pca10056’ from solution ‘secure_bootloader_ble_s140_pca10056’ in configuration ‘Release’
    Assembling ‘thumb_crt0.s’
    Compiling ‘nrf_log_frontend.c’
    Compiling ‘nrf_log_str_formatter.c’
    Compiling ‘app_error_weak.c’
    Compiling ‘app_scheduler.c’
    Compiling ‘app_util_platform.c’
    Compiling ‘crc32.c’
    Compiling ‘mem_manager.c’
    Compiling ‘nrf_assert.c’
    Compiling ‘nrf_atfifo.c’
    Compiling ‘nrf_atomic.c’
    Compiling ‘nrf_balloc.c’
    Compiling ‘nrf_fprintf.c’
    Compiling ‘nrf_fprintf_format.c’
    Compiling ‘nrf_fstorage.c’
    Compiling ‘nrf_fstorage_nvmc.c’
    Compiling ‘nrf_fstorage_sd.c’
    Compiling ‘nrf_memobj.c’
    Compiling ‘nrf_queue.c’
    Compiling ‘nrf_ringbuf.c’
    Compiling ‘nrf_section_iter.c’
    Compiling ‘nrf_strerror.c’
    Compiling ‘pb_common.c’
    Compiling ‘pb_decode.c’
    Compiling ‘cc310_bl_backend_ecc.c’
    Compiling ‘cc310_bl_backend_ecdsa.c’
    Compiling ‘cc310_bl_backend_hash.c’
    Compiling ‘cc310_bl_backend_init.c’
    Compiling ‘cc310_bl_backend_shared.c’
    Compiling ‘boards.c’
    Compiling ‘nrf_sdh.c’
    Compiling ‘nrf_sdh_ble.c’
    Compiling ‘nrf_sdh_soc.c’
    Compiling ‘nrf_nvmc.c’
    Compiling ‘nrfx_atomic.c’
    Compiling ‘nrf_crypto_ecc.c’
    Compiling ‘nrf_crypto_ecdsa.c’
    Compiling ‘nrf_crypto_hash.c’
    Compiling ‘nrf_crypto_init.c’
    Compiling ‘nrf_crypto_shared.c’
    Compiling ‘nrf_dfu_svci.c’
    Compiling ‘nrf_dfu_svci_handler.c’
    Compiling ‘nrf_svc_handler.c’
    Compiling ‘ble_srv_common.c’
    Compiling ‘nrf_bootloader.c’
    Compiling ‘nrf_bootloader_app_start.c’
    Compiling ‘nrf_bootloader_app_start_final.c’
    Compiling ‘nrf_bootloader_dfu_timers.c’
    Compiling ‘nrf_bootloader_fw_activation.c’
    Compiling ‘nrf_bootloader_info.c’
    Compiling ‘nrf_bootloader_wdt.c’
    Assembling ‘ses_startup_nrf52840.s’
    Assembling ‘ses_startup_nrf_common.s’
    Compiling ‘system_nrf52840.c’
    Compiling ‘dfu-cc.pb.c’
    Compiling ‘nrf_dfu.c’
    Compiling ‘nrf_dfu_ble.c’
    Compiling ‘nrf_dfu_flash.c’
    Compiling ‘nrf_dfu_handling_error.c’
    Compiling ‘nrf_dfu_mbr.c’
    Compiling ‘nrf_dfu_req_handler.c’
    Compiling ‘nrf_dfu_settings.c’
    Compiling ‘nrf_dfu_settings_svci.c’
    Compiling ‘nrf_dfu_transport.c’
    Compiling ‘nrf_dfu_utils.c’
    Compiling ‘nrf_dfu_validation.c’
    Compiling ‘nrf_dfu_ver_validation.c’
    Compiling ‘oberon_backend_chacha_poly_aead.c’
    Compiling ‘oberon_backend_ecc.c’
    Compiling ‘oberon_backend_ecdh.c’
    Compiling ‘oberon_backend_ecdsa.c’
    Compiling ‘oberon_backend_hash.c’
    Compiling ‘oberon_backend_hmac.c’
    Compiling ‘dfu_public_key.c’
    Compiling ‘main.c’
    Generating linker script ‘secure_bootloader_ble_s140_pca10056.ld’
    Linking secure_bootloader_ble_s140_pca10056.elf
    .text is larger than specified size
    .rodata is too large to fit in FLASH1 memory segment
    .rodata is larger than specified size
    .data is too large to fit in FLASH1 memory segment
    section .tdata overlaps absolute placed section .mbr_params_page
    section .mbr_params_page VMA [00000000000fe000,00000000000fefff] overlaps section .text VMA [00000000000f83b8,00000000000fea2f]
    section .crypto_data VMA [00000000000fea30,00000000000fea37] overlaps section .mbr_params_page VMA [00000000000fe000,00000000000fefff]
    section .bootloader_settings_page VMA [00000000000ff000,00000000000fffff] overlaps section .rodata VMA [00000000000feb28,00000000001005ab]
    Output/Release/Obj/secure_bootloader_ble_s140_pca10056/main.o: in function `main':
    undefined reference to `nrf_log_default_backends_init'
    Build failed

  • Some debug output:

    Generating linker script ‘secure_bootloader_ble_s140_pca10056.ld’
    Linking secure_bootloader_ble_s140_pca10056.elf
    .text is too large to fit in FLASH1 memory segment
    .text is larger than specified size
    .crypto_data is too large to fit in FLASH1 memory segment
    .dfu_trans is too large to fit in FLASH1 memory segment
    .svc_data is too large to fit in FLASH1 memory segment
    .log_const_data is too large to fit in FLASH1 memory segment
    .nrf_balloc is too large to fit in FLASH1 memory segment
    .sdh_ble_observers is too large to fit in FLASH1 memory segment
    .sdh_req_observers is too large to fit in FLASH1 memory segment
    .sdh_state_observers is too large to fit in FLASH1 memory segment
    .sdh_stack_observers is too large to fit in FLASH1 memory segment
    .sdh_soc_observers is too large to fit in FLASH1 memory segment
    .fs_data is too large to fit in FLASH1 memory segment
    .rodata is too large to fit in FLASH1 memory segment
    .rodata is larger than specified size
    .data is too large to fit in FLASH1 memory segment
    section .tdata overlaps absolute placed section .mbr_params_page
    section .mbr_params_page VMA [00000000000fe000,00000000000fefff] overlaps section .text VMA [00000000000f83b8,0000000000104127]
    Build failed

    FLASH1 size seems way too small. I have not added any of my own code to this project. This is just the code that came with the example. Config file attached.

    1452.sdk_config.h

  • Hi,

    These linker warnings indicate that the bootloader is too large to fit in the assigned memory region. When I test, I get the same issue as you if I for instance reduce the size of the region (increase the start address and reduce the size) in the linker configuration or change the optimization. That is a bit odd though, as this example project builds fine when I test. Did you do any changes? If so, which?

    So in short, this should not happen out of the box, but is expected in case of size changes. The question then is if the size change is wanted, and if so, you need to adjust the start address and size which you do here:

    If this is not intentional though, I would first try to figure out why the size is larger than expected.

Reply
  • Hi,

    These linker warnings indicate that the bootloader is too large to fit in the assigned memory region. When I test, I get the same issue as you if I for instance reduce the size of the region (increase the start address and reduce the size) in the linker configuration or change the optimization. That is a bit odd though, as this example project builds fine when I test. Did you do any changes? If so, which?

    So in short, this should not happen out of the box, but is expected in case of size changes. The question then is if the size change is wanted, and if so, you need to adjust the start address and size which you do here:

    If this is not intentional though, I would first try to figure out why the size is larger than expected.

Children
  • I had to make two changes to sdk_config.h:

    // <i> Choose memory allocator used by nrf_crypto. Default is alloca if possible or nrf_malloc otherwise. If 'User macros' are selected, the user has to create 'nrf_crypto_allocator.h' file that contains NRF_CRYPTO_ALLOC, NRF_CRYPTO_FREE, and NRF_CRYPTO_ALLOC_ON_STACK.
    // <0=> Default
    // <1=> User macros
    // <2=> On stack (alloca)
    // <3=> C dynamic memory (malloc)
    // <4=> SDK Memory Manager (nrf_malloc)

    #ifndef NRF_CRYPTO_ALLOCATOR
    #define NRF_CRYPTO_ALLOCATOR 2

    I chose 2 (On stack). The example file has 1 (User macros) defined which cause a compile fail.

    #define NRF_LOG_ENABLED 1 

    Changed to 1 from 0 to enable logging. Also would then not compile until I added nrf_log_default_backends.c to project.

    These changes don't appear to add significant flash space.

  • I built the project as you did and it builds with no errors. FLASH1 is 99.9% used. Not much room left for adding anything.

    RAM is only 14% used.

    Any suggestions on how to safely change FLASH1 layout to make space for my apps?

  • Hi,

    davidb said:

    #define NRF_LOG_ENABLED 1 

    Changed to 1 from 0 to enable logging. Also would then not compile until I added nrf_log_default_backends.c to project.

    Yes, that is expected. For most example bootloader projects, there is a corresponding "_debug" project. The main addition here is logging. And for that reason, it also has more memory reserved (and a lower start address). The normal projects (without the "_debug" suffix) does not include the logger dependencies, nor is there room for the logger.

    davidb said:

    I built the project as you did and it builds with no errors. FLASH1 is 99.9% used. Not much room left for adding anything.

    RAM is only 14% used.

    Any suggestions on how to safely change FLASH1 layout to make space for my apps?

    The way this is shown in SES gives the wrong impression. This means that the bootloader uses almost everything of the allocated flash, but that is not the same as all the flash. See the screenshot from my previous post where i highlighted the linker configuration for the flash memory. In that case, the bootloader start address is 0xF8000, and everything there can be used for other things (like SoftDevice, application and persistent storage). See memory layout in the bootloader documentation for a better overview.

    Regarding RAM the bootloader and application does not run at the same time, so the RAM usage of the bootloader does not have any impact on what is available for the application (it can overlap).

Related