secure bootloader linker - migrating from SES to GCC

We used the secure bootloader example, and then made room in the FLASH for an LCD driver/animation.

SES is building fine

Problem - 
GCC is running out of space in FLASH. 
I would expect similar binaries from each toolchain. Seems like I might have screwed up the linker. 

SES linker settings follow in .emproject - 

linker_section_placement_macros="FLASH_PH_START=0x0;FLASH_PH_SIZE=0x100000;RAM_PH_START=0x20000000;RAM_PH_SIZE=0x40000;FLASH_START=0xee000;FLASH_SIZE=0x10000;RAM_START=0x20005978;RAM_SIZE=0x3a688"
linker_section_placements_segments="FLASH RX 0x0 0x100000;RAM1 RWX 0x20000000 0x40000;mbr_params_page RX 0x000FE000 0x1000;bootloader_settings_page RX 0x000FF000 0x1000;uicr_bootloader_start_address RX 0x10001014 0x4;uicr_mbr_params_page RX 0x10001018 0x4"

I took the linker script from the secure bootloader GCC example, with the same size modifications for the LCD driver/animation. 

MEMORY
{
FLASH (rx) : ORIGIN = 0xee000, LENGTH = 0x10000
RAM (rwx) : ORIGIN = 0x20005978, LENGTH = 0x3a688
uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4
bootloader_settings_page (r) : ORIGIN = 0x000FF000, LENGTH = 0x1000
uicr_mbr_params_page (r) : ORIGIN = 0x10001018, LENGTH = 0x4
mbr_params_page (r) : ORIGIN = 0x000FE000, LENGTH = 0x1000
}

/usr/local/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/bin/ld: region FLASH overflowed with .data and user data
/usr/local/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/bin/ld: section .mbr_params_page VMA [00000000000fe000,00000000000fefff] overlaps section .text VMA [00000000000ee000,00000000000ff3c7]
/usr/local/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/bin/ld: section .crypto_data VMA [00000000000ff3c8,00000000000ff3cf] overlaps section .bootloader_settings_page VMA [00000000000ff000,00000000000fffff]
/usr/local/gcc-arm-none-eabi-6-2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/bin/ld: region `FLASH' overflowed by 5340 bytes
collect2: error: ld returned 1 exit status
make: *** [_build/ocho.out] Error 1

Looking at the memory maps, I notice something different.
SES throws things into a section called reserved_flash, GCC doesn't make that distinction. 
The Memory Config summaries show flash beginning at 0x0 for SES, then reserved flash at 0xee000.

.reserved_flash
0x00000000 0xee000
0x00000000 __reserved_flash_start__ = .
*(.reserved_flash .reserved_flash.*)
0x000ee000 . = MAX (((__reserved_flash_start__ + 0xee000) - 0x0), .)
*fill* 0x00000000 0xee000
0x000ee000 __reserved_flash_end__ = (__reserved_flash_start__ + SIZEOF (.reserved_flash))
0x000ee000 __reserved_flash_size__ = SIZEOF (.reserved_flash)
0x000ee000 __reserved_flash_load_end__ = __reserved_flash_end__
0x00000001 . = ASSERT (((__reserved_flash_start__ == __reserved_flash_end__) || ((__reserved_flash_end__ - __FLASH_segment_start__) <= __FLASH_segment_size__)), error: .reserved_flash is too large to fit in FLASH memory segment)
0x00000001 . = ASSERT ((__reserved_flash_size__ <= 0xee000), error: .reserved_flash section is larger than specified size)
0x000ee000 __vectors_load_start__ = 0xee000

.vectors 0x000ee000 0x200
0x000ee000 __vectors_start__ = .

SES memory config summary

Name Origin Length Attributes
UNPLACED_SECTIONS 0x00000000 0x00000000 xw
uicr_mbr_params_page 0x10001018 0x00000004 xw
uicr_bootloader_start_address 0x10001014 0x00000004 xw
RAM1 0x20000000 0x00040000 xw
FLASH 0x00000000 0x00100000 xw
*default* 0x00000000 0xffffffff

GCC memory config summary

Memory Configuration


Name Origin Length Attributes
FLASH 0x00000000000ee000 0x0000000000010000 xr
RAM 0x0000000020005978 0x000000000003a688 xrw
uicr_bootloader_start_address 0x0000000010001014 0x0000000000000004 r
bootloader_settings_page 0x00000000000ff000 0x0000000000001000 r
uicr_mbr_params_page 0x0000000010001018 0x0000000000000004 r
mbr_params_page 0x00000000000fe000 0x0000000000001000 r
*default* 0x0000000000000000 0xffffffffffffffff

Full GCC linker below

6038.gcc_nrf52.ld

  • Hello,

    I couldn’t find any errors in the linker script you posted. It seems that the bootloader image is simply too large to fit in the allocated region. The 'reserved' section used by SES is just a placeholder to indicate that the area is reserved for the application and softdevice. This section is not required and it can easily be removed by editing the flash_placement.xml file which is the file SES generates the linker script from. 

    Please try to increase the bootloader FLASH region with a couple of flash pages to allow the build to succeed, then compare the *.map files from the SES and pure GCC build to see if you can determine what part is making the GCC image that much bigger. Maybe it has to do with the C libs.

    Also, this may not be directly related to your issue, but there was an error in the flash_placement.xml configuration in an older SDK version. This error would prevent you from getting a linker error if the bootloader code grew into the mbr_params_page and bootloader_settings_page sections. These sections need to be placed in the FLASH region, as shown below.

      

    Best regards,

    Vidar

  • Thanks Vidar. I just figured it out using your recommended method.
    I first thought it was optlevel, but by digging in there I found the root cause. 
    My Makefile had float printf enabled, my SES project did not. 

Related