1;/*
2; *  SPDX-License-Identifier: BSD-3-Clause
3; *  SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
4; *
5; */
6/* Linker script to configure memory regions. */
7/* This file will be run trough the pre-processor. */
8#include "region_defs.h"
9/* Include file with definitions for section alignments.
10 * Note: it should be included after region_defs.h to let platform define
11 * default values if needed. */
12MEMORY
13{
14    FLASH (rx)  : ORIGIN = NS_CODE_START, LENGTH = NS_CODE_SIZE
15    RAM   (rwx) : ORIGIN = NS_DATA_START, LENGTH = NS_DATA_SIZE
16#ifdef __ENABLE_SCRATCH__
17    SCRATCH_X(rwx) : ORIGIN = SRAM_SCRATCH_X_BASE, LENGTH = SCRATCH_X_SIZE
18    SCRATCH_Y(rwx) : ORIGIN = SRAM_SCRATCH_Y_BASE, LENGTH = SCRATCH_Y_SIZE
19#endif
20}
21
22__heap_size__  = NS_HEAP_SIZE;
23__stack_size__ = NS_STACK_SIZE;
24ENTRY(_entry_point)
25SECTIONS
26{
27    .vectors :
28    {
29        __logical_binary_start = .;
30        __Vectors_Start__ = .;
31        KEEP(*(.vectors))
32        __Vectors_End = .;
33        __Vectors_Size = __Vectors_End - __Vectors_Start__;
34        __end__ = .;
35    } > FLASH
36
37#if defined(NS_VECTOR_ALLOCATED_SIZE)
38    ASSERT(. <= ADDR(.vectors) + NS_VECTOR_ALLOCATED_SIZE, ".vectors section size overflow.")
39    . = ADDR(.vectors) + NS_VECTOR_ALLOCATED_SIZE;
40#endif
41
42    .CORE1_ENTRY : ALIGN(4)
43    {
44        KEEP (*(.core1_ns_entry*))
45    }
46
47    .PICO_RESET : ALIGN(4)
48    {
49        KEEP (*(.binary_info_header))
50        __binary_info_header_end = .;
51        KEEP (*(.embedded_block))
52        __embedded_block_end = .;
53        KEEP (*(.reset))
54    } > FLASH
55
56    .text (READONLY) :
57    {
58        *(.text*)
59
60        . = ALIGN(4);
61        /* preinit data */
62        PROVIDE_HIDDEN (__mutex_array_start = .);
63        KEEP(*(SORT(.mutex_array.*)))
64        KEEP(*(.mutex_array))
65        PROVIDE_HIDDEN (__mutex_array_end = .);
66
67        . = ALIGN(4);
68        /* preinit data */
69        PROVIDE_HIDDEN (__preinit_array_start = .);
70        KEEP(*(SORT(.preinit_array.*)))
71        KEEP(*(.preinit_array))
72        PROVIDE_HIDDEN (__preinit_array_end = .);
73
74        . = ALIGN(4);
75        /* init data */
76        PROVIDE_HIDDEN (__init_array_start = .);
77        KEEP(*(SORT(.init_array.*)))
78        KEEP(*(.init_array))
79        PROVIDE_HIDDEN (__init_array_end = .);
80
81        . = ALIGN(4);
82        /* finit data */
83        PROVIDE_HIDDEN (__fini_array_start = .);
84        KEEP(*(SORT(.fini_array.*)))
85        KEEP(*(.fini_array))
86        PROVIDE_HIDDEN (__fini_array_end = .);
87
88        /* .copy.table */
89        . = ALIGN(4);
90        __copy_table_start__ = .;
91        LONG (__etext)
92        LONG (__data_start__)
93        LONG ((__data_end__ - __data_start__) / 4)
94        LONG (__etext2)
95        LONG (__data2_start__)
96        LONG ((__data2_end__ - __data2_start__) / 4)
97        __copy_table_end__ = .;
98
99        /* .zero.table */
100        . = ALIGN(4);
101        __zero_table_start__ = .;
102        LONG (__bss_start__)
103        LONG ((__bss_end__ - __bss_start__) / 4)
104        LONG (__bss2_start__)
105        LONG ((__bss2_end__ - __bss2_start__) / 4)
106        __zero_table_end__ = .;
107
108        KEEP(*(.init))
109        KEEP(*(.fini))
110
111        /* .ctors */
112        *crtbegin.o(.ctors)
113        *crtbegin?.o(.ctors)
114        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
115        *(SORT(.ctors.*))
116        *(.ctors)
117
118        /* .dtors */
119         *crtbegin.o(.dtors)
120         *crtbegin?.o(.dtors)
121         *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
122         *(SORT(.dtors.*))
123         *(.dtors)
124
125        *(.rodata*)
126
127        KEEP(*(.eh_frame*))
128    } > FLASH
129
130    .ARM.extab :
131    {
132        *(.ARM.extab* .gnu.linkonce.armextab.*)
133    } > FLASH
134
135    __exidx_start = .;
136    .ARM.exidx :
137    {
138        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
139    } > FLASH
140    __exidx_end = .;
141
142    /* Machine inspectable binary information */
143    . = ALIGN(4);
144    __binary_info_start = .;
145    .binary_info :
146    {
147        KEEP(*(.binary_info.keep.*))
148        *(.binary_info.*)
149    } > FLASH
150    __binary_info_end = .;
151
152    __etext2 = ALIGN(4);
153
154    .data : AT (__etext2)
155    {
156        __data2_start__ = .;
157        *(vtable)
158        *(.data*)
159
160        KEEP(*(.jcr*))
161        . = ALIGN(4);
162        /* All data end */
163        __data2_end__ = .;
164    } > RAM
165
166    /* Pico crt0.S copies the __data_start__-__data_end__ region, but we handle
167     * that in our runtime_init */
168     __etext = 0;
169     __data_start__ = 0;
170     __data_end__ = 0;
171
172    .ram_vector_table (NOLOAD): ALIGN(256)  {
173        *(.ram_vector_table)
174    } > RAM
175
176    .bss :
177    {
178        . = ALIGN(4);
179        __bss2_start__ = .;
180        *(.bss*)
181        *(COMMON)
182        . = ALIGN(4);
183        __bss2_end__ = .;
184    } > RAM
185
186    /* Pico crt0.S zeros the __bss_start__-__bss_end__ region, but we handle
187     * that in our runtime_init */
188     __bss_start__ = 0;
189     __bss_end__ = 0;
190
191    bss_size = __bss2_end__ - __bss2_start__;
192
193    .heap : ALIGN(8)
194    {
195        . = ALIGN(8);
196        __end__ = .;
197        PROVIDE(end = .);
198        __HeapBase = .;
199        . += __heap_size__;
200        __HeapLimit = .;
201        __heap_limit = .; /* Add for _sbrk */
202    } > RAM
203
204    #ifdef __ENABLE_SCRATCH__
205    /* Start and end symbols must be word-aligned */
206    .scratch_x : {
207        __scratch_x_start__ = .;
208        *(.scratch_x.*)
209        . = ALIGN(4);
210        __scratch_x_end__ = .;
211    } > SCRATCH_X AT > FLASH
212    __scratch_x_source__ = LOADADDR(.scratch_x);
213    .scratch_y : {
214        __scratch_y_start__ = .;
215        *(.scratch_y.*)
216        . = ALIGN(4);
217        __scratch_y_end__ = .;
218    } > SCRATCH_Y AT > FLASH
219    __scratch_y_source__ = LOADADDR(.scratch_y);
220
221    .stack1_dummy (NOLOAD):
222    {
223        *(.stack1*)
224    } > SCRATCH_X
225    .stack_dummy (NOLOAD):
226    {
227        KEEP(*(.stack*))
228    } > SCRATCH_Y
229
230    /* stack limit is poorly named, but historically is maximum heap ptr */
231    __StackLimit = ORIGIN(RAM) + LENGTH(RAM);
232    __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
233    __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
234    __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
235    __StackBottom = __StackTop - SIZEOF(.stack_dummy);
236    /* Check if data + heap + stack exceeds RAM limit */
237    ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
238    PROVIDE(__stack = __StackTop);
239#endif
240
241    ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary")
242}
243