1# Linking Picolibc applications 2 3Linking embedded applications requires significant target-specific 4information, including the location of various memory sections along with 5a range of application-specific memory settings. 6 7You can create your own custom linker script, or you can use the 8linker script provided by Picolibc. This document describes how to do 9either. 10 11## Creating a Custom Linker Script 12 13Aside from the application and hardware specific aspects of creating a 14linker script, if your application is using the Picolib startup code, 15then you need to define the addresses used in that code, and set up 16the data as required. Checkout the [Initializers in Picolibc](init.md) document 17for details on what names to declare. 18 19To use a custom linker script when linking with gcc using 20`-specs=picolibc.specs`, you'll need to use the gcc `-T` option 21instead of using the `-Wl,-T` linker pass through option. This causes 22`picolibc.specs` to not add the picolibc linker script along with your 23custom one: 24 25 gcc -specs=picolibc.specs -Tcustom.ld 26 27## Using picolibc.ld 28 29Picolibc provides a default linker script which can often be used to 30link applications, providing that your linking requirements are fairly 31straightforward. To use picolibc.ld, you'll create a custom linker 32script that sets up some variables and then INCLUDE's 33picolibc.ld. Here's a sample custom linker script `sample.ld`: 34 35 __flash = 0x08000000; 36 __flash_size = 128K; 37 __ram = 0x20000000; 38 __ram_size = 16k; 39 __stack_size = 512; 40 41 INCLUDE picolibc.ld 42 43This is for an STM32L151 SoC with 128kB of flash and 16kB of RAM. We 44want to make sure there's space for at least 512 bytes of stack. To use 45this with gcc, the command line would look like this: 46 47 gcc -specs=picolibc.specs -Tsample.ld 48 49Alternatively, you can specify those values using `--defsym` and use 50picolibc.ld as the linker script: 51 52 cc -Wl,--defsym=__flash=__0x08000000 -Wl,--defsym=__flash_size=128K ... -Tpicolibc.ld 53 54### Defining Memory Regions 55 56Picolibc.ld defines only two memory regions: `flash` and `ram`. Flash 57is an addressable region of read-only memory which holds program text, 58constant data and initializers for read-write data. Ram is read-write 59memory which needs to be initialized before your application starts. 60 61As shown above, you declare the base and size of both memory regions 62in your linker script: 63 64 * `__flash` specifies the lowest address in read-only memory used by 65 your application. This needs to be in flash, but need not be the 66 start of actual flash in the device. 67 68 * `__flash_size` specifies the amount of read-only memory you want to 69 allow the application to fill. This need not be all of the 70 available memory. 71 72 * `__ram` specifies the lowest address you want the linker to 73 allocate to read-write data for the application. 74 75 * `__ram_size` specifies the maximum amount of read-write memory you 76 want to permit the application to use. 77 78 * `__stack_size` reserves this much space at the top of ram for the 79 initial stack. 80 81### Arranging Code and Data in Memory 82 83Where bits of code and data land in memory can be controlled to some 84degree by placing variables and functions in various sections by 85decorating them with `__attribute__ ((section(`*name*`)))`. You'll 86find '*' used in the following defintions; that can be replaced with 87any string. For instance, when you use -ffunction-sections or 88-fdata-sections with gcc, that creates a section named 89`.text.`*function-name* for each function and `.data.`*variable-name* 90for each variable. Here are all of the section names used in 91picolibc.ld: 92 93#### Flash contents 94 95These are stored in flash and used directly from flash. 96 97 1. Contents located first in flash. These can be used for interrupt 98 vectors or startup code. 99 100 * `.text.init.enter` 101 * `.data.init.enter` 102 * `.init`, `.init.*` 103 104 2. The bulk of the application code 105 106 * `.text.unlikely`, `.text.unlikely.*` 107 * `.text.startup`, `.text.startup.*` 108 * `.text`, `.text.*` 109 * `.gnu.linkonce.t.*` 110 111 3. Cleanup routines 112 113 * `.fini`, `.fini.*` 114 115 4. Read-only data 116 117 * `.rdata` 118 * `.rodata`, `.rodata.*` 119 * `.gnu.linkonce.r.*` 120 * `.srodata.cst16` 121 * `.srodata.cst8` 122 * `.srodata.cst4` 123 * `.srodata.cst2` 124 * `.srodata`, `.srodata.*` 125 * `.data.rel.ro`, `.data.rel.ro.*` 126 * `.got`, `.got.*` 127 128 5. Addresses of pre-initialization functions. Each of the addresses 129 in the list is called during program initialization, before 130 `_init()`. 131 132 * `.preinit_array` 133 134 6. Addresses of initializer/constructor functions. Each of the 135 addresses in the list is called during program initialization, 136 before `main()`. 137 138 * `.init_array`, `.ctors` 139 140 7. Addresses of de-initializer/destructor functions. Each of the 141 addresses in the list is called after the program finishes, after 142 `main()`. 143 144 * `.fini_array`, `.dtors` 145 146#### Uninitialized ram contents 147 148You can place items in RAM that is *not* initialized by 149picolibc. These can be handy if you need values in memory to survive 150reset, perhaps as a way to communicate from the application to a boot 151loader or similar. These are placed first in RAM and are sorted by 152name so that the order is consistent across linking operations: 153 154 1. `.preserve.*` 155 156 2. `.preserve` 157 158#### Initialized ram contents 159 160picolibc.ld places values for variables with explicit initializers in 161flash and marks the location in flash and in RAM. At application 162startup, picocrt uses those recorded addresses to copy data from flash 163to RAM. As a result, any initialized data takes twice as much memory; 164the initialization values stored in flash and the runtime values 165stored in ram. Making values read-only where possible saves the RAM. 166 167 1) `.data`, `.data.*` 168 169 2) `.gnu.linkonce.d.*` 170 171 3) `.sdata`, `.sdata.*`, `.sdata2.*` 172 173 4) `.gnu.linkonce.s.*` 174 175Picolibc uses native toolchain TLS support for values which should be 176per-thread. This means that variables like `errno` will be referenced 177using TLS mechanisms. To make these work even when the application 178doesn't support threading, Picolibc allocates a static copy of the TLS 179data in RAM. Picocrt initializes the architecture TLS mechanism to 180reference this static copy. 181 182By arranging the static copy of initialized and zero'd TLS data right 183at the data/bss boundary, picolibc can initialize the TLS block as a 184part of initializing RAM with no additional code. This requires a bit 185of a trick as the linker doesn't allocate any memory for TLS bss 186segments; picolibc.ld makes space by simply advancing the memory 187location by the size of the TLS bss segment. 188 189 1) `.tdata`, `.tdata.*`, `.gnu.linkonce.td.*` 190 191#### Cleared ram contents 192 193Variables without any explicit initializers are set to zero by picocrt 194at startup time. The first chunk of these is part of the TLS block: 195 196 1) `.tbss`, `.tbss.*`, `.gnu.linkonce.tb.*` 197 2) `.tcommon` 198 199After the TLS bss section comes the regular BSS variables: 200 201 1) `.sbss*` 202 2) `.gnu.linkonce.sb.*` 203 3) `.bss`, `.bss.*` 204 4) `.gnu.linkonce.b.*` 205 5) `COMMON` 206