SEGGER Linker Script Files

From SEGGER Wiki
Jump to: navigation, search

Linker scripts for the SEGGER Linker are easy to write and provide full flexibility and smart features. SEGGER Linker Scripts for most embedded systems can be written with about 20 to 50 lines of statements.

The SEGGER Linker User guide is available at https://segger.com/doc/UM20005_Linker.html

Minimal Example Script

This is an example of a minimalist linker script which could define a complete application binary:

// Define Memory Regions
define memory with size = 4G; 
define region FLASH = [from 0x00000000 size 512k];
define region RAM   = [from 0x1fff0000 size 64k] + [0x20000000 size 192k];
// Define Blocks
define block heap  with size = 10240,  alignment = 8, readwrite access { };
define block stack with size = 2048, alignment = 8, readwrite access { };
// Configure Initialization
do not initialize                       { section .non_init, section .non_init.*};
initialize by copy with packing=auto    { section .data, section .data.* };
initialize by symbol __SEGGER_init_heap { block heap  };
// Place Inputs
place at start of FLASH                 { section .vectors };
place in FLASH                          { readexec, readonly };
place in RAM                            { readwrite, zeroinit };
place at end of RAM                     { block heap, block stack };

Section Placement

The SEGGER Linker enables smart placement of symbols and sections in memory, which can be controlled in the linker script. After defining memory regions, such as Flash and RAM, the placement is done with section selectors.

Section selectors, as the name suggests, select sections from the input files. Sections are selected by symbol, name, or attributes.

Placement by Attribute

Sections have attributes which define whether they are executable, writable, or special init and exit sections.

The SEGGER Linker supports catch-all section selectors which evaluate these attributes. The selectors are:

  • readexec
  • readonly
  • readwrite
  • zeroinit
  • init_array and fini_array

With catch-all section selectors the simplest placement in the linker script can look like this:

place in FLASH { readexec, readonly };
place in RAM   { readwrite, zeroinit };

Placement by Symbol

The SEGGER Linker supports section selection by symbol names. Given the symbol name, the SEGGER Linker selects the section which is associated with the symbol.

This feature for example enables placement of symbols at a fixed address, even without knowledge of which section the symbol will be in.

place at address 0x400 { symbol aConfig };

Placement by Section Name

A linker works on elf sections, which are taken from the input files. Each section has a name, which usually describes its purpose and contents. There may be multiple sections with the same name.

The SEGGER Linker's section selectors take all sections which match the given string. The string can be a full section name or a wildcard.

place in RAM { section .bss };

will only match sections with the exact name ".bss".

Most compilers create one "sub-section" per symbol to be placed into a section. With wildcard selectors all those sub-sections can be selected.

place in RAM { section .bss, section .bss.* };

will match the section ".bss" as well as all sections which start with ".bss."

Generic Cortex-M Linker Script

This is the generic linker script for Cortex-M target devices, which in extension to the minimalist example takes care of commonly used user-defined sections, vectors in Flash and RAM, and Arm-specific sections.

 define memory with size = 4G;
 //
 // Combined regions per memory type
 //
 define region FLASH = FLASH1;
 define region RAM   = RAM1;
 //
 // Block definitions
 //
 define block vectors                        { section .vectors };                                   // Vector table section
 define block vectors_ram                    { section .vectors_ram };                               // Vector table section
 define block ctors                          { section .ctors,     section .ctors.*, block with         alphabetical order { init_array } };
 define block dtors                          { section .dtors,     section .dtors.*, block with reverse alphabetical order { fini_array } };
 define block exidx                          { section .ARM.exidx, section .ARM.exidx.* };
 define block tbss                           { section .tbss,      section .tbss.*  };
 define block tdata                          { section .tdata,     section .tdata.* };
 define block tls                            { block tbss, block tdata };
 define block tdata_load                     { copy of block tdata };
 define block heap  with size = __HEAPSIZE__,  alignment = 8, /* fill =0x00, */ readwrite access { };
 define block stack with size = __STACKSIZE__, alignment = 8, /* fill =0xCD, */ readwrite access { };
 //
 // Explicit initialization settings for sections
 // Packing options for initialize by copy: packing=auto/lzss/zpak/packbits
 //
 do not initialize                           { section .non_init, section .non_init.*, section .*.non_init, section .*.non_init.* };
 do not initialize                           { section .no_init, section .no_init.*, section .*.no_init, section .*.no_init.* };   // Legacy sections, kept for backwards compatibility
 do not initialize                           { section .noinit, section .noinit.*, section .*.noinit, section .*.noinit.* };       // Legacy sections, used by some SDKs/HALs
 do not initialize                           { block vectors_ram };
 initialize by copy with packing=auto        { section .data, section .data.*, section .*.data, section .*.data.* };               // Static data sections
 initialize by copy with packing=auto        { section .fast, section .fast.* };                                                   // "RAM Code" sections
 initialize by symbol __SEGGER_init_heap     { block heap  };                                        // Init the heap if there is one
 initialize by symbol __SEGGER_init_ctors    { block ctors };                                        // Call constructors for global objects which need to be constructed before reaching main (if any). Make sure this is done after setting up heap.
 //
 // Explicit placement in FLASHn
 //
 place in FLASH1                             { section .FLASH1, section .FLASH1.* };
 //
 // FLASH Placement
 //
 place at start of FLASH                     { block vectors };                                      // Vector table section
 place in FLASH with minimum size order      { block tdata_load,                                     // Thread-local-storage load image
                                               block exidx,                                          // ARM exception unwinding block
                                               block ctors,                                          // Constructors block
                                               block dtors,                                          // Destructors block
                                               readonly,                                             // Catch-all for readonly data (e.g. .rodata, .srodata)
                                               readexec                                              // Catch-all for (readonly) executable code (e.g. .text)
                                             };
 //
 // Explicit placement in RAMn
 //
 place in RAM1                               { section .RAM1, section .RAM1.* };
 //
 // RAM Placement
 //
 place at start of RAM                       { block vectors_ram };
 place in RAM with auto order                { section .fast, section .fast.*,                       // "ramfunc" section
                                               block tls,                                            // Thread-local-storage block
                                               readwrite,                                            // Catch-all for initialized/uninitialized data sections (e.g. .data, .noinit)
                                               zeroinit                                              // Catch-all for zero-initialized data sections (e.g. .bss)
                                             };
 place in RAM                                { block heap };                                         // Heap reserved block
 place at end of RAM                         { block stack };                                        // Stack reserved block at the end