1/* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright © 2019 Keith Packard 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * 3. Neither the name of the copyright holder nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 33 * OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36/* ---------------------------------------------------------------------------- 37 Stack seal size definition 38 *----------------------------------------------------------------------------*/ 39#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) 40#define __STACKSEAL_SIZE ( 8 ) 41#else 42#define __STACKSEAL_SIZE ( 0 ) 43#endif 44 45/* ---------------------------------------------------------------------------- 46 Memory definition 47 *----------------------------------------------------------------------------*/ 48MEMORY 49{ 50 ROM0 (rx!w) : ORIGIN = S_CODE_START, LENGTH = S_CODE_SIZE + 0x000000 51#if __ROM1_SIZE > 0 52 ROM1 (rx!w) : ORIGIN = __ROM1_BASE, LENGTH = __ROM1_SIZE 53#endif 54#if __ROM2_SIZE > 0 55 ROM2 (rx!w) : ORIGIN = __ROM2_BASE, LENGTH = __ROM2_SIZE 56#endif 57#if __ROM3_SIZE > 0 58 ROM3 (rx!w) : ORIGIN = __ROM3_BASE, LENGTH = __ROM3_SIZE 59#endif 60 61 RAM0 (w!rx) : ORIGIN = S_DATA_START, LENGTH = S_DATA_SIZE + 0x000000 62#if __RAM1_SIZE > 0 63 RAM1 (w!rx) : ORIGIN = __RAM1_BASE, LENGTH = __RAM1_SIZE 64#endif 65#if __RAM2_SIZE > 0 66 RAM2 (w!rx) : ORIGIN = __RAM2_BASE, LENGTH = __RAM2_SIZE 67#endif 68#if __RAM3_SIZE > 0 69 RAM3 (w!rx) : ORIGIN = __RAM3_BASE, LENGTH = __RAM3_SIZE 70#endif 71} 72 73ENTRY(Reset_Handler) 74 75PHDRS 76{ 77 text PT_LOAD; 78 ram PT_LOAD; 79 ram_init PT_LOAD; 80 tls PT_TLS; 81} 82 83SECTIONS 84{ 85 .init : { 86 KEEP (*(.vectors)) 87 KEEP (*(.text.init.enter)) 88 KEEP (*(.data.init.enter)) 89 KEEP (*(SORT_BY_NAME(.init) SORT_BY_NAME(.init.*))) 90 } >ROM0 AT>ROM0 :text 91 92 .text : { 93 94 /* code */ 95 *(.text.unlikely .text.unlikely.*) 96 *(.text.startup .text.startup.*) 97 *(.text .text.* .opd .opd.*) 98 *(.gnu.linkonce.t.*) 99 KEEP (*(.fini .fini.*)) 100 __text_end = .; 101 102 PROVIDE (__etext = __text_end); 103 PROVIDE (_etext = __text_end); 104 PROVIDE (etext = __text_end); 105 106 *(.gnu.linkonce.r.*) 107 108 109 110 *(.srodata.cst16) 111 *(.srodata.cst8) 112 *(.srodata.cst4) 113 *(.srodata.cst2) 114 *(.srodata .srodata.*) 115 *(.data.rel.ro .data.rel.ro.*) 116 *(.got .got.*) 117 118 /* Need to pre-align so that the symbols come after padding */ 119 . = ALIGN(8); 120 121 /* lists of constructors and destructors */ 122 PROVIDE_HIDDEN ( __preinit_array_start = . ); 123 KEEP (*(.preinit_array)) 124 PROVIDE_HIDDEN ( __preinit_array_end = . ); 125 126 PROVIDE_HIDDEN ( __init_array_start = . ); 127 KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) 128 KEEP (*(.init_array .ctors)) 129 PROVIDE_HIDDEN ( __init_array_end = . ); 130 131 PROVIDE_HIDDEN ( __fini_array_start = . ); 132 KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) 133 KEEP (*(.fini_array .dtors)) 134 PROVIDE_HIDDEN ( __fini_array_end = . ); 135 136 } >ROM0 AT>ROM0 :text 137 138#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) 139 .veneers : 140 { 141 . = ALIGN(32); 142 KEEP(*(.gnu.sgstubs)) 143 } > ROM0 AT>ROM0 :text 144#endif 145 146 .toc : { 147 *(.toc .toc.*) 148 } >ROM0 AT>ROM0 :text 149 150 /* additional sections when compiling with C++ exception support */ 151 152 .except_ordered : { 153 *(.gcc_except_table *.gcc_except_table.*) 154 KEEP (*(.eh_frame .eh_frame.*)) 155 *(.ARM.extab* .gnu.linkonce.armextab.*) 156 } >ROM0 AT>ROM0 :text 157 158 .except_unordered : { 159 . = ALIGN(8); 160 161 PROVIDE(__exidx_start = .); 162 *(.ARM.exidx*) 163 PROVIDE(__exidx_end = .); 164 } >ROM0 AT>ROM0 :text 165 166 167 /* 168 * Data values which are preserved across reset 169 */ 170 .preserve (NOLOAD) : { 171 PROVIDE(__preserve_start__ = .); 172 KEEP(*(SORT_BY_NAME(.preserve.*))) 173 KEEP(*(.preserve)) 174 PROVIDE(__preserve_end__ = .); 175 } >RAM0 AT>RAM0 :ram 176 177 .data : { 178 *(.data .data.*) 179 *(.gnu.linkonce.d.*) 180 181 /* read-only data */ 182 *(.rdata) 183 *(.rodata .rodata.*) 184 185 /* Need to pre-align so that the symbols come after padding */ 186 . = ALIGN(8); 187 188 PROVIDE( __global_pointer$ = . + 0x800 ); 189 *(.sdata .sdata.* .sdata2.*) 190 *(.gnu.linkonce.s.*) 191 } >RAM0 AT>ROM0 :ram_init 192 PROVIDE(__data_start = ADDR(.data)); 193 PROVIDE(__data_source = LOADADDR(.data)); 194 195 /* Thread local initialized data. This gets 196 * space allocated as it is expected to be placed 197 * in ram to be used as a template for TLS data blocks 198 * allocated at runtime. We're slightly abusing that 199 * by placing the data in flash where it will be copied 200 * into the allocate ram addresses by the existing 201 * data initialization code in crt0 202 */ 203 .tdata : { 204 *(.tdata .tdata.* .gnu.linkonce.td.*) 205 PROVIDE(__data_end = .); 206 PROVIDE(__tdata_end = .); 207 } >RAM0 AT>ROM0 :tls :ram_init 208 PROVIDE( __tls_base = ADDR(.tdata)); 209 PROVIDE( __tdata_start = ADDR(.tdata)); 210 PROVIDE( __tdata_source = LOADADDR(.tdata) ); 211 PROVIDE( __tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) ); 212 PROVIDE( __data_source_end = __tdata_source_end ); 213 PROVIDE( __tdata_size = SIZEOF(.tdata) ); 214 PROVIDE( __tls_align = MAX(ALIGNOF(.tdata),ALIGNOF(.tbss)) ); 215 216 PROVIDE( __edata = __data_end ); 217 PROVIDE( _edata = __data_end ); 218 PROVIDE( edata = __data_end ); 219 PROVIDE( __data_size = __data_end - __data_start ); 220 PROVIDE( __data_source_size = __data_source_end - __data_source ); 221 222 .tbss (NOLOAD) : { 223 *(.tbss .tbss.* .gnu.linkonce.tb.*) 224 *(.tcommon) 225 PROVIDE( __tls_end = . ); 226 PROVIDE( __tbss_end = . ); 227 } >RAM0 AT>RAM0 :tls :ram 228 PROVIDE( __bss_start = ADDR(.tbss)); 229 PROVIDE( __tbss_start = ADDR(.tbss)); 230 PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) ); 231 PROVIDE( __tbss_size = SIZEOF(.tbss) ); 232 PROVIDE( __tls_size = __tls_end - __tls_base ); 233 PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); 234 PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); 235 PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) ); 236 237 /* 238 * The linker special cases .tbss segments which are 239 * identified as segments which are not loaded and are 240 * thread_local. 241 * 242 * For these segments, the linker does not advance 'dot' 243 * across them. We actually need memory allocated for tbss, 244 * so we create a special segment here just to make room 245 */ 246 /* 247 .tbss_space (NOLOAD) : { 248 . = ADDR(.tbss); 249 . = . + SIZEOF(.tbss); 250 } >RAM0 AT>RAM0 :ram 251 */ 252 253 .bss (NOLOAD) : { 254 *(.sbss*) 255 *(.gnu.linkonce.sb.*) 256 *(.bss .bss.*) 257 *(.gnu.linkonce.b.*) 258 *(COMMON) 259 260 /* Align the heap */ 261 . = ALIGN(8); 262 __bss_end = .; 263 } >RAM0 AT>RAM0 :ram 264 PROVIDE( __non_tls_bss_start = ADDR(.bss) ); 265 PROVIDE( __end = __bss_end ); 266 PROVIDE( _end = __bss_end ); 267 PROVIDE( end = __bss_end ); 268 PROVIDE( __bss_size = __bss_end - __bss_start ); 269 270 /* Make the rest of memory available for heap storage */ 271 PROVIDE (__heap_start = __end); 272#ifdef HEAP_SIZE 273 PROVIDE (__heap_end = __heap_start + HEAP_SIZE); 274 PROVIDE (__heap_size = HEAP_SIZE); 275#else 276 PROVIDE (__heap_end = __stack - STACK_SIZE); 277 PROVIDE (__heap_size = __heap_end - __heap_start); 278#endif 279 .heap (NOLOAD) : { 280 . += __heap_size; 281 } >RAM0 :ram 282 283 /* Define a stack region to make sure it fits in memory */ 284 PROVIDE(__stack = ORIGIN(RAM0) + LENGTH(RAM0) - __STACKSEAL_SIZE); 285 PROVIDE(__stack_limit = __stack - STACK_SIZE); 286 .stack (__stack_limit) (NOLOAD) : { 287 . += STACK_SIZE; 288 } >RAM0 :ram 289 290#if __STACKSEAL_SIZE > 0 291 PROVIDE(__stack_seal = __stack); 292 .stackseal (__stack) (NOLOAD) : 293 { 294 . += __STACKSEAL_SIZE; 295 } >RAM0 :ram 296#endif 297 298 /* Throw away C++ exception handling information */ 299 300 /* 301 302 /DISCARD/ : { 303 *(.note .note.*) 304 *(.eh_frame .eh_frame.*) 305 *(.ARM.extab* .gnu.linkonce.armextab.*) 306 *(.ARM.exidx*) 307 } 308 309 */ 310 311 /* Stabs debugging sections. */ 312 .stab 0 : { *(.stab) } 313 .stabstr 0 : { *(.stabstr) } 314 .stab.excl 0 : { *(.stab.excl) } 315 .stab.exclstr 0 : { *(.stab.exclstr) } 316 .stab.index 0 : { *(.stab.index) } 317 .stab.indexstr 0 : { *(.stab.indexstr) } 318 .comment 0 : { *(.comment) } 319 .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } 320 /* DWARF debug sections. 321 Symbols in the DWARF debugging sections are relative to the beginning 322 of the section so we begin them at 0. */ 323 /* DWARF 1. */ 324 .debug 0 : { *(.debug) } 325 .line 0 : { *(.line) } 326 /* GNU DWARF 1 extensions. */ 327 .debug_srcinfo 0 : { *(.debug_srcinfo) } 328 .debug_sfnames 0 : { *(.debug_sfnames) } 329 /* DWARF 1.1 and DWARF 2. */ 330 .debug_aranges 0 : { *(.debug_aranges) } 331 .debug_pubnames 0 : { *(.debug_pubnames) } 332 /* DWARF 2. */ 333 .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 334 .debug_abbrev 0 : { *(.debug_abbrev) } 335 .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } 336 .debug_frame 0 : { *(.debug_frame) } 337 .debug_str 0 : { *(.debug_str) } 338 .debug_loc 0 : { *(.debug_loc) } 339 .debug_macinfo 0 : { *(.debug_macinfo) } 340 /* SGI/MIPS DWARF 2 extensions. */ 341 .debug_weaknames 0 : { *(.debug_weaknames) } 342 .debug_funcnames 0 : { *(.debug_funcnames) } 343 .debug_typenames 0 : { *(.debug_typenames) } 344 .debug_varnames 0 : { *(.debug_varnames) } 345 /* DWARF 3. */ 346 .debug_pubtypes 0 : { *(.debug_pubtypes) } 347 .debug_ranges 0 : { *(.debug_ranges) } 348 /* DWARF 5. */ 349 .debug_addr 0 : { *(.debug_addr) } 350 .debug_line_str 0 : { *(.debug_line_str) } 351 .debug_loclists 0 : { *(.debug_loclists) } 352 .debug_macro 0 : { *(.debug_macro) } 353 .debug_names 0 : { *(.debug_names) } 354 .debug_rnglists 0 : { *(.debug_rnglists) } 355 .debug_str_offsets 0 : { *(.debug_str_offsets) } 356 .debug_sup 0 : { *(.debug_sup) } 357 .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } 358} 359/* 360 * Check that sections that are copied from flash to RAM have matching 361 * padding, so that a single memcpy() of __data_size copies the correct bytes. 362 */ 363ASSERT( __data_size == __data_source_size, 364 "ERROR: .data/.tdata flash size does not match RAM size"); 365