The most thoroughly commented linker script (probably)

rramadass1 pts0 comments

The most thoroughly commented linker script (probably) - Stargirl (Thea) Flowers

Posted by Stargirl Flowers on January 13, 2021<br>· view all posts

The most thoroughly commented linker script (probably)

While developing the firmware for Winterbloom's Castor & Pollux, I got very curious as to just what the Microchip/Atmel-provided linker script was doing.

If you've never heard of or seen a linker script before you're not alone. Most of us never even have to think about them, however, on memory constrained embedded devices it's not uncommon to need to modify the default linker script.

The linker script controls how ld combines all of your .o files into a single .elf and how that resulting .elf file gets loaded by the target processor.

So I was staring at this script that made absolutely no sense to me. It's filled with incantations and mysterious symbols and there's no indication of what they're for or where they come from.

So I did a lot of research and now I can present to you the most thoroughly commented linker script 1.

You can see this script in its entirety, comments and all, on GitHub. But if you'd like to read it here instead it's transcribed below.

Output format

Output format sets the ELF output format to use a specific BFD backend.

The first is the default BFD. The second and third arguments are used<br>when big (-EB) or little (-EL) endian is requested.

Since the SAM D series are configured with only little endian support,<br>"elf32-littlearm" is used across the board. This option seems to be<br>included by Atmel/Microchip out of an abundance of caution, as<br>arm-none-eabi-ld will do the right thing and use "elf32-littlearm" by<br>default.

The list of acceptable values can be obtained using objdump -i.

References:

https://sourceware.org/binutils/docs/ld/Format-Commands.html#Format-Commands

https://sourceware.org/binutils/docs/ld/BFD.html

https://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D21_DA1_Family_DataSheet_DS40001882F.pdf<br>Section 11.1.11, Cortex M0+ Configuration

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

CPU memory configuration variables

These variables are used by the following "MEMORY" command to define<br>the various memory spaces.

For the SAMD21G18A used by this project, the available Flash is<br>262kB and the available SRAM is 32kB.

This project also reserves 8kB for the bootloader and 1kB for<br>"non-volatile memory" (NVM) - which is used by the application<br>to store calibration and user settings.

References:

https://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D21_DA1_Family_DataSheet_DS40001882F.pdf<br>Section 10.2, Physical Memory Map

FLASH_SIZE = 0x40000; /* 256kB */<br>BOOTLOADER_SIZE = 0x2000; /* 8kB */<br>NVM_SIZE = 0x400; /* 1kbB */<br>SRAM_SIZE = 0x8000; /* 32kB */

ARM Cortex-M processors use a descending stack and generally<br>require stack space to be set aside in RAM.

The application's behavior determines just how much stack space<br>should be reserved. I generally start with 2kB (0x800) of<br>stack space for Cortex-M0+ projects programmed in C .

You can analyze stack usage in GCC using the -fstack-usage<br>flag and you can enable compiler warnings for stack usage<br>with -Wstack-usage=STACK_SIZE.

References:

https://embeddedartistry.com/blog/2020/08/17/three-gcc-flags-for-analyzing-memory-usage/

https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/how-much-stack-memory-do-i-need-for-my-arm-cortex--m-applications

https://gcc.gnu.org/onlinedocs/gnat_ugn/Static-Stack-Usage-Analysis.html

https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x800;

Memory space definition

This section declare blocks of memories for specific purposes. Since an<br>ARM's address space is generally split between Flash, SRAM, peripherals,<br>and other regions, it's necessary to tell the linker where different<br>types of data can go in the address space.

These blocks will be used in the SECTIONS command below.

References:

https://sourceware.org/binutils/docs/ld/MEMORY.html#MEMORY

https://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D21_DA1_Family_DataSheet_DS40001882F.pdf<br>Section 10.2, Physical Memory Map

MEMORY

Start with the Flash memory region. On the SAMD21, Flash starts at<br>the beginning of the address space (0x00000000) and is contiguous<br>right up to the size of the Flash. Flash is marked a rx so<br>that the linker knows that this space is read-only (r) and<br>executable (x).

The "bootloader" section allows this firmware to work with the uf2<br>bootloader. The bootloader takes the first 0x2000 bytes of flash<br>memory.

References:

https://github.com/adafruit/uf2-samdx1#configuration

bootloader (rx) : ORIGIN = 0x00000000, LENGTH = BOOTLOADER_SIZE

Following the bootloader is the flash memory used by the application,<br>called "rom" here - even though it's flash, the name is just a name<br>and doesn't carry special meaning.

The total length of the rom block is the MCU's flash size minus the<br>bootloader's size...

memory https linker script flash stack

Related Articles