1;/* 2; * Copyright (c) 2009-2022 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; * This file is derivative of CMSIS V5.00 gcc_arm.ld 18; */ 19 20/* Linker script to configure memory regions. */ 21/* This file will be run trough the pre-processor. */ 22 23#include "region_defs.h" 24 25MEMORY 26{ 27 FLASH (rx) : ORIGIN = S_CODE_START, LENGTH = S_CODE_SIZE 28 RAM (rwx) : ORIGIN = S_DATA_START, LENGTH = S_DATA_SIZE 29 VENEERS (rx) : ORIGIN = CMSE_VENEER_REGION_START, LENGTH = CMSE_VENEER_REGION_SIZE 30 31#if defined(PSA_PROXY_SHARED_MEMORY_BASE) 32 PSA_PROXY_SHARED_MEMORY_RAM (rw) : ORIGIN = PSA_PROXY_SHARED_MEMORY_BASE, LENGTH = PSA_PROXY_SHARED_MEMORY_SIZE 33#endif 34 35} 36 37__heap_size__ = S_HEAP_SIZE; 38__msp_stack_size__ = S_MSP_STACK_SIZE; 39 40/* Library configurations */ 41GROUP(libgcc.a libc.a libm.a libnosys.a libc_nano.a) 42 43ENTRY(Reset_Handler) 44 45SECTIONS 46{ 47 .TFM_VECTORS : ALIGN(4) 48 { 49 __vectors_start__ = .; 50 KEEP(*(.vectors)) 51 __vectors_end__ = .; 52 *startup*(.text*) 53 . = ALIGN(4); 54 } > FLASH 55 56 .copy.table : ALIGN(4) 57 { 58 __copy_table_start__ = .; 59 LONG (LOADADDR(.TFM_DATA)) 60 LONG (ADDR(.TFM_DATA)) 61 LONG (SIZEOF(.TFM_DATA) / 4) 62 63 LONG (LOADADDR(.TFM_PSA_ROT_LINKER_DATA)) 64 LONG (ADDR(.TFM_PSA_ROT_LINKER_DATA)) 65 LONG (SIZEOF(.TFM_PSA_ROT_LINKER_DATA) / 4) 66 67 LONG (LOADADDR(.TFM_APP_ROT_LINKER_DATA)) 68 LONG (ADDR(.TFM_APP_ROT_LINKER_DATA)) 69 LONG (SIZEOF(.TFM_APP_ROT_LINKER_DATA) / 4) 70 __copy_table_end__ = .; 71 } > FLASH 72 73 .zero.table : ALIGN(4) 74 { 75 __zero_table_start__ = .; 76 LONG (ADDR(.TFM_BSS)) 77 LONG (SIZEOF(.TFM_BSS) / 4) 78 LONG (ADDR(.TFM_PSA_ROT_LINKER_BSS)) 79 LONG (SIZEOF(.TFM_PSA_ROT_LINKER_BSS) / 4) 80 81 LONG (ADDR(.TFM_APP_ROT_LINKER_BSS)) 82 LONG (SIZEOF(.TFM_APP_ROT_LINKER_BSS) / 4) 83#if defined(PSA_PROXY_SHARED_MEMORY_BASE) 84 LONG (PSA_PROXY_SHARED_MEMORY_BASE) 85 LONG (PSA_PROXY_SHARED_MEMORY_SIZE / 4) 86#endif 87#if defined(CONFIG_TFM_PARTITION_META) 88 LONG (ADDR(.TFM_SP_META_PTR)) 89 LONG (SIZEOF(.TFM_SP_META_PTR) / 4) 90#endif 91 __zero_table_end__ = .; 92 } > FLASH 93 94 /**** Section for holding partition RO load data */ 95 /* 96 * Sort the partition info by priority to guarantee the initing order. 97 * The first loaded partition will be inited at last in SFN model. 98 */ 99 .TFM_SP_LOAD_LIST : ALIGN(4) 100 { 101 KEEP(*(.part_load_priority_lowest)) 102 KEEP(*(.part_load_priority_low)) 103 KEEP(*(.part_load_priority_normal)) 104 KEEP(*(.part_load_priority_high)) 105 } > FLASH 106 Image$$TFM_SP_LOAD_LIST$$RO$$Base = ADDR(.TFM_SP_LOAD_LIST); 107 Image$$TFM_SP_LOAD_LIST$$RO$$Limit = ADDR(.TFM_SP_LOAD_LIST) + SIZEOF(.TFM_SP_LOAD_LIST); 108 . = ALIGN(32); 109 110 /**** PSA RoT RO part (CODE + RODATA) start here */ 111 Image$$TFM_PSA_CODE_START$$Base = .; 112 113 .TFM_PSA_ROT_LINKER : ALIGN(32) 114 { 115 *tfm_psa_rot_partition*:*(.text*) 116 *tfm_psa_rot_partition*:*(.rodata*) 117 *(TFM_*_PSA-ROT_ATTR_FN) 118 . = ALIGN(32); 119 } > FLASH 120 121 Image$$TFM_PSA_ROT_LINKER$$RO$$Base = ADDR(.TFM_PSA_ROT_LINKER); 122 Image$$TFM_PSA_ROT_LINKER$$RO$$Limit = ADDR(.TFM_PSA_ROT_LINKER) + SIZEOF(.TFM_PSA_ROT_LINKER); 123 Image$$TFM_PSA_ROT_LINKER$$Base = ADDR(.TFM_PSA_ROT_LINKER); 124 Image$$TFM_PSA_ROT_LINKER$$Limit = ADDR(.TFM_PSA_ROT_LINKER) + SIZEOF(.TFM_PSA_ROT_LINKER); 125 126 /**** PSA RoT RO part (CODE + RODATA) end here */ 127 Image$$TFM_PSA_CODE_END$$Base = .; 128 129 130#if TFM_LVL != 1 131 .ARM.extab : 132 { 133 *(.ARM.extab* .gnu.linkonce.armextab.*) 134 } > FLASH 135 136 __exidx_start = .; 137 .ARM.exidx : 138 { 139 *(.ARM.exidx* .gnu.linkonce.armexidx.*) 140 } > FLASH 141 __exidx_end = .; 142 143#endif /* TFM_LVL != 1 */ 144 145 .ER_TFM_CODE : ALIGN(4) 146 { 147 *libplatform_s*:*(.text*) 148 *libtfm_spm*:*(.text*) 149 150 *libplatform_s*:*(.rodata*) 151 *libtfm_spm*:*(.rodata*) 152 } > FLASH 153 /* unpriv data is placed 1st */ 154 .dummy_empty : ALIGN(32) 155 { 156 . += 0x0; 157 } > RAM 158/**** Unpriv DATA start here */ 159 Image$$TFM_APP_RW_STACK_START$$Base = ADDR(.dummy_empty); 160#if defined(CONFIG_TFM_PARTITION_META) 161 .TFM_SP_META_PTR : ALIGN(32) 162 { 163 *(.bss.SP_META_PTR_SPRTL_INST) 164 . = ALIGN(32); 165 } > RAM 166 Image$$TFM_SP_META_PTR$$ZI$$Base = ADDR(.TFM_SP_META_PTR); 167 Image$$TFM_SP_META_PTR$$ZI$$Limit = ADDR(.TFM_SP_META_PTR) + SIZEOF(.TFM_SP_META_PTR); 168#endif 169 170 .TFM_APP_ROT_LINKER_DATA : ALIGN(32) 171 { 172 *tfm_app_rot_partition*:*(.data*) 173 *(TFM_*_APP-ROT_ATTR_RW) 174 . = ALIGN(32); 175 } > RAM AT> FLASH 176 Image$$TFM_APP_ROT_LINKER_DATA$$RW$$Base = ADDR(.TFM_APP_ROT_LINKER_DATA); 177 Image$$TFM_APP_ROT_LINKER_DATA$$RW$$Limit = ADDR(.TFM_APP_ROT_LINKER_DATA) + SIZEOF(.TFM_APP_ROT_LINKER_DATA); 178 179 .TFM_APP_ROT_LINKER_BSS : ALIGN(32) 180 { 181 start_of_TFM_APP_ROT_LINKER = .; 182 *tfm_app_rot_partition*:*(.bss*) 183 *tfm_app_rot_partition*:*(COMMON) 184 *(TFM_*_APP-ROT_ATTR_ZI) 185 . += (. - start_of_TFM_APP_ROT_LINKER) ? 0 : 4; 186 . = ALIGN(GTZC_RAM_ALIGN); 187 } > RAM AT> RAM 188 189 ASSERT(GTZC_RAM_ALIGN % 4 == 0, "GTZC_RAM_ALIGN must be divisible by 4") 190 191 Image$$TFM_APP_ROT_LINKER_DATA$$ZI$$Base = ADDR(.TFM_APP_ROT_LINKER_BSS); 192 Image$$TFM_APP_ROT_LINKER_DATA$$ZI$$Limit = ADDR(.TFM_APP_ROT_LINKER_BSS) + SIZEOF(.TFM_APP_ROT_LINKER_BSS); 193 194 195 /**** APPLICATION RoT DATA end here */ 196 Image$$TFM_APP_RW_STACK_END$$Base = .; 197 198 /* shared_data and msp_stack are overlapping on purpose when 199 * msp_stack is extended until the beginning of RAM, when shared_date 200 * was read out by partitions 201 */ 202 .tfm_bl2_shared_data : ALIGN(32) 203 { 204 . += BOOT_TFM_SHARED_DATA_SIZE; 205 } > RAM 206 207 .msp_stack : ALIGN(32) 208 { 209 . += __msp_stack_size__ - 0x8; 210 } > RAM 211 Image$$ARM_LIB_STACK$$ZI$$Base = ADDR(.msp_stack); 212 Image$$ARM_LIB_STACK$$ZI$$Limit = ADDR(.msp_stack) + SIZEOF(.msp_stack); 213 214 .msp_stack_seal_res : 215 { 216 . += 0x8; 217 } > RAM 218 __StackSeal = ADDR(.msp_stack_seal_res); 219 220#if (TFM_LVL == 1) 221 .heap : ALIGN(8) 222 { 223 __end__ = .; 224 PROVIDE(end = .); 225 __HeapBase = .; 226 . += __heap_size__; 227 __HeapLimit = .; 228 __heap_limit = .; /* Add for _sbrk */ 229 } > RAM 230#endif /* TFM_LVL == 1 */ 231 232#if TFM_LVL != 1 233#ifdef TFM_PARTITION_TEST_SECURE_SERVICES 234 .TFM_SP_SECURE_TEST_PARTITION_LINKER_DATA : ALIGN(32) 235 { 236 *libc_nano*:*(.data*) 237 . = ALIGN(32); 238 } > RAM AT> FLASH 239 240 .TFM_SP_SECURE_TEST_PARTITION_LINKER_BSS : ALIGN(32) 241 { 242 /* FixMe: 243 * Test framework use printf to print out test result. Implementation of 244 * printf in GCC libc use static data and heap as well. To be able to 245 * execute test suites with TFM_LVL=3 this workaround is needed to 246 * allocate libc static data and heap within the data section of secure 247 * test partition. This can be removed if test service will be executed 248 * in privileged mode. 249 */ 250 *libc_nano*:*(.bss*) 251 *libc_nano*:*(COMMON) 252 253 __end__ = .; 254 PROVIDE(end = .); 255 __HeapBase = .; 256 . += __heap_size__; 257 __HeapLimit = .; 258 __heap_limit = .; /* Add for _sbrk */ 259 260 . = ALIGN(32); 261 } > RAM AT> RAM 262#else /* TFM_PARTITION_TEST_SECURE_SERVICES */ 263 .heap : ALIGN(8) 264 { 265 __end__ = .; 266 PROVIDE(end = .); 267 __HeapBase = .; 268 . += __heap_size__; 269 __HeapLimit = .; 270 __heap_limit = .; /* Add for _sbrk */ 271 } > RAM AT> RAM 272#endif /* TFM_PARTITION_TEST_SECURE_SERVICES */ 273#endif /* TFM_LVL != 1 */ 274 275 /**** PSA RoT DATA start here */ 276 277 Image$$TFM_PSA_RW_STACK_START$$Base = .; 278 279 .TFM_PSA_ROT_LINKER_DATA : ALIGN(32) 280 { 281 *tfm_psa_rot_partition*:*(.data*) 282 *(TFM_*_PSA-ROT_ATTR_RW) 283 . = ALIGN(32); 284 } > RAM AT> FLASH 285 Image$$TFM_PSA_ROT_LINKER_DATA$$RW$$Base = ADDR(.TFM_PSA_ROT_LINKER_DATA); 286 Image$$TFM_PSA_ROT_LINKER_DATA$$RW$$Limit = ADDR(.TFM_PSA_ROT_LINKER_DATA) + SIZEOF(.TFM_PSA_ROT_LINKER_DATA); 287 288 .TFM_PSA_ROT_LINKER_BSS : ALIGN(32) 289 { 290 start_of_TFM_PSA_ROT_LINKER = .; 291 *tfm_psa_rot_partition*:*(.bss*) 292 *tfm_psa_rot_partition*:*(COMMON) 293 *(TFM_*_PSA-ROT_ATTR_ZI) 294 . += (. - start_of_TFM_PSA_ROT_LINKER) ? 0 : 4; 295 . = ALIGN(32); 296 } > RAM AT> RAM 297 Image$$TFM_PSA_ROT_LINKER_DATA$$ZI$$Base = ADDR(.TFM_PSA_ROT_LINKER_BSS); 298 Image$$TFM_PSA_ROT_LINKER_DATA$$ZI$$Limit = ADDR(.TFM_PSA_ROT_LINKER_BSS) + SIZEOF(.TFM_PSA_ROT_LINKER_BSS); 299 300 .TFM_DATA : ALIGN(4) 301 { 302 *(.data*) 303 304 . = ALIGN(4); 305 /* preinit data */ 306 PROVIDE_HIDDEN (__preinit_array_start = .); 307 KEEP(*(.preinit_array)) 308 PROVIDE_HIDDEN (__preinit_array_end = .); 309 310 . = ALIGN(4); 311 /* init data */ 312 PROVIDE_HIDDEN (__init_array_start = .); 313 KEEP(*(SORT(.init_array.*))) 314 KEEP(*(.init_array)) 315 PROVIDE_HIDDEN (__init_array_end = .); 316 317 . = ALIGN(4); 318 /* finit data */ 319 PROVIDE_HIDDEN (__fini_array_start = .); 320 KEEP(*(SORT(.fini_array.*))) 321 KEEP(*(.fini_array)) 322 PROVIDE_HIDDEN (__fini_array_end = .); 323 324 KEEP(*(.jcr*)) 325 . = ALIGN(4); 326 327 } > RAM AT> FLASH 328 Image$$ER_TFM_DATA$$RW$$Base = ADDR(.TFM_DATA); 329 Image$$ER_TFM_DATA$$RW$$Limit = ADDR(.TFM_DATA) + SIZEOF(.TFM_DATA); 330 331 /**** PSA RoT DATA end here */ 332 Image$$TFM_PSA_RW_STACK_END$$Base = .; 333 334 .TFM_UNPRIV_CODE : ALIGN(GTZC_FLASH_ALIGN) 335 { 336 *(SFN) 337 *(.text*) 338 339 KEEP(*(.init)) 340 KEEP(*(.fini)) 341 342 /* .ctors */ 343 *crtbegin.o(.ctors) 344 *crtbegin?.o(.ctors) 345 *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) 346 *(SORT(.ctors.*)) 347 *(.ctors) 348 349 /* .dtors */ 350 *crtbegin.o(.dtors) 351 *crtbegin?.o(.dtors) 352 *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) 353 *(SORT(.dtors.*)) 354 *(.dtors) 355 356 *(.rodata*) 357 358 KEEP(*(.eh_frame*)) 359 . = ALIGN(32); 360 } > FLASH 361 Image$$TFM_UNPRIV_CODE$$RO$$Base = ADDR(.TFM_UNPRIV_CODE); 362 Image$$TFM_UNPRIV_CODE$$RO$$Limit = ADDR(.TFM_UNPRIV_CODE) + SIZEOF(.TFM_UNPRIV_CODE); 363 364 /**** APPLICATION RoT RO part (CODE + RODATA) start here */ 365 Image$$TFM_APP_CODE_START$$Base = .; 366 367 .TFM_APP_ROT_LINKER : ALIGN(32) 368 { 369 *tfm_app_rot_partition*:*(.text*) 370 *tfm_app_rot_partition*:*(.rodata*) 371 *(TFM_*_APP-ROT_ATTR_FN) 372 . = ALIGN(32); 373 } > FLASH 374 375 /**** APPLICATION RoT RO part (CODE + RODATA) end here */ 376 Image$$TFM_APP_CODE_END$$Base = .; 377 378 Image$$TFM_APP_ROT_LINKER$$RO$$Base = ADDR(.TFM_APP_ROT_LINKER); 379 Image$$TFM_APP_ROT_LINKER$$RO$$Limit = ADDR(.TFM_APP_ROT_LINKER) + SIZEOF(.TFM_APP_ROT_LINKER); 380 Image$$TFM_APP_ROT_LINKER$$Base = ADDR(.TFM_APP_ROT_LINKER); 381 Image$$TFM_APP_ROT_LINKER$$Limit = ADDR(.TFM_APP_ROT_LINKER) + SIZEOF(.TFM_APP_ROT_LINKER); 382 383 .TFM_BSS : ALIGN(4) 384 { 385 __bss_start__ = .; 386 387 /* The runtime partition placed order is same as load partition */ 388 __partition_runtime_start__ = .; 389 KEEP(*(.bss.part_runtime_priority_lowest)) 390 KEEP(*(.bss.part_runtime_priority_low)) 391 KEEP(*(.bss.part_runtime_priority_normal)) 392 KEEP(*(.bss.part_runtime_priority_high)) 393 __partition_runtime_end__ = .; 394 . = ALIGN(4); 395 396 /* The runtime service placed order is same as load partition */ 397 __service_runtime_start__ = .; 398 KEEP(*(.bss.serv_runtime_priority_lowest)) 399 KEEP(*(.bss.serv_runtime_priority_low)) 400 KEEP(*(.bss.serv_runtime_priority_normal)) 401 KEEP(*(.bss.serv_runtime_priority_high)) 402 __service_runtime_end__ = .; 403 *(.bss*) 404 *(COMMON) 405 . = ALIGN(4); 406 __bss_end__ = .; 407 } > RAM AT> RAM 408 Image$$ER_TFM_DATA$$ZI$$Base = ADDR(.TFM_BSS); 409 Image$$ER_TFM_DATA$$ZI$$Limit = ADDR(.TFM_BSS) + SIZEOF(.TFM_BSS); 410 Image$$ER_PART_RT_POOL$$ZI$$Base = __partition_runtime_start__; 411 Image$$ER_PART_RT_POOL$$ZI$$Limit = __partition_runtime_end__; 412 Image$$ER_SERV_RT_POOL$$ZI$$Base = __service_runtime_start__; 413 Image$$ER_SERV_RT_POOL$$ZI$$Limit = __service_runtime_end__; 414 415 Image$$ER_TFM_DATA$$Base = ADDR(.TFM_DATA); 416 Image$$ER_TFM_DATA$$Limit = ADDR(.TFM_DATA) + SIZEOF(.TFM_DATA) + SIZEOF(.TFM_BSS); 417 418#if defined(PSA_PROXY_SHARED_MEMORY_BASE) 419 /* If a variable defined with __attribute__((section())) keyword the 420 * variable is treated like an initialized variable. To not waste memory 421 * NOLOAD attribute used here. The whole section is zero initialized by 422 * adding section information to .zero.table */ 423 .PSA_PROXY_SHARED_MEMORY (NOLOAD) : ALIGN(4) 424 { 425 KEEP(*(PSA_PROXY_SHARED_MEMORY_SECTION)) 426 . = ALIGN(4); 427 } > PSA_PROXY_SHARED_MEMORY_RAM 428#endif 429 430 /* 431 * Place the CMSE Veneers (containing the SG instruction) after the code, in a 432 * separate 32 bytes aligned region so that the SAU can programmed to just set 433 * this region as Non-Secure Callable. 434 */ 435 .gnu.sgstubs : ALIGN(32) 436 { 437 *(.gnu.sgstubs*) 438 . = ALIGN(32); 439 } > VENEERS AT> VENEERS 440 Load$$LR$$LR_VENEER$$Base = ADDR(.gnu.sgstubs); 441 Load$$LR$$LR_VENEER$$Limit = ADDR(.gnu.sgstubs) + SIZEOF(.gnu.sgstubs); 442 443 Load$$LR$$LR_NS_PARTITION$$Base = NS_PARTITION_START; 444 445#ifdef BL2 446 Load$$LR$$LR_SECONDARY_PARTITION$$Base = SECONDARY_PARTITION_START; 447#endif /* BL2 */ 448 449 PROVIDE(__stack = Image$$ARM_LIB_STACK$$ZI$$Limit); 450} 451