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