mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-23 09:41:36 +00:00
204 lines
6.5 KiB
Markdown
204 lines
6.5 KiB
Markdown
---
|
||
category: tool
|
||
tool: GNU linker (ld)
|
||
contributors:
|
||
- ["Alexander Kovalchuk", "https://github.com/Zamuhrishka"]
|
||
translators:
|
||
- ["Anuj Shah", "https://github.com/ShahAnuj2610"]
|
||
---
|
||
|
||
## Basic concepts and definitions
|
||
|
||
**Position counter** - the linker has a special variable
|
||
"." (dot) always contains the current output position.
|
||
|
||
## Functions
|
||
|
||
**ADDR (section)** - returns the absolute address of the specified section. However
|
||
this section must be defined before using the ADDR function.
|
||
|
||
**ALIGN (exp)** - returns the value of the position counter aligned to the border
|
||
following the exp expression.
|
||
|
||
**SIZEOF (section)** - returns the size of the section in bytes.
|
||
|
||
**FILL (param)** - defines the fill pattern for the current section. All
|
||
other unspecified regions within the section are filled with the value indicated
|
||
in function argument.
|
||
|
||
**KEEP (param)** - used to mark param as fatal.
|
||
|
||
**ENTRY (func)** - defines the function that will be the entry point
|
||
into the program.
|
||
|
||
```bash
|
||
# Determine the entry point to the program
|
||
ENTRY(Reset_Handler)
|
||
|
||
# Define a variable that contains the address of the top of the stack
|
||
_estack = 0x20020000;
|
||
# Define a variable that contains a heap size value
|
||
_Min_Heap_Size = 0x200;
|
||
# Define a variable that contains the value of the stack size
|
||
_Min_Stack_Size = 0x400;
|
||
|
||
# Description of the memory card available for this processor
|
||
# MEMORY
|
||
# {
|
||
#MEMORY_DOMAIN_NAME (access rights): ORIGIN = START_ADDRESS, LENGTH = SIZE
|
||
# }
|
||
# In our example, the controller contains three memory areas:
|
||
# RAM - starts with the address 0x20000000 and takes 128 KB;
|
||
# CCMRAM - starts with the address 0x10000000 and occupies 64 KB;
|
||
# FLASH - starts with the address 0x8000000; takes 1024 Kb;
|
||
# Moreover, RAM memory access for reading, writing and execution.
|
||
# CCMRAM memory is read-write only.
|
||
# FLASH memory is available for reading and execution.
|
||
MEMORY
|
||
{
|
||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
|
||
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
|
||
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
|
||
}
|
||
|
||
# We describe output sections
|
||
SECTIONS
|
||
{
|
||
# The first section contains a table of interrupt vectors
|
||
.isr_vector :
|
||
{
|
||
# Align the current position to the border of 4 bytes.
|
||
. = ALIGN(4);
|
||
|
||
# There is an option --gc-sections, which allows you to collect garbage from unused
|
||
# input sections. And if there are sections that the garbage collector should not touch,
|
||
# you need to specify them as an argument to the KEEP () function (analogue of the keyword
|
||
# volatile).
|
||
# The entry (* (. Isr_vector)) means the .isr_vector sections in all object files. Because
|
||
# appeal to the section in general terms looks like this: (FILE_NAME (SECTION_NAME))
|
||
KEEP(*(.isr_vector))
|
||
|
||
# Align the current position to the border of 4 bytes.
|
||
. = ALIGN(4);
|
||
|
||
# The expression "> MEMORY AREA" indicates which area of memory will be placed
|
||
# this section. In our section, the .isr_vector section will be located in FLASH memory.
|
||
} >FLASH
|
||
|
||
# TOTAL: The .isr_vector section that contains the table of interrupt vectors is aligned
|
||
# on the border of 4 bytes, marked as inaccessible to the garbage collector and placed at the beginning
|
||
# FLASH microcontroller memory.
|
||
|
||
# The second section contains the program code.
|
||
.text :
|
||
{
|
||
# Align the current position to the border of 4 bytes.
|
||
. = ALIGN(4);
|
||
|
||
# We indicate that in this section the .text areas of all
|
||
# object files
|
||
*(.text)
|
||
*(.text*)
|
||
|
||
# Protect the .init and .fini sections from the garbage collector
|
||
KEEP (*(.init))
|
||
KEEP (*(.fini))
|
||
|
||
# Align the current position to the border of 4 bytes.
|
||
. = ALIGN(4);
|
||
|
||
# The variable _etext is defined, which stores the address of the end of the .text section and which
|
||
# may be available in the source code of the program through the announcement
|
||
# volaile unsigned int extern _etext;
|
||
_etext = .;
|
||
} >FLASH
|
||
|
||
# TOTAL: The .text section that contains the program code is aligned on the border of 4 bytes,
|
||
# includes: all sections with program code in all object files and protected
|
||
# from the garbage collector of the .init and .fini sections in all object files, located in FLASH
|
||
# microcontroller memory immediately after the table of vectors.
|
||
# The text, .init, and .fini sections. are located in memory in the order in which they
|
||
# declared in the script.
|
||
|
||
# The third section contains constant data.
|
||
.rodata :
|
||
{
|
||
# Align the current position to the border of 4 bytes.
|
||
. = ALIGN(4);
|
||
|
||
# We indicate that in this section areas .rodata will be stored
|
||
# object files
|
||
*(.rodata)
|
||
*(.rodata*)
|
||
|
||
# Align the current position to the border of 4 bytes.
|
||
. = ALIGN(4);
|
||
} >FLASH
|
||
|
||
# Save the absolute address of the .data section in the _sidata variable
|
||
_sidata = LOADADDR(.data);
|
||
|
||
# The fourth section contains initialized variables.
|
||
.data :
|
||
{
|
||
# Align the current position to the border of 4 bytes.
|
||
. = ALIGN(4);
|
||
|
||
# Save the address of the current position (beginning of the section) in the variable _sdata
|
||
_sdata = .;
|
||
|
||
# We indicate that in this section the .data areas of all
|
||
# object files
|
||
*(.data)
|
||
*(.data*)
|
||
|
||
# Align the current position to the border of 4 bytes.
|
||
. = ALIGN(4);
|
||
|
||
# Save the address of the current position (end of section) in the variable _sdata
|
||
_edata = .;
|
||
|
||
# AT function indicates that this sector is stored in one memory area
|
||
# (in our case, FLASH), and it will be executed from another area of memory (in our case, RAM).
|
||
# There are two types of addresses:
|
||
# * VMA (Virtual memory address) - this is the run-time address at which the compiler expects
|
||
# see data.
|
||
# * LMA (Load memory address) is the address at which the linker stores data.
|
||
|
||
#Startup must code to copy the .data section from the LMA addresses to the VMA addresses.
|
||
|
||
} >RAM AT> FLASH
|
||
|
||
# The fifth section contains zero-initialized variables.
|
||
.bss :
|
||
{
|
||
# Save the address of the current position (beginning of the section) in the variable _sbss and __bss_start__
|
||
_sbss = .;
|
||
__bss_start__ = _sbss;
|
||
|
||
# We indicate that in this section the .bss areas of all
|
||
# object files
|
||
*(.bss)
|
||
*(.bss*)
|
||
|
||
# Align the current position to the border of 4 bytes.
|
||
. = ALIGN(4);
|
||
|
||
# Save the address of the current position (beginning of the section) in the variable _ebss and __bss_end__
|
||
_ebss = .;
|
||
__bss_end__ = _ebss;
|
||
} >RAM
|
||
|
||
# The sixth section contains a bunch and a stack. It is located at the very end of RAM.
|
||
._user_heap_stack :
|
||
{
|
||
. = ALIGN(4);
|
||
PROVIDE ( end = . );
|
||
PROVIDE ( _end = . );
|
||
. = . + _Min_Heap_Size;
|
||
. = . + _Min_Stack_Size;
|
||
. = ALIGN(4);
|
||
} >RAM
|
||
}
|
||
```
|