1/*
2 * Copyright (c) 2023 Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/* ----------------------------------------------------------------------------
20  Stack seal size definition
21 *----------------------------------------------------------------------------*/
22#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
23#define __STACKSEAL_SIZE   ( 8 )
24#else
25#define __STACKSEAL_SIZE   ( 0 )
26#endif
27
28/* ----------------------------------------------------------------------------
29  Memory definition
30 *----------------------------------------------------------------------------*/
31MEMORY
32{
33  ROM0  (rx)  : ORIGIN = __ROM0_BASE, LENGTH = __ROM0_SIZE
34#if __ROM1_SIZE > 0
35  ROM1  (rx)  : ORIGIN = __ROM1_BASE, LENGTH = __ROM1_SIZE
36#endif
37#if __ROM2_SIZE > 0
38  ROM2  (rx)  : ORIGIN = __ROM2_BASE, LENGTH = __ROM2_SIZE
39#endif
40#if __ROM3_SIZE > 0
41  ROM3  (rx)  : ORIGIN = __ROM3_BASE, LENGTH = __ROM3_SIZE
42#endif
43
44  RAM0  (rwx) : ORIGIN = __RAM0_BASE, LENGTH = __RAM0_SIZE
45#if __RAM1_SIZE > 0
46  RAM1  (rwx) : ORIGIN = __RAM1_BASE, LENGTH = __RAM1_SIZE
47#endif
48#if __RAM2_SIZE > 0
49  RAM2  (rwx) : ORIGIN = __RAM2_BASE, LENGTH = __RAM2_SIZE
50#endif
51#if __RAM3_SIZE > 0
52  RAM3  (rwx) : ORIGIN = __RAM3_BASE, LENGTH = __RAM3_SIZE
53#endif
54}
55
56/* Linker script to place sections and symbol values. Should be used together
57 * with other linker script that defines memory regions FLASH and RAM.
58 * It references following symbols, which must be defined in code:
59 *   Reset_Handler : Entry of reset handler
60 *
61 * It defines following symbols, which code can use without definition:
62 *   __exidx_start
63 *   __exidx_end
64 *   __copy_table_start__
65 *   __copy_table_end__
66 *   __zero_table_start__
67 *   __zero_table_end__
68 *   __etext          (deprecated)
69 *   __data_start__
70 *   __preinit_array_start
71 *   __preinit_array_end
72 *   __init_array_start
73 *   __init_array_end
74 *   __fini_array_start
75 *   __fini_array_end
76 *   __data_end__
77 *   __bss_start__
78 *   __bss_end__
79 *   __noinit_start
80 *   __noinit_end
81 *   __end__
82 *   end
83 *   __HeapLimit
84 *   __StackLimit
85 *   __StackTop
86 *   __stack
87 */
88ENTRY(Reset_Handler)
89
90SECTIONS
91{
92  .text :
93  {
94    KEEP(*(.vectors))
95    *(.text*)
96
97    KEEP(*(.init))
98    KEEP(*(.fini))
99
100    /* .ctors */
101    *crtbegin.o(.ctors)
102    *crtbegin?.o(.ctors)
103    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
104    *(SORT(.ctors.*))
105    *(.ctors)
106
107    /* .dtors */
108    *crtbegin.o(.dtors)
109    *crtbegin?.o(.dtors)
110    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
111    *(SORT(.dtors.*))
112    *(.dtors)
113
114    *(.rodata*)
115
116    KEEP(*(.eh_frame*))
117  } > ROM0
118
119#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
120  .gnu.sgstubs :
121  {
122    . = ALIGN(32);
123  } > ROM0
124#endif
125
126  .ARM.extab :
127  {
128    *(.ARM.extab* .gnu.linkonce.armextab.*)
129  } > ROM0
130
131  __exidx_start = .;
132  .ARM.exidx :
133  {
134    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
135  } > ROM0
136  __exidx_end = .;
137
138  .copy.table :
139  {
140    . = ALIGN(4);
141    __copy_table_start__ = .;
142
143    LONG (LOADADDR(.data))
144    LONG (ADDR(.data))
145    LONG (SIZEOF(.data) / 4)
146
147    /* Add each additional data section here */
148/*
149    LONG (LOADADDR(.data2))
150    LONG (ADDR(.data2))
151    LONG (SIZEOF(.data2) / 4)
152*/
153    __copy_table_end__ = .;
154  } > ROM0
155
156  .zero.table :
157  {
158    . = ALIGN(4);
159    __zero_table_start__ = .;
160
161/*  .bss initialization to zero is already done during C Run-Time Startup.
162    LONG (ADDR(.bss))
163    LONG (SIZEOF(.bss) / 4)
164*/
165
166    /* Add each additional bss section here */
167/*
168    LONG (ADDR(.bss2))
169    LONG (SIZEOF(.bss2) / 4)
170*/
171    __zero_table_end__ = .;
172  } > ROM0
173
174  /*
175   * This __etext variable is kept for backward compatibility with older,
176   * ASM based startup files.
177   */
178  PROVIDE(__etext = LOADADDR(.data));
179
180  .data : ALIGN(4)
181  {
182    __data_start__ = .;
183    *(vtable)
184    *(.data)
185    *(.data.*)
186
187    . = ALIGN(4);
188    /* preinit data */
189    PROVIDE_HIDDEN (__preinit_array_start = .);
190    KEEP(*(.preinit_array))
191    PROVIDE_HIDDEN (__preinit_array_end = .);
192
193    . = ALIGN(4);
194    /* init data */
195    PROVIDE_HIDDEN (__init_array_start = .);
196    KEEP(*(SORT(.init_array.*)))
197    KEEP(*(.init_array))
198    PROVIDE_HIDDEN (__init_array_end = .);
199
200    . = ALIGN(4);
201    /* finit data */
202    PROVIDE_HIDDEN (__fini_array_start = .);
203    KEEP(*(SORT(.fini_array.*)))
204    KEEP(*(.fini_array))
205    PROVIDE_HIDDEN (__fini_array_end = .);
206
207    KEEP(*(.jcr*))
208    . = ALIGN(4);
209    /* All data end */
210    __data_end__ = .;
211
212  } > RAM0 AT > ROM0
213
214  /*
215   * Secondary data section, optional
216   *
217   * Remember to add each additional data section
218   * to the .copy.table above to assure proper
219   * initialization during startup.
220   */
221/*
222  .data2 : ALIGN(4)
223  {
224    . = ALIGN(4);
225    __data2_start__ = .;
226    *(.data2)
227    *(.data2.*)
228    . = ALIGN(4);
229    __data2_end__ = .;
230
231  } > RAM1 AT > ROM0
232*/
233
234  .bss :
235  {
236    . = ALIGN(4);
237    __bss_start__ = .;
238    *(.bss)
239    *(.bss.*)
240    *(COMMON)
241    . = ALIGN(4);
242    __bss_end__ = .;
243  } > RAM0 AT > RAM0
244
245  /*
246   * Secondary bss section, optional
247   *
248   * Remember to add each additional bss section
249   * to the .zero.table above to assure proper
250   * initialization during startup.
251   */
252/*
253  .bss2 :
254  {
255    . = ALIGN(4);
256    __bss2_start__ = .;
257    *(.bss2)
258    *(.bss2.*)
259    . = ALIGN(4);
260    __bss2_end__ = .;
261  } > RAM1 AT > RAM1
262*/
263
264  /* This section contains data that is not initialized during load,
265     or during the application's initialization sequence. */
266  .noinit (NOLOAD) :
267  {
268    . = ALIGN(4);
269    __noinit_start = .;
270    *(.noinit)
271    *(.noinit.*)
272    . = ALIGN(4);
273    __noinit_end = .;
274  } > RAM0
275
276  .heap (NOLOAD) :
277  {
278    . = ALIGN(8);
279    __end__ = .;
280    PROVIDE(end = .);
281    . = . + __HEAP_SIZE;
282    . = ALIGN(8);
283    __HeapLimit = .;
284  } > RAM0
285
286  .stack (ORIGIN(RAM0) + LENGTH(RAM0) - __STACK_SIZE - __STACKSEAL_SIZE) (NOLOAD) :
287  {
288    . = ALIGN(8);
289    __StackLimit = .;
290    . = . + __STACK_SIZE;
291    . = ALIGN(8);
292    __StackTop = .;
293  } > RAM0
294  PROVIDE(__stack = __StackTop);
295
296#if __STACKSEAL_SIZE > 0
297  .stackseal (ORIGIN(RAM0) + LENGTH(RAM0) - __STACKSEAL_SIZE) (NOLOAD) :
298  {
299    . = ALIGN(8);
300    __StackSeal = .;
301    . = . + 8;
302    . = ALIGN(8);
303  } > RAM0
304#endif
305
306  /* Check if data + heap + stack exceeds RAM limit */
307  ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
308}
309