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"
9MEMORY
10{
11    FLASH (rx)  : ORIGIN = BL2_CODE_START, LENGTH = BL2_CODE_SIZE
12    RAM   (rwx) : ORIGIN = BL2_DATA_START, LENGTH = BL2_DATA_SIZE
13#ifdef __ENABLE_SCRATCH__
14    SCRATCH_X(rwx) : ORIGIN = SCRATCH_X_START, LENGTH = SCRATCH_X_SIZE
15    SCRATCH_Y(rwx) : ORIGIN = SCRATCH_Y_START, LENGTH = SCRATCH_Y_SIZE
16#endif
17}
18__heap_size__  = BL2_HEAP_SIZE;
19__msp_stack_size__ = BL2_MSP_STACK_SIZE;
20ENTRY(Reset_Handler)
21SECTIONS
22{
23    .flash_begin : {
24        __flash_binary_start = .;
25    } > FLASH
26    .text (READONLY) :
27    {
28        __logical_binary_start = .;
29        __Vectors_Start = .;
30        KEEP(*(.vectors))
31        __Vectors_End = .;
32        __Vectors_Size = __Vectors_End - __Vectors_Start;
33        KEEP (*(.binary_info_header))
34        __binary_info_header_end = .;
35        KEEP (*(.embedded_block))
36        __embedded_block_end = .;
37        KEEP (*(.reset))
38        __end__ = .;
39        . = ALIGN(4);
40        /* preinit data */
41        PROVIDE_HIDDEN (__preinit_array_start = .);
42        KEEP(*(SORT(.preinit_array.*)))
43        KEEP(*(.preinit_array))
44        PROVIDE_HIDDEN (__preinit_array_end = .);
45        . = ALIGN(4);
46        /* init data */
47        PROVIDE_HIDDEN (__init_array_start = .);
48        KEEP(*(SORT(.init_array.*)))
49        KEEP(*(.init_array))
50        PROVIDE_HIDDEN (__init_array_end = .);
51        . = ALIGN(4);
52        /* finit data */
53        PROVIDE_HIDDEN (__fini_array_start = .);
54        KEEP(*(SORT(.fini_array.*)))
55        KEEP(*(.fini_array))
56        PROVIDE_HIDDEN (__fini_array_end = .);
57        /* .copy.table */
58        . = ALIGN(4);
59        __copy_table_start__ = .;
60#ifdef CODE_SHARING
61        LONG (LOADADDR(.tfm_shared_symbols))
62        LONG (ADDR(.tfm_shared_symbols))
63        LONG (SIZEOF(.tfm_shared_symbols) / 4)
64#endif
65        LONG (LOADADDR(.data))
66        LONG (ADDR(.data))
67        LONG (SIZEOF(.data) / 4)
68        __copy_table_end__ = .;
69        /* .zero.table */
70        . = ALIGN(4);
71        __zero_table_start__ = .;
72        LONG (ADDR(.bss))
73        LONG (SIZEOF(.bss) / 4)
74        __zero_table_end__ = .;
75        KEEP(*(.init))
76        *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*)
77        KEEP(*(.fini))
78        /* .ctors */
79        *crtbegin.o(.ctors)
80        *crtbegin?.o(.ctors)
81        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
82        *(SORT(.ctors.*))
83        *(.ctors)
84        /* .dtors */
85         *crtbegin.o(.dtors)
86         *crtbegin?.o(.dtors)
87         *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
88         *(SORT(.dtors.*))
89         *(.dtors)
90        *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*)
91        *(.srodata*)
92        . = ALIGN(4);
93        *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
94        . = ALIGN(4);
95        KEEP(*(.eh_frame*))
96        . = ALIGN(4);
97    } > FLASH
98    /* Note the boot2 section is optional, and should be discarded if there is
99       no reference to it *inside* the binary, as it is not called by the
100       bootrom. (The bootrom performs a simple best-effort XIP setup and
101       leaves it to the binary to do anything more sophisticated.) However
102       there is still a size limit of 256 bytes, to ensure the boot2 can be
103       stored in boot RAM.
104       Really this is a "XIP setup function" -- the name boot2 is historic and
105       refers to its dual-purpose on RP2040, where it also handled vectoring
106       from the bootrom into the user image.
107    */
108    .boot2 : {
109        __boot2_start__ = .;
110        *(.boot2)
111        __boot2_end__ = .;
112    } > FLASH
113    ASSERT(__boot2_end__ - __boot2_start__ <= 256,
114        "ERROR: Pico second stage bootloader must be no more than 256 bytes in size")
115    .ARM.extab :
116    {
117        *(.ARM.extab* .gnu.linkonce.armextab.*)
118    } > FLASH
119    __exidx_start = .;
120    .ARM.exidx :
121    {
122        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
123    } > FLASH
124    __exidx_end = .;
125    /* Machine inspectable binary information */
126    . = ALIGN(4);
127    __binary_info_start = .;
128    .binary_info :
129    {
130        KEEP(*(.binary_info.keep.*))
131        *(.binary_info.*)
132    } > FLASH
133    __binary_info_end = .;
134#ifdef CODE_SHARING
135    /* The code sharing between bootloader and runtime firmware requires to
136     * share the global variables. Section size must be equal with
137     * SHARED_SYMBOL_AREA_SIZE defined in region_defs.h
138     */
139    .tfm_shared_symbols : ALIGN(4)
140    {
141        *(.data.mbedtls_calloc_func)
142        *(.data.mbedtls_free_func)
143        *(.data.mbedtls_exit)
144        *(.data.memset_func)
145        . = ALIGN(SHARED_SYMBOL_AREA_SIZE);
146    } > RAM AT > FLASH
147    ASSERT(SHARED_SYMBOL_AREA_SIZE % 4 == 0, "SHARED_SYMBOL_AREA_SIZE must be divisible by 4")
148#endif
149    .tfm_bl2_shared_data : ALIGN(32)
150    {
151        . += BOOT_TFM_SHARED_DATA_SIZE;
152    } > RAM
153    Image$$SHARED_DATA$$RW$$Base = ADDR(.tfm_bl2_shared_data);
154    Image$$SHARED_DATA$$RW$$Limit = ADDR(.tfm_bl2_shared_data) + SIZEOF(.tfm_bl2_shared_data);
155    . = ALIGN(4);
156   .ram_vector_table (NOLOAD): {
157        *(.ram_vector_table)
158    } > RAM
159    .data : ALIGN(4)
160    {
161        __data_start__ = .;
162        *(vtable)
163        *(.time_critical*)
164        /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */
165        *(.text*)
166        . = ALIGN(4);
167        *(.rodata*)
168        . = ALIGN(4);
169        *(.data*)
170        *(.sdata*)
171        . = ALIGN(4);
172        *(.after_data.*)
173        . = ALIGN(4);
174        /* preinit data */
175        PROVIDE_HIDDEN (__mutex_array_start = .);
176        KEEP(*(SORT(.mutex_array.*)))
177        KEEP(*(.mutex_array))
178        PROVIDE_HIDDEN (__mutex_array_end = .);
179        KEEP(*(.jcr*))
180        . = ALIGN(4);
181        /* All data end */
182        __data_end__ = .;
183    } > RAM AT > FLASH
184    __etext = LOADADDR(.data);
185    Image$$ER_DATA$$Base = ADDR(.data);
186    .uninitialized_data (NOLOAD): {
187        . = ALIGN(4);
188        *(.uninitialized_data*)
189    } > RAM
190    .bss : ALIGN(4)
191    {
192        . = ALIGN(4);
193        __bss_start__ = .;
194        *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
195        *(COMMON)
196        PROVIDE(__global_pointer$ = . + 2K);
197        *(.sbss*)
198        . = ALIGN(4);
199        __bss_end__ = .;
200    } > RAM
201#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
202    .msp_stack ALIGN(32) :
203    {
204        . += __msp_stack_size__ - 0x8;
205    } > RAM
206    Image$$ARM_LIB_STACK$$ZI$$Base = ADDR(.msp_stack);
207    Image$$ARM_LIB_STACK$$ZI$$Limit = ADDR(.msp_stack) + SIZEOF(.msp_stack);
208    .msp_stack_seal_res :
209    {
210        . += 0x8;
211    } > RAM
212    __StackSeal = ADDR(.msp_stack_seal_res);
213#else
214    .msp_stack ALIGN(32) :
215    {
216        . += __msp_stack_size__;
217    } > RAM
218    Image$$ARM_LIB_STACK$$ZI$$Base = ADDR(.msp_stack);
219    Image$$ARM_LIB_STACK$$ZI$$Limit = ADDR(.msp_stack) + SIZEOF(.msp_stack);
220#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
221#ifdef __ENABLE_SCRATCH__
222    /* Start and end symbols must be word-aligned */
223    .scratch_x : {
224        __scratch_x_start__ = .;
225        *(.scratch_x.*)
226        . = ALIGN(4);
227        __scratch_x_end__ = .;
228    } > SCRATCH_X AT > FLASH
229    __scratch_x_source__ = LOADADDR(.scratch_x);
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#endif
238    .heap (NOLOAD): ALIGN(8)
239    {
240        . = ALIGN(8);
241        __end__ = .;
242        PROVIDE(end = .);
243        __HeapBase = .;
244        KEEP(*(.heap*))
245        . += __heap_size__;
246        __HeapLimit = .;
247        __heap_limit = .; /* Add for _sbrk */
248    } > RAM
249    Image$$ARM_LIB_HEAP$$ZI$$Limit = ADDR(.heap) + SIZEOF(.heap);
250    /* .stack*_dummy section doesn't contains any symbols. It is only
251     * used for linker to calculate size of stack sections, and assign
252     * values to stack symbols later
253     *
254     * stack1 section may be empty/missing if platform_launch_core1 is not used */
255    /* by default we put core 0 stack at the end of scratch Y, so that if core 1
256     * stack is not used then all of SCRATCH_X is free.
257     */
258#ifdef __ENABLE_SCRATCH__
259    .stack1_dummy (NOLOAD):
260    {
261        *(.stack1*)
262    } > SCRATCH_X
263    .stack_dummy (NOLOAD):
264    {
265        KEEP(*(.stack*))
266    } > SCRATCH_Y
267#endif
268    .flash_end : {
269        PROVIDE(__flash_binary_end = .);
270    } > FLASH =0xaa
271    PROVIDE(__stack = Image$$ARM_LIB_STACK$$ZI$$Limit);
272#ifdef __ENABLE_SCRATCH__
273    /* stack limit is poorly named, but historically is maximum heap ptr */
274    __StackLimit = ORIGIN(RAM) + LENGTH(RAM);
275    __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
276    __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
277    __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
278    __StackBottom = __StackTop - SIZEOF(.stack_dummy);
279    /* Check if data + heap + stack exceeds RAM limit */
280    ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
281#endif
282    ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary")
283    /* todo assert on extra code */
284}
285