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
24MEMORY
25{
26    INCLUDE "pico_flash_region.ld"
27    RAM(rwx) : ORIGIN =  0x20000000, LENGTH = 256k
28    SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
29    SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
30}
31
32ENTRY(_entry_point)
33
34SECTIONS
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
287