aboutsummaryrefslogtreecommitdiff
path: root/tests/link_ram_cortex_m.x
diff options
context:
space:
mode:
authorPriit Laes <[email protected]>2024-01-05 14:58:57 +0200
committerPriit Laes <[email protected]>2024-01-05 15:01:05 +0200
commit890ceae4e5b353ac85d7030ea7b344c18a1d663e (patch)
tree15893e72e92935948a0c8cc7bef139a0d134d492 /tests/link_ram_cortex_m.x
parent17346fdfc22a34d651d9d30bcc35125916ee44b5 (diff)
tests: Use unified link_ram_cortex_m.x file for all Cortex M targets
Diffstat (limited to 'tests/link_ram_cortex_m.x')
-rw-r--r--tests/link_ram_cortex_m.x276
1 files changed, 276 insertions, 0 deletions
diff --git a/tests/link_ram_cortex_m.x b/tests/link_ram_cortex_m.x
new file mode 100644
index 000000000..5cb23a642
--- /dev/null
+++ b/tests/link_ram_cortex_m.x
@@ -0,0 +1,276 @@
1/* ##### EMBASSY NOTE
2 Originally from https://github.com/rust-embedded/cortex-m/blob/master/cortex-m-rt/link.x.in
3 Adjusted to put everything in RAM
4*/
5
6/* # Developer notes
7
8- Symbols that start with a double underscore (__) are considered "private"
9
10- Symbols that start with a single underscore (_) are considered "semi-public"; they can be
11 overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" {
12 static mut __sbss }`).
13
14- `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a
15 symbol if not dropped if it appears in or near the front of the linker arguments and "it's not
16 needed" by any of the preceding objects (linker arguments)
17
18- `PROVIDE` is used to provide default values that can be overridden by a user linker script
19
20- On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and*
21 the LMA of .data are all 4-byte aligned. These alignments are assumed by the RAM initialization
22 routine. There's also a second benefit: 4-byte aligned boundaries means that you won't see
23 "Address (..) is out of bounds" in the disassembly produced by `objdump`.
24*/
25
26/* Provides information about the memory layout of the device */
27/* This will be provided by the user (see `memory.x`) or by a Board Support Crate */
28INCLUDE memory.x
29
30/* # Entry point = reset vector */
31EXTERN(__RESET_VECTOR);
32EXTERN(Reset);
33ENTRY(Reset);
34
35/* # Exception vectors */
36/* This is effectively weak aliasing at the linker level */
37/* The user can override any of these aliases by defining the corresponding symbol themselves (cf.
38 the `exception!` macro) */
39EXTERN(__EXCEPTIONS); /* depends on all the these PROVIDED symbols */
40
41EXTERN(DefaultHandler);
42
43PROVIDE(NonMaskableInt = DefaultHandler);
44EXTERN(HardFaultTrampoline);
45PROVIDE(MemoryManagement = DefaultHandler);
46PROVIDE(BusFault = DefaultHandler);
47PROVIDE(UsageFault = DefaultHandler);
48PROVIDE(SecureFault = DefaultHandler);
49PROVIDE(SVCall = DefaultHandler);
50PROVIDE(DebugMonitor = DefaultHandler);
51PROVIDE(PendSV = DefaultHandler);
52PROVIDE(SysTick = DefaultHandler);
53
54PROVIDE(DefaultHandler = DefaultHandler_);
55PROVIDE(HardFault = HardFault_);
56
57/* # Interrupt vectors */
58EXTERN(__INTERRUPTS); /* `static` variable similar to `__EXCEPTIONS` */
59
60/* # Pre-initialization function */
61/* If the user overrides this using the `pre_init!` macro or by creating a `__pre_init` function,
62 then the function this points to will be called before the RAM is initialized. */
63PROVIDE(__pre_init = DefaultPreInit);
64
65/* # Sections */
66SECTIONS
67{
68 PROVIDE(_ram_start = ORIGIN(RAM));
69 PROVIDE(_ram_end = ORIGIN(RAM) + LENGTH(RAM));
70 PROVIDE(_stack_start = _ram_end);
71
72 /* ## Sections in RAM */
73 /* ### Vector table */
74 .vector_table ORIGIN(RAM) :
75 {
76 __vector_table = .;
77
78 /* Initial Stack Pointer (SP) value.
79 * We mask the bottom three bits to force 8-byte alignment.
80 * Despite having an assert for this later, it's possible that a separate
81 * linker script could override _stack_start after the assert is checked.
82 */
83 LONG(_stack_start & 0xFFFFFFF8);
84
85 /* Reset vector */
86 KEEP(*(.vector_table.reset_vector)); /* this is the `__RESET_VECTOR` symbol */
87
88 /* Exceptions */
89 __exceptions = .; /* start of exceptions */
90 KEEP(*(.vector_table.exceptions)); /* this is the `__EXCEPTIONS` symbol */
91 __eexceptions = .; /* end of exceptions */
92
93 /* Device specific interrupts */
94 KEEP(*(.vector_table.interrupts)); /* this is the `__INTERRUPTS` symbol */
95 } > RAM
96
97 PROVIDE(_stext = ADDR(.vector_table) + SIZEOF(.vector_table));
98
99 /* ### .text */
100 .text _stext :
101 {
102 __stext = .;
103 *(.Reset);
104
105 *(.text .text.*);
106
107 /* The HardFaultTrampoline uses the `b` instruction to enter `HardFault`,
108 so must be placed close to it. */
109 *(.HardFaultTrampoline);
110 *(.HardFault.*);
111
112 . = ALIGN(4); /* Pad .text to the alignment to workaround overlapping load section bug in old lld */
113 __etext = .;
114 } > RAM
115
116 /* ### .rodata */
117 .rodata : ALIGN(4)
118 {
119 . = ALIGN(4);
120 __srodata = .;
121 *(.rodata .rodata.*);
122
123 /* 4-byte align the end (VMA) of this section.
124 This is required by LLD to ensure the LMA of the following .data
125 section will have the correct alignment. */
126 . = ALIGN(4);
127 __erodata = .;
128 } > RAM
129
130 /* ## Sections in RAM */
131 /* ### .data */
132 .data : ALIGN(4)
133 {
134 . = ALIGN(4);
135 __sdata = .;
136 *(.data .data.*);
137 . = ALIGN(4); /* 4-byte align the end (VMA) of this section */
138 } > RAM
139 /* Allow sections from user `memory.x` injected using `INSERT AFTER .data` to
140 * use the .data loading mechanism by pushing __edata. Note: do not change
141 * output region or load region in those user sections! */
142 . = ALIGN(4);
143 __edata = .;
144
145 /* LMA of .data */
146 __sidata = LOADADDR(.data);
147
148 /* ### .gnu.sgstubs
149 This section contains the TrustZone-M veneers put there by the Arm GNU linker. */
150 /* Security Attribution Unit blocks must be 32 bytes aligned. */
151 /* Note that this pads the RAM usage to 32 byte alignment. */
152 .gnu.sgstubs : ALIGN(32)
153 {
154 . = ALIGN(32);
155 __veneer_base = .;
156 *(.gnu.sgstubs*)
157 . = ALIGN(32);
158 } > RAM
159 /* Place `__veneer_limit` outside the `.gnu.sgstubs` section because veneers are
160 * always inserted last in the section, which would otherwise be _after_ the `__veneer_limit` symbol.
161 */
162 . = ALIGN(32);
163 __veneer_limit = .;
164
165 /* ### .bss */
166 .bss (NOLOAD) : ALIGN(4)
167 {
168 . = ALIGN(4);
169 __sbss = .;
170 *(.bss .bss.*);
171 *(COMMON); /* Uninitialized C statics */
172 . = ALIGN(4); /* 4-byte align the end (VMA) of this section */
173 } > RAM
174 /* Allow sections from user `memory.x` injected using `INSERT AFTER .bss` to
175 * use the .bss zeroing mechanism by pushing __ebss. Note: do not change
176 * output region or load region in those user sections! */
177 . = ALIGN(4);
178 __ebss = .;
179
180 /* ### .uninit */
181 .uninit (NOLOAD) : ALIGN(4)
182 {
183 . = ALIGN(4);
184 __suninit = .;
185 *(.uninit .uninit.*);
186 . = ALIGN(4);
187 __euninit = .;
188 } > RAM
189
190 /* Place the heap right after `.uninit` in RAM */
191 PROVIDE(__sheap = __euninit);
192
193 /* ## .got */
194 /* Dynamic relocations are unsupported. This section is only used to detect relocatable code in
195 the input files and raise an error if relocatable code is found */
196 .got (NOLOAD) :
197 {
198 KEEP(*(.got .got.*));
199 }
200
201 /* ## Discarded sections */
202 /DISCARD/ :
203 {
204 /* Unused exception related info that only wastes space */
205 *(.ARM.exidx);
206 *(.ARM.exidx.*);
207 *(.ARM.extab.*);
208 }
209}
210
211/* Do not exceed this mark in the error messages below | */
212/* # Alignment checks */
213ASSERT(ORIGIN(RAM) % 4 == 0, "
214ERROR(cortex-m-rt): the start of the RAM region must be 4-byte aligned");
215
216ASSERT(__sdata % 4 == 0 && __edata % 4 == 0, "
217BUG(cortex-m-rt): .data is not 4-byte aligned");
218
219ASSERT(__sidata % 4 == 0, "
220BUG(cortex-m-rt): the LMA of .data is not 4-byte aligned");
221
222ASSERT(__sbss % 4 == 0 && __ebss % 4 == 0, "
223BUG(cortex-m-rt): .bss is not 4-byte aligned");
224
225ASSERT(__sheap % 4 == 0, "
226BUG(cortex-m-rt): start of .heap is not 4-byte aligned");
227
228ASSERT(_stack_start % 8 == 0, "
229ERROR(cortex-m-rt): stack start address is not 8-byte aligned.
230If you have set _stack_start, check it's set to an address which is a multiple of 8 bytes.
231If you haven't, stack starts at the end of RAM by default. Check that both RAM
232origin and length are set to multiples of 8 in the `memory.x` file.");
233
234/* # Position checks */
235
236/* ## .vector_table
237 *
238 * If the *start* of exception vectors is not 8 bytes past the start of the
239 * vector table, then we somehow did not place the reset vector, which should
240 * live 4 bytes past the start of the vector table.
241 */
242ASSERT(__exceptions == ADDR(.vector_table) + 0x8, "
243BUG(cortex-m-rt): the reset vector is missing");
244
245ASSERT(__eexceptions == ADDR(.vector_table) + 0x40, "
246BUG(cortex-m-rt): the exception vectors are missing");
247
248ASSERT(SIZEOF(.vector_table) > 0x40, "
249ERROR(cortex-m-rt): The interrupt vectors are missing.
250Possible solutions, from most likely to less likely:
251- Link to a svd2rust generated device crate
252- Check that you actually use the device/hal/bsp crate in your code
253- Disable the 'device' feature of cortex-m-rt to build a generic application (a dependency
254may be enabling it)
255- Supply the interrupt handlers yourself. Check the documentation for details.");
256
257/* ## .text */
258ASSERT(ADDR(.vector_table) + SIZEOF(.vector_table) <= _stext, "
259ERROR(cortex-m-rt): The .text section can't be placed inside the .vector_table section
260Set _stext to an address greater than the end of .vector_table (See output of `nm`)");
261
262ASSERT(_stext + SIZEOF(.text) < ORIGIN(RAM) + LENGTH(RAM), "
263ERROR(cortex-m-rt): The .text section must be placed inside the RAM memory.
264Set _stext to an address smaller than 'ORIGIN(RAM) + LENGTH(RAM)'");
265
266/* # Other checks */
267ASSERT(SIZEOF(.got) == 0, "
268ERROR(cortex-m-rt): .got section detected in the input object files
269Dynamic relocations are not supported. If you are linking to C code compiled using
270the 'cc' crate then modify your build script to compile the C code _without_
271the -fPIC flag. See the documentation of the `cc::Build.pic` method for details.");
272/* Do not exceed this mark in the error messages above | */
273
274/* Provides weak aliases (cf. PROVIDED) for device specific interrupt handlers */
275/* This will usually be provided by a device crate generated using svd2rust (see `device.x`) */
276INCLUDE device.x