(1) OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
(2) OUTPUT_ARCH(arm)
(3) ENTRY(Reset_Handler) /* entry Point */
(4) MEMORY { /* memory map of STM32F107C */
(5) ROM (rx) : ORIGIN = 0x08000000, LENGTH = 256K
(6) RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
}
/* The size of the stack used by the application. NOTE: you need to adjust */
(7) STACK_SIZE = 1024;
/* The size of the heap used by the application. NOTE: you need to adjust */
(8) HEAP_SIZE = 0;
SECTIONS {
(9) .isr_vector : { /* the vector table goes FIRST into ROM */
(10) KEEP(*(.isr_vector)) /* vector table */
(11) . = ALIGN(4);
(12) } >ROM
(13) .text : { /* code and constants */
. = ALIGN(4);
(14) *(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
(15) *(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
(16) KEEP (*(.init))
(17) KEEP (*(.fini))
. = ALIGN(4);
(18) _etext = .; /* global symbols at end of code */
} >ROM
(19) .preinit_array : {
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ROM
(20) .init_array : {
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >ROM
(21) .fini_array : {
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ROM
(22) .data : {
__data_load = LOADADDR (.data);
__data_start = .;
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
__data_end__ = .;
_edata = __data_end__;
(23) } >RAM AT>ROM
21 of 37 Copyright © Quantum Leaps, LLC. All Rights Reserved. QDK
STM32 with GNU
www.state-machine.com/arm
(24) .bss : {
__bss_start__ = . ;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = .;
(25) } >RAM
(26) PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
PROVIDE ( __end__ = _ebss );
(27) .heap : {
__heap_start__ = . ;
. = . + HEAP_SIZE;
. = ALIGN(4);
__heap_end__ = . ;
} >RAM
(28) .stack : {
__stack_start__ = . ;
. = . + STACK_SIZE;
. = ALIGN(4);
__c_stack_top__ = . ;
__stack_end__ = . ;
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ : {
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
}
Listing 3 shows the linker script for the STM32F10x MCU. The script is identical for C and C++ versions.
The highlights of the linker script are as follows:
(1) The OUTPUT_FORMAT directive specifies the format of the output image (elf32, little-endian, ARM)
(2) OUTPUT_ARCH specifies the target machine architecture.
(3) ENTRY explicitly specifies the first instruction to execute in a program
(4) The MEMORY command describes the location and size of blocks of memory in the target.
(5) The region ROM corresponds to the on-chip flash of the STM32F10x device. It can contain read-only
and executable sections (rx), it starts at 0x08000000 and is 256KB in size.
(6) The region RAM corresponds to the on-chip SRAM of the STM32F10x device. It can contain read-
only, read-write and executable sections (rwx), it starts at 0x20000000 and is 64KB in size.
(7) The STACK_SIZE symbol determines the sizes of the ARM Main stack. You need to adjust the size
for your particular application. The stack size cannot be zero.
(8) The HEAP_SIZE symbol determines the sizes of the heap. You need to adjust the sizes for your
particular application. The heap size can be zero.
(9) The .isr_vector section contains the ARM Cortex IVT and must be located as the first section in
ROM.
(10) This line locates all .isr_vector section.
(11) The section size is aligned to the 4-byte boundary
(12) This section is loaded directly to the ROM region defined in the MEMORY command.
(13) The .text section is for code and read-only data accessed in place.
(14) The .text section groups all individual .text and .text* sections from all modules.
(15) The section .rodata is used for read-only (constant) data, such as look-up tables.
(16-17) The .init and .fini sections are synthesized by the GNU C++ compiler and are used for static
constructors and destructors. These sections are empty in C programs.
(18) The .text section is located and loaded to ROM.
(19,20) The .preinint_array and .inint_array sections hold arrays of function pointers that are
called by the startup code to initialize the program. In C++ programs these hold pointers to the static
constructors that are called by __libc_init_array() before main().
(21) The .fini_array section holds an array of function pointers that are called before terminating the
program. In C++ programs this array holds pointers to the static destructors.
(22) The .data section contains initialized data.
(23) The .data section is located in RAM, but is loaded to ROM and copied to RAM during startup.
(24) The .bss section contains uninitialized data. The C/C++ standard requires that this section must be
cleared at startup.
(25) The .bss section is located in RAM only.
(26) The symbols marking the end of the .bss sections are used by the startup code to allocate the
beginning of the heap.
(27) The .heap section contains the heap (please also see the HEAP_SIZE symbol definition in line (8))
NOTE: Even though the linker script supports the heap, it is almost never a good idea to use the heap in embedded
systems. Therefore the examples provided with this Application Note contain the file no_heap.c/cpp, which contains
dummy definitions of malloc()/free()/realloc() functions. Linking this file saves some 2.8KB of code space
compared to the actual implementation of the memory allocating functions.
(28) The .stack section contains the C stack (please also see the STACK_SIZE symbol definition in line
(7)). The stack memory is initialized with a given bit-pattern at startup.
4.1 Linker Options
The linker options for C and C++ are the same and are defined in the Makefile located in the DPP
directory. The most
Linker options for C and C++ builds.
(1) LINKFLAGS = -T ./$(APP_NAME).ld /
(2) -o $(BINDIR)/$(APP_NAME).elf /
(3) -Wl,-Map,$(BINDIR)/$(APP_NAME).map,--cref,--gc-sections
(1) –T option specifies the name of the linker script (dpp.ld in this case).
(2) –o option specifies the name of image file (dpp.elf in this case).
(3) --gc-sections enable garbage collection of unused input sections..