Hi, I'm trying to compile the bootloader example using GCC instead of Keil compiler.
To do so, I copied the bootloader example and started editing the file bootloader_util_arm.c, in particular I've changed:
__asm void StartApplication(uint32_t start_addr)
{
LDR R2, [R0]
MSR MSP, R2
LDR R3, [R0, #0x00000004]
BX R3
ALIGN
}
in
void StartApplication(uint32_t start_addr)
{
asm volatile (
"LDR R2, [R0] \n\t"
"MSR MSP, R2 \n\t"
"LDR R3, [R0, #0x00000004] \n\t"
"BX R3 \n\t"
".align \n\t"
);
}
Then I changed
uint8_t m_boot_settings[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS))) __attribute__((used));
uint32_t m_uicr_bootloader_start_address __attribute__((at(NRF_UICR_BOOT_START_ADDRESS))) = BOOTLOADER_REGION_START;
in
uint8_t m_boot_settings[CODE_PAGE_SIZE] __attribute__((section(".bootloader_settings"))) __attribute__((used));
uint32_t m_uicr_bootloader_start_address __attribute__((section(".bootloader_addr"))) __attribute__((used)) = BOOTLOADER_REGION_START;
And now, I need to edit the linker script in order to add the sections used above, so I've copied the two linker scripts gcc_nrf51_common.ld and gcc_nrf51_s110_xxaa.ld and edited like this.
gcc_nrf51_s110_xxaa.ld:
/* Linker script to configure memory regions. */
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
MEMORY
{
FLASH (rx) : ORIGIN = 0x00014000, LENGTH = 0x2C000
UICR (rwx) : ORIGIN = 0x10001000, LENGTH = 0x18
RAM (rwx) : ORIGIN = 0x20002000, LENGTH = 0x2000
}
INCLUDE "gcc_nrf51_common.ld"
gcc_nrf51_common.ld:
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.Vectors))
*(.text*)
*(.init)
*(.fini)
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
*(.eh_frame*)
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
.bootloader_settings 0x0003FC00 :
{
KEEP(*(.bootloader_settings))
} > FLASH
__etext = .;
.bootloader_addr 0x10001014 :
{
KEEP(*(.bootloader_addr))
} > UICR
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
*(.preinit_array)
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
*(SORT(.init_array.*))
*(.init_array)
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
*(SORT(.fini_array.*))
*(.fini_array)
PROVIDE_HIDDEN (__fini_array_end = .);
*(.jcr)
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
end = __end__;
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}
Then in the Makefile I specified the linker scripts to use when building the executable.
Compilation and linking goes fine, without any errors, but the resulting executable has a size of 256MB!
I found that the problem seems to be the KEEP(*(.bootloader_addr)), because if I cut out this, I get an executable of 176KB, but if I remove the KEEP instruction the linker discards the bootloader_addr section (I checked this running the arm-none-eabi-nm on the .out executable).
WIth the KEEP instruction (.bin file has size of 256MB), running the command nm:
arm-none-eabi-nm _build/dfu_single_bank_ble_s110.out | sort
...
...
00040000 D __etext
10001014 D m_uicr_bootloader_start_address
20002000 D __data_start__
...
Without the KEEP instruction (.bin file has size of 176KB), I get:
arm-none-eabi-nm _build/dfu_single_bank_ble_s110.out | sort
...
...
00040000 D __etext
20002000 D __data_start__
...
I'm new with linker scripts and I suspect that my modified ld scripts could have some bugs or I have made some mistakes somewhere... but I don't know where to search the error that makes the executable become 256MB...
Thanks for any help/support.
Regards, Samuele.