1;/*
2; * Copyright (c) 2009-2023 Arm Limited
3; *
4; * Licensed under the Apache License, Version 2.0 (the "License");
5; * you may not use this file except in compliance with the License.
6; * You may obtain a copy of the License at
7; *
8; *     http://www.apache.org/licenses/LICENSE-2.0
9; *
10; * Unless required by applicable law or agreed to in writing, software
11; * distributed under the License is distributed on an "AS IS" BASIS,
12; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13; * See the License for the specific language governing permissions and
14; * limitations under the License.
15; */
16
17/* Linker script to configure memory regions. */
18/* This file will be run trough the pre-processor. */
19
20#include "region_defs.h"
21
22MEMORY
23{
24  FLASH (rx)  : ORIGIN = S_CODE_START, LENGTH = S_CODE_SIZE
25  RAM   (rwx) : ORIGIN = S_DATA_START, LENGTH = S_DATA_SIZE
26}
27
28__heap_size__  = HEAP_SIZE;
29__stack_size__ = STACK_SIZE;
30
31/* Library configurations */
32GROUP(libgcc.a libc.a libm.a libnosys.a)
33
34/* Linker script to place sections and symbol values. Should be used together
35 * with other linker script that defines memory regions FLASH and RAM.
36 * It references following symbols, which must be defined in code:
37 *   Reset_Handler : Entry of reset handler
38 *
39 * It defines following symbols, which code can use without definition:
40 *   __exidx_start
41 *   __exidx_end
42 *   __copy_table_start__
43 *   __copy_table_end__
44 *   __zero_table_start__
45 *   __zero_table_end__
46 *   __etext
47 *   __data_start__
48 *   __preinit_array_start
49 *   __preinit_array_end
50 *   __init_array_start
51 *   __init_array_end
52 *   __fini_array_start
53 *   __fini_array_end
54 *   __data_end__
55 *   __bss_start__
56 *   __bss_end__
57 *   __end__
58 *   end
59 *   __HeapBase
60 *   __HeapLimit
61 *   __StackLimit
62 *   __StackTop
63 *   __stack
64 *   __Vectors_End
65 *   __Vectors_Size
66 */
67ENTRY(Reset_Handler)
68
69SECTIONS
70{
71    .text :
72    {
73        KEEP(*(.vectors))
74        __Vectors_End = .;
75        __Vectors_Size = __Vectors_End - __Vectors;
76        __end__ = .;
77
78        *(.text*)
79
80        KEEP(*(.init))
81        KEEP(*(.fini))
82
83
84        /* .ctors */
85        *crtbegin.o(.ctors)
86        *crtbegin?.o(.ctors)
87        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
88        *(SORT(.ctors.*))
89        *(.ctors)
90
91        /* .dtors */
92         *crtbegin.o(.dtors)
93         *crtbegin?.o(.dtors)
94         *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
95         *(SORT(.dtors.*))
96         *(.dtors)
97
98        *(.rodata*)
99
100        KEEP(*(.eh_frame*))
101    } > FLASH
102
103    /*
104     * Place the CMSE Veneers (containing the SG instruction) after the code, in a
105     * separate 32 bytes aligned region so that the SAU can programmed to just set
106     * this region as Non-Secure Callable. The maximum size of this executable
107     * region makes it only used the space left over by the ER_CODE region
108     * so that you can rely on code+veneer size combined will not exceed the
109     * S_CODE_SIZE value. We also substract from the available space the
110     * area used to align this section on 32 bytes boundary (for SAU conf).
111     */
112    .gnu.sgstubs : ALIGN(32)
113    {
114        *(.gnu.sgstubs*)
115    } > FLASH
116    . = ALIGN(32);
117    Image$$ER_CODE_CMSE_VENEER$$Base = ADDR(.gnu.sgstubs);
118    Image$$ER_CODE_CMSE_VENEER$$Limit = .;
119    Image$$ER_CODE_CMSE_VENEER$$Length = Image$$ER_CODE_CMSE_VENEER$$Limit - Image$$ER_CODE_CMSE_VENEER$$Base;
120
121    /* Make sure veneers fit into code memory */
122    ASSERT(((S_CODE_START + S_CODE_SIZE) > Image$$ER_CODE_CMSE_VENEER$$Limit), "Veneer region does not fit into code memory")
123
124    .ARM.extab : ALIGN(32)
125    {
126        *(.ARM.extab* .gnu.linkonce.armextab.*)
127    } > FLASH
128
129    __exidx_start = .;
130    .ARM.exidx :
131    {
132        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
133    } > FLASH
134    __exidx_end = .;
135
136    /* To copy multiple ROM to RAM sections,
137     * define etext2/data2_start/data2_end and
138     * define __STARTUP_COPY_MULTIPLE in startup_cmsdk_mps2_sse_200.S */
139    .copy.table : ALIGN(4)
140    {
141        __copy_table_start__ = .;
142        LONG (__etext)
143        LONG (__data_start__)
144        LONG ((__data_end__ - __data_start__) / 4)
145        LONG (DEFINED(__etext2) ? __etext2 : 0)
146        LONG (DEFINED(__data2_start__) ? __data2_start__ : 0)
147        LONG (DEFINED(__data2_start__) ? ((__data2_end__ - __data2_start__) / 4) : 0)
148        __copy_table_end__ = .;
149    } > FLASH
150
151    /* To clear multiple BSS sections,
152     * uncomment .zero.table section and,
153     * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
154    .zero.table : ALIGN(4)
155    {
156        __zero_table_start__ = .;
157        LONG (__bss_start__)
158        LONG ((__bss_end__ - __bss_start__) / 4)
159        LONG (DEFINED(__bss2_start__) ? __bss2_start__ : 0)
160        LONG (DEFINED(__bss2_start__) ? ((__bss2_end__ - __bss2_start__) / 4) : 0)
161        __zero_table_end__ = .;
162    } > FLASH
163
164    __etext = ALIGN(4);
165
166    .data : ALIGN(4)
167    {
168        __data_start__ = .;
169        *(vtable)
170        *(.data*)
171
172        . = ALIGN(4);
173        /* preinit data */
174        PROVIDE_HIDDEN (__preinit_array_start = .);
175        KEEP(*(.preinit_array))
176        PROVIDE_HIDDEN (__preinit_array_end = .);
177
178        . = ALIGN(4);
179        /* init data */
180        PROVIDE_HIDDEN (__init_array_start = .);
181        KEEP(*(SORT(.init_array.*)))
182        KEEP(*(.init_array))
183        PROVIDE_HIDDEN (__init_array_end = .);
184
185
186        . = ALIGN(4);
187        /* finit data */
188        PROVIDE_HIDDEN (__fini_array_start = .);
189        KEEP(*(SORT(.fini_array.*)))
190        KEEP(*(.fini_array))
191        PROVIDE_HIDDEN (__fini_array_end = .);
192
193        KEEP(*(.jcr*))
194        . = ALIGN(4);
195        /* All data end */
196        __data_end__ = .;
197
198    } > RAM AT> FLASH
199
200    .bss : ALIGN(4)
201    {
202        __bss_start__ = .;
203        *(.bss*)
204        *(COMMON)
205        . = ALIGN(4);
206        __bss_end__ = .;
207    } > RAM
208
209    bss_size = __bss_end__ - __bss_start__;
210
211    .stack : ALIGN(8)
212    {
213        __StackLimit = .;
214        KEEP(*(.stack*))
215        . += __stack_size__ - 0x8;
216        __StackTop = .;
217    } > RAM
218
219    .msp_stack_seal_res :
220    {
221        . += 0x8;
222    } > RAM
223    __StackSeal = ADDR(.msp_stack_seal_res);
224
225    .heap : ALIGN(8)
226    {
227        __end__ = .;
228        PROVIDE(end = .);
229        __HeapBase = .;
230        . += __heap_size__;
231        __HeapLimit = .;
232        __heap_limit = .; /* Add for _sbrk */
233    } > RAM
234
235    /* Set stack top to end of the used RAM section, and stack limit move down by
236     * size of stack_dummy section */
237    PROVIDE(__stack = __StackTop);
238
239
240    /* Check if data + heap + stack exceeds RAM limit */
241    ASSERT(__StackTop <= (S_DATA_START + S_DATA_SIZE), "Secure RAM region overflowed")
242}
243