Skip to content

Commit 4430502

Browse files
committed
Create new linker scripts rather than modifying existing
New template flash and sram linker scripts, to avoid need for parsing the file Adds a test to kitchen_sink that these new linker scripts produce the same defaults, to ensure modifications to linker scripts are propogated
1 parent b2dba0e commit 4430502

File tree

8 files changed

+1208
-11
lines changed

8 files changed

+1208
-11
lines changed
Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
/* Based on GCC ARM embedded samples.
2+
Defines the following symbols for use by code:
3+
__exidx_start
4+
__exidx_end
5+
__etext
6+
__data_start__
7+
__preinit_array_start
8+
__preinit_array_end
9+
__init_array_start
10+
__init_array_end
11+
__fini_array_start
12+
__fini_array_end
13+
__data_end__
14+
__bss_start__
15+
__bss_end__
16+
__end__
17+
end
18+
__HeapLimit
19+
__StackLimit
20+
__StackTop
21+
__stack (== StackTop)
22+
*/
23+
24+
MEMORY
25+
{
26+
INCLUDE "pico_flash_region.ld"
27+
RAM(rwx) : ORIGIN = @RAM_ORIGIN@, LENGTH = @RAM_LENGTH@
28+
SCRATCH_X(rwx) : ORIGIN = @SCRATCH_X_ORIGIN@, LENGTH = @SCRATCH_X_LENGTH@
29+
SCRATCH_Y(rwx) : ORIGIN = @SCRATCH_Y_ORIGIN@, LENGTH = @SCRATCH_Y_LENGTH@
30+
}
31+
32+
ENTRY(_entry_point)
33+
34+
SECTIONS
35+
{
36+
/* Second stage bootloader is prepended to the image. It must be 256 bytes big
37+
and checksummed. It is usually built by the boot_stage2 target
38+
in the Raspberry Pi Pico SDK
39+
*/
40+
41+
.flash_begin : {
42+
__flash_binary_start = .;
43+
} > FLASH
44+
45+
.boot2 : {
46+
__boot2_start__ = .;
47+
KEEP (*(.boot2))
48+
__boot2_end__ = .;
49+
} > FLASH
50+
51+
ASSERT(__boot2_end__ - __boot2_start__ == 256,
52+
"ERROR: Pico second stage bootloader must be 256 bytes in size")
53+
54+
/* The second stage will always enter the image at the start of .text.
55+
The debugger will use the ELF entry point, which is the _entry_point
56+
symbol if present, otherwise defaults to start of .text.
57+
This can be used to transfer control back to the bootrom on debugger
58+
launches only, to perform proper flash setup.
59+
*/
60+
61+
.text : {
62+
__logical_binary_start = .;
63+
KEEP (*(.vectors))
64+
KEEP (*(.binary_info_header))
65+
__binary_info_header_end = .;
66+
KEEP (*(.embedded_block))
67+
__embedded_block_end = .;
68+
KEEP (*(.reset))
69+
/* TODO revisit this now memset/memcpy/float in ROM */
70+
/* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from
71+
* FLASH ... we will include any thing excluded here in .data below by default */
72+
*(.init)
73+
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*)
74+
*(.fini)
75+
/* Pull all c'tors into .text */
76+
*crtbegin.o(.ctors)
77+
*crtbegin?.o(.ctors)
78+
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
79+
*(SORT(.ctors.*))
80+
*(.ctors)
81+
/* Followed by destructors */
82+
*crtbegin.o(.dtors)
83+
*crtbegin?.o(.dtors)
84+
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
85+
*(SORT(.dtors.*))
86+
*(.dtors)
87+
88+
. = ALIGN(4);
89+
/* preinit data */
90+
PROVIDE_HIDDEN (__preinit_array_start = .);
91+
KEEP(*(SORT(.preinit_array.*)))
92+
KEEP(*(.preinit_array))
93+
PROVIDE_HIDDEN (__preinit_array_end = .);
94+
95+
. = ALIGN(4);
96+
/* init data */
97+
PROVIDE_HIDDEN (__init_array_start = .);
98+
KEEP(*(SORT(.init_array.*)))
99+
KEEP(*(.init_array))
100+
PROVIDE_HIDDEN (__init_array_end = .);
101+
102+
. = ALIGN(4);
103+
/* finit data */
104+
PROVIDE_HIDDEN (__fini_array_start = .);
105+
*(SORT(.fini_array.*))
106+
*(.fini_array)
107+
PROVIDE_HIDDEN (__fini_array_end = .);
108+
109+
*(.eh_frame*)
110+
. = ALIGN(4);
111+
} > FLASH
112+
113+
.rodata : {
114+
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*)
115+
. = ALIGN(4);
116+
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
117+
. = ALIGN(4);
118+
} > FLASH
119+
120+
.ARM.extab :
121+
{
122+
*(.ARM.extab* .gnu.linkonce.armextab.*)
123+
} > FLASH
124+
125+
__exidx_start = .;
126+
.ARM.exidx :
127+
{
128+
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
129+
} > FLASH
130+
__exidx_end = .;
131+
132+
/* Machine inspectable binary information */
133+
. = ALIGN(4);
134+
__binary_info_start = .;
135+
.binary_info :
136+
{
137+
KEEP(*(.binary_info.keep.*))
138+
*(.binary_info.*)
139+
} > FLASH
140+
__binary_info_end = .;
141+
. = ALIGN(4);
142+
143+
.ram_vector_table (NOLOAD): {
144+
*(.ram_vector_table)
145+
} > RAM
146+
147+
.uninitialized_data (NOLOAD): {
148+
. = ALIGN(4);
149+
*(.uninitialized_data*)
150+
} > RAM
151+
152+
.data : {
153+
__data_start__ = .;
154+
*(vtable)
155+
156+
*(.time_critical*)
157+
158+
/* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */
159+
*(.text*)
160+
. = ALIGN(4);
161+
*(.rodata*)
162+
. = ALIGN(4);
163+
164+
*(.data*)
165+
166+
. = ALIGN(4);
167+
*(.after_data.*)
168+
. = ALIGN(4);
169+
/* preinit data */
170+
PROVIDE_HIDDEN (__mutex_array_start = .);
171+
KEEP(*(SORT(.mutex_array.*)))
172+
KEEP(*(.mutex_array))
173+
PROVIDE_HIDDEN (__mutex_array_end = .);
174+
175+
. = ALIGN(4);
176+
*(.jcr)
177+
. = ALIGN(4);
178+
} > RAM AT> FLASH
179+
180+
.tdata : {
181+
. = ALIGN(4);
182+
*(.tdata .tdata.* .gnu.linkonce.td.*)
183+
/* All data end */
184+
__tdata_end = .;
185+
} > RAM AT> FLASH
186+
PROVIDE(__data_end__ = .);
187+
188+
/* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
189+
__etext = LOADADDR(.data);
190+
191+
.tbss (NOLOAD) : {
192+
. = ALIGN(4);
193+
__bss_start__ = .;
194+
__tls_base = .;
195+
*(.tbss .tbss.* .gnu.linkonce.tb.*)
196+
*(.tcommon)
197+
198+
__tls_end = .;
199+
} > RAM
200+
201+
.bss (NOLOAD) : {
202+
. = ALIGN(4);
203+
__tbss_end = .;
204+
205+
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
206+
*(COMMON)
207+
. = ALIGN(4);
208+
__bss_end__ = .;
209+
} > RAM
210+
211+
.heap (NOLOAD):
212+
{
213+
__end__ = .;
214+
end = __end__;
215+
KEEP(*(.heap*))
216+
} > RAM
217+
/* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however
218+
to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */
219+
__HeapLimit = ORIGIN(RAM) + LENGTH(RAM);
220+
221+
/* Start and end symbols must be word-aligned */
222+
.scratch_x : {
223+
__scratch_x_start__ = .;
224+
*(.scratch_x.*)
225+
. = ALIGN(4);
226+
__scratch_x_end__ = .;
227+
} > SCRATCH_X AT > FLASH
228+
__scratch_x_source__ = LOADADDR(.scratch_x);
229+
230+
.scratch_y : {
231+
__scratch_y_start__ = .;
232+
*(.scratch_y.*)
233+
. = ALIGN(4);
234+
__scratch_y_end__ = .;
235+
} > SCRATCH_Y AT > FLASH
236+
__scratch_y_source__ = LOADADDR(.scratch_y);
237+
238+
/* .stack*_dummy section doesn't contains any symbols. It is only
239+
* used for linker to calculate size of stack sections, and assign
240+
* values to stack symbols later
241+
*
242+
* stack1 section may be empty/missing if platform_launch_core1 is not used */
243+
244+
/* by default we put core 0 stack at the end of scratch Y, so that if core 1
245+
* stack is not used then all of SCRATCH_X is free.
246+
*/
247+
.stack1_dummy (NOLOAD):
248+
{
249+
*(.stack1*)
250+
} > SCRATCH_X
251+
.stack_dummy (NOLOAD):
252+
{
253+
KEEP(*(.stack*))
254+
} > SCRATCH_Y
255+
256+
.flash_end : {
257+
KEEP(*(.embedded_end_block*))
258+
PROVIDE(__flash_binary_end = .);
259+
} > FLASH
260+
261+
/* stack limit is poorly named, but historically is maximum heap ptr */
262+
__StackLimit = ORIGIN(RAM) + LENGTH(RAM);
263+
__StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
264+
__StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
265+
__StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
266+
__StackBottom = __StackTop - SIZEOF(.stack_dummy);
267+
PROVIDE(__stack = __StackTop);
268+
269+
/* picolibc and LLVM */
270+
PROVIDE (__heap_start = __end__);
271+
PROVIDE (__heap_end = __HeapLimit);
272+
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
273+
PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1));
274+
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
275+
276+
/* llvm-libc */
277+
PROVIDE (_end = __end__);
278+
PROVIDE (__llvm_libc_heap_limit = __HeapLimit);
279+
280+
/* Check if data + heap + stack exceeds RAM limit */
281+
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
282+
283+
ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary")
284+
/* todo assert on extra code */
285+
}
286+

0 commit comments

Comments
 (0)