Linker Script
Here is an example of an arm linker script (they end in .ld). Let's go over the basics below.
The entry point. This is pretty self explanatory. The input is the label that will be called as first instructions.
The next interesting thing to note here is the symbol _estack. In a linker file, symbols are assigned addresses- here it is being assigned to the end of RAM b/c this is a stack downward growth setup. The practical aspect of this is that this symbol can be accessed in your code as follows:
extern int* _estack asm("_estack");
Note here for an explanation on the need for the asm() keyword.
Next starts the SECTIONS. This is simply a way to map linker inputs to memory output locations. The memory types (FLASH, RAM, CCMRAM) are defined just above this (self explanatory).
The inputs are inside the output sections. Once the sections block starts, memory starts at the beginning and gets incremented by the size of the output section. The >MEMORY_TYPE at the end of an output section tells the linker what memory this should live in.
For example, the .text output will contain any inputs with the .text tag or .text* (wildcard).
Now the beautiful part is that you can easily mark a variable or function in your c/c++ code and it will be put in the output location that you want.
All code automatically gets tagged in the text section, so that's not a good example. Let's look a bit farther down the linker script for a practical example.
Here is the init_array section:
Most applications using standard library have an array of functions that are called right after data+bss sections have been initialized in RAM. In order to add another function to be called in initialization, we can add it to this memory section. The output is .init_array and the inputs are anything tagged as init_array (plus wildcard). So, we simply tag our code as follows:
This was from an example where I wanted to initialize parts of memory for stack/heap analysis right at the beginning of the code. The last line, where I add the __attribute__ and assign the function I want to use to the init_array inputs. It then gets added into the correct place in memory.
The full linker script can be seen below: