Created
June 23, 2020 14:03
-
-
Save MathiasKoch/74345d0f938c1410c41bbd77545731a1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* # Developer notes | |
- Symbols that start with a double underscore (__) are considered "private" | |
- Symbols that start with a single underscore (_) are considered "semi-public"; they can be | |
overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" { | |
static mut __sbss }`). | |
- `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a | |
symbol if not dropped if it appears in or near the front of the linker arguments and "it's not | |
needed" by any of the preceding objects (linker arguments) | |
- `PROVIDE` is used to provide default values that can be overridden by a user linker script | |
- On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and* | |
the LMA of .data are all 4-byte aligned. These alignments are assumed by the RAM initialization | |
routine. There's also a second benefit: 4-byte aligned boundaries means that you won't see | |
"Address (..) is out of bounds" in the disassembly produced by `objdump`. | |
*/ | |
/* Provides information about the memory layout of the device */ | |
/* This will be provided by the user (see `memory.x`) or by a Board Support Crate */ | |
INCLUDE memory.x | |
/* # Entry point = reset vector */ | |
ENTRY(Reset); | |
EXTERN(__RESET_VECTOR); /* depends on the `Reset` symbol */ | |
/* # Exception vectors */ | |
/* This is effectively weak aliasing at the linker level */ | |
/* The user can override any of these aliases by defining the corresponding symbol themselves (cf. | |
the `exception!` macro) */ | |
EXTERN(__EXCEPTIONS); /* depends on all the these PROVIDED symbols */ | |
EXTERN(DefaultHandler); | |
PROVIDE(NonMaskableInt = DefaultHandler); | |
EXTERN(HardFaultTrampoline); | |
PROVIDE(MemoryManagement = DefaultHandler); | |
PROVIDE(BusFault = DefaultHandler); | |
PROVIDE(UsageFault = DefaultHandler); | |
PROVIDE(SecureFault = DefaultHandler); | |
PROVIDE(SVCall = DefaultHandler); | |
PROVIDE(DebugMonitor = DefaultHandler); | |
PROVIDE(PendSV = DefaultHandler); | |
PROVIDE(SysTick = DefaultHandler); | |
PROVIDE(DefaultHandler = DefaultHandler_); | |
PROVIDE(HardFault = HardFault_); | |
/* # Interrupt vectors */ | |
EXTERN(__INTERRUPTS); /* `static` variable similar to `__EXCEPTIONS` */ | |
/* # Pre-initialization function */ | |
/* If the user overrides this using the `pre_init!` macro or by creating a `__pre_init` function, | |
then the function this points to will be called before the RAM is initialized. */ | |
PROVIDE(__pre_init = DefaultPreInit); | |
/* # Sections */ | |
SECTIONS | |
{ | |
PROVIDE(_stack_start = ORIGIN(RAM) + LENGTH(RAM)); | |
/* ## Sections in FLASH */ | |
/* ### Vector table */ | |
.vector_table ORIGIN(FLASH) : | |
{ | |
/* Initial Stack Pointer (SP) value */ | |
LONG(_stack_start); | |
/* Reset vector */ | |
KEEP(*(.vector_table.reset_vector)); /* this is the `__RESET_VECTOR` symbol */ | |
__reset_vector = .; | |
/* Exceptions */ | |
KEEP(*(.vector_table.exceptions)); /* this is the `__EXCEPTIONS` symbol */ | |
__eexceptions = .; | |
/* Device specific interrupts */ | |
KEEP(*(.vector_table.interrupts)); /* this is the `__INTERRUPTS` symbol */ | |
} > FLASH | |
PROVIDE(_stext = ADDR(.vector_table) + SIZEOF(.vector_table)); | |
/* ### .text */ | |
.text _stext : | |
{ | |
*(.text .text.*); | |
*(.HardFaultTrampoline); | |
*(.HardFault.*); | |
. = ALIGN(4); | |
__etext = .; | |
} > FLASH | |
/* ### .rodata */ | |
.rodata __etext : ALIGN(4) | |
{ | |
*(.rodata .rodata.*); | |
/* 4-byte align the end (VMA) of this section. | |
This is required by LLD to ensure the LMA of the following .data | |
section will have the correct alignment. */ | |
. = ALIGN(4); | |
__erodata = .; | |
} > FLASH | |
/* ## Sections in RAM */ | |
/* ### .data */ | |
.data : AT(__erodata) ALIGN(4) | |
{ | |
. = ALIGN(4); | |
__sdata = .; | |
*(.data .data.*); | |
. = ALIGN(4); /* 4-byte align the end (VMA) of this section */ | |
__edata = .; | |
} > RAM | |
/* LMA of .data */ | |
__sidata = LOADADDR(.data); | |
/* ### .bss */ | |
.bss : ALIGN(4) | |
{ | |
. = ALIGN(4); | |
__sbss = .; | |
*(.bss .bss.*); | |
. = ALIGN(4); /* 4-byte align the end (VMA) of this section */ | |
__ebss = .; | |
} > RAM | |
/* ### .uninit */ | |
.uninit (NOLOAD) : ALIGN(4) | |
{ | |
. = ALIGN(4); | |
*(.uninit .uninit.*); | |
. = ALIGN(4); | |
} > RAM | |
/* Place the heap right after `.uninit` */ | |
. = ALIGN(4); | |
__sheap = .; | |
/* ## .got */ | |
/* Dynamic relocations are unsupported. This section is only used to detect relocatable code in | |
the input files and raise an error if relocatable code is found */ | |
.got (NOLOAD) : | |
{ | |
KEEP(*(.got .got.*)); | |
} | |
/* ## Discarded sections */ | |
/DISCARD/ : | |
{ | |
/* Unused exception related info that only wastes space */ | |
*(.ARM.exidx); | |
*(.ARM.exidx.*); | |
*(.ARM.extab.*); | |
} | |
} | |
/* Do not exceed this mark in the error messages below | */ | |
/* # Alignment checks */ | |
ASSERT(ORIGIN(FLASH) % 4 == 0, " | |
ERROR(cortex-m-rt): the start of the FLASH region must be 4-byte aligned"); | |
ASSERT(ORIGIN(RAM) % 4 == 0, " | |
ERROR(cortex-m-rt): the start of the RAM region must be 4-byte aligned"); | |
ASSERT(__sdata % 4 == 0 && __edata % 4 == 0, " | |
BUG(cortex-m-rt): .data is not 4-byte aligned"); | |
ASSERT(__sidata % 4 == 0, " | |
BUG(cortex-m-rt): the LMA of .data is not 4-byte aligned"); | |
ASSERT(__sbss % 4 == 0 && __ebss % 4 == 0, " | |
BUG(cortex-m-rt): .bss is not 4-byte aligned"); | |
ASSERT(__sheap % 4 == 0, " | |
BUG(cortex-m-rt): start of .heap is not 4-byte aligned"); | |
/* # Position checks */ | |
/* ## .vector_table */ | |
ASSERT(__reset_vector == ADDR(.vector_table) + 0x8, " | |
BUG(cortex-m-rt): the reset vector is missing"); | |
ASSERT(__eexceptions == ADDR(.vector_table) + 0x40, " | |
BUG(cortex-m-rt): the exception vectors are missing"); | |
ASSERT(SIZEOF(.vector_table) > 0x40, " | |
ERROR(cortex-m-rt): The interrupt vectors are missing. | |
Possible solutions, from most likely to less likely: | |
- Link to a svd2rust generated device crate | |
- Disable the 'device' feature of cortex-m-rt to build a generic application (a dependency | |
may be enabling it) | |
- Supply the interrupt handlers yourself. Check the documentation for details."); | |
/* ## .text */ | |
ASSERT(ADDR(.vector_table) + SIZEOF(.vector_table) <= _stext, " | |
ERROR(cortex-m-rt): The .text section can't be placed inside the .vector_table section | |
Set _stext to an address greater than the end of .vector_table (See output of `nm`)"); | |
ASSERT(_stext + SIZEOF(.text) < ORIGIN(FLASH) + LENGTH(FLASH), " | |
ERROR(cortex-m-rt): The .text section must be placed inside the FLASH memory. | |
Set _stext to an address smaller than 'ORIGIN(FLASH) + LENGTH(FLASH)'"); | |
/* # Other checks */ | |
ASSERT(SIZEOF(.got) == 0, " | |
ERROR(cortex-m-rt): .got section detected in the input object files | |
Dynamic relocations are not supported. If you are linking to C code compiled using | |
the 'cc' crate then modify your build script to compile the C code _without_ | |
the -fPIC flag. See the documentation of the `cc::Build.pic` method for details."); | |
/* Do not exceed this mark in the error messages above | */ | |
/* Provides weak aliases (cf. PROVIDED) for device specific interrupt handlers */ | |
/* This will usually be provided by a device crate generated using svd2rust (see `device.x`) */ | |
INCLUDE device.x | |
ASSERT(SIZEOF(.vector_table) <= 0x400, " | |
There can't be more than 240 interrupt handlers. This may be a bug in | |
your device crate, or you may have registered more than 240 interrupt | |
handlers."); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment