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    FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 2048k
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    .flashtext : {
62        __logical_binary_start = .;
63        KEEP (*(.vectors))
64        KEEP (*(.binary_info_header))
65        __binary_info_header_end = .;
66        KEEP (*(.reset))
67    }
68
69    .rodata : {
70        /* segments not marked as .flashdata are instead pulled into .data (in RAM) to avoid accidental flash accesses */
71        *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
72        . = ALIGN(4);
73    } > FLASH
74
75    .ARM.extab :
76    {
77        *(.ARM.extab* .gnu.linkonce.armextab.*)
78    } > FLASH
79
80    __exidx_start = .;
81    .ARM.exidx :
82    {
83        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
84    } > FLASH
85    __exidx_end = .;
86
87    /* Machine inspectable binary information */
88    . = ALIGN(4);
89    __binary_info_start = .;
90    .binary_info :
91    {
92        KEEP(*(.binary_info.keep.*))
93        *(.binary_info.*)
94    } > FLASH
95    __binary_info_end = .;
96    . = ALIGN(4);
97
98    /* Vector table goes first in RAM, to avoid large alignment hole */
99   .ram_vector_table (NOLOAD): {
100        *(.ram_vector_table)
101    } > RAM
102
103    .text : {
104        __ram_text_start__ = .;
105        *(.init)
106        *(.text*)
107        *(.fini)
108        /* Pull all c'tors into .text */
109        *crtbegin.o(.ctors)
110        *crtbegin?.o(.ctors)
111        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
112        *(SORT(.ctors.*))
113        *(.ctors)
114        /* Followed by destructors */
115        *crtbegin.o(.dtors)
116        *crtbegin?.o(.dtors)
117        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
118        *(SORT(.dtors.*))
119        *(.dtors)
120
121        *(.eh_frame*)
122        . = ALIGN(4);
123        __ram_text_end__ = .;
124    } > RAM AT> FLASH
125    __ram_text_source__ = LOADADDR(.text);
126    . = ALIGN(4);
127
128    .data : {
129        __data_start__ = .;
130        *(vtable)
131
132        *(.time_critical*)
133
134        . = ALIGN(4);
135        *(.rodata*)
136        . = ALIGN(4);
137
138        *(.data*)
139
140        . = ALIGN(4);
141        *(.after_data.*)
142        . = ALIGN(4);
143        /* preinit data */
144        PROVIDE_HIDDEN (__mutex_array_start = .);
145        KEEP(*(SORT(.mutex_array.*)))
146        KEEP(*(.mutex_array))
147        PROVIDE_HIDDEN (__mutex_array_end = .);
148
149        . = ALIGN(4);
150        /* preinit data */
151        PROVIDE_HIDDEN (__preinit_array_start = .);
152        KEEP(*(SORT(.preinit_array.*)))
153        KEEP(*(.preinit_array))
154        PROVIDE_HIDDEN (__preinit_array_end = .);
155
156        . = ALIGN(4);
157        /* init data */
158        PROVIDE_HIDDEN (__init_array_start = .);
159        KEEP(*(SORT(.init_array.*)))
160        KEEP(*(.init_array))
161        PROVIDE_HIDDEN (__init_array_end = .);
162
163        . = ALIGN(4);
164        /* finit data */
165        PROVIDE_HIDDEN (__fini_array_start = .);
166        *(SORT(.fini_array.*))
167        *(.fini_array)
168        PROVIDE_HIDDEN (__fini_array_end = .);
169
170        *(.jcr)
171        . = ALIGN(4);
172        /* All data end */
173        __data_end__ = .;
174    } > RAM AT> FLASH
175    /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
176    __etext = LOADADDR(.data);
177
178    .uninitialized_data (NOLOAD): {
179        . = ALIGN(4);
180        *(.uninitialized_data*)
181    } > RAM
182
183    /* Start and end symbols must be word-aligned */
184    .scratch_x : {
185        __scratch_x_start__ = .;
186        *(.scratch_x.*)
187        . = ALIGN(4);
188        __scratch_x_end__ = .;
189    } > SCRATCH_X AT > FLASH
190    __scratch_x_source__ = LOADADDR(.scratch_x);
191
192    .scratch_y : {
193        __scratch_y_start__ = .;
194        *(.scratch_y.*)
195        . = ALIGN(4);
196        __scratch_y_end__ = .;
197    } > SCRATCH_Y AT > FLASH
198    __scratch_y_source__ = LOADADDR(.scratch_y);
199
200    .bss  : {
201        . = ALIGN(4);
202        __bss_start__ = .;
203        *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
204        *(COMMON)
205        . = ALIGN(4);
206        __bss_end__ = .;
207    } > RAM
208
209    .heap (NOLOAD):
210    {
211        __end__ = .;
212        end = __end__;
213        KEEP(*(.heap*))
214        __HeapLimit = .;
215    } > RAM
216
217    /* .stack*_dummy section doesn't contains any symbols. It is only
218     * used for linker to calculate size of stack sections, and assign
219     * values to stack symbols later
220     *
221     * stack1 section may be empty/missing if platform_launch_core1 is not used */
222
223    /* by default we put core 0 stack at the end of scratch Y, so that if core 1
224     * stack is not used then all of SCRATCH_X is free.
225     */
226    .stack1_dummy (NOLOAD):
227    {
228        *(.stack1*)
229    } > SCRATCH_X
230    .stack_dummy (NOLOAD):
231    {
232        KEEP(*(.stack*))
233    } > SCRATCH_Y
234
235    .flash_end : {
236        __flash_binary_end = .;
237    } > FLASH
238
239    /* stack limit is poorly named, but historically is maximum heap ptr */
240    __StackLimit = ORIGIN(RAM) + LENGTH(RAM);
241    __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
242    __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
243    __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
244    __StackBottom = __StackTop - SIZEOF(.stack_dummy);
245    PROVIDE(__stack = __StackTop);
246
247    /* Check if data + heap + stack exceeds RAM limit */
248    ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
249
250    ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary")
251    /* todo assert on extra code */
252}
253
254