1/* Based on GCC ARM embedded samples. 2 Defines the following symbols for use by code: 3 __exidx_start 4 __exidx_end 5 __etext 6 __data_start__ 7 __preinit_array_start 8 __preinit_array_end 9 __init_array_start 10 __init_array_end 11 __fini_array_start 12 __fini_array_end 13 __data_end__ 14 __bss_start__ 15 __bss_end__ 16 __end__ 17 end 18 __HeapLimit 19 __StackLimit 20 __StackTop 21 __stack (== StackTop) 22*/ 23 24MEMORY 25{ 26 RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k 27 SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k 28 SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k 29} 30 31ENTRY(_entry_point) 32 33SECTIONS 34{ 35 /* Note in NO_FLASH builds the entry point for both the bootrom, and debugger 36 entry (ELF entry point), are *first* in the image, and the vector table 37 follows immediately afterward. This is because the bootrom enters RAM 38 binaries directly at their lowest address (preferring main RAM over XIP 39 cache-as-SRAM if both are used). 40 */ 41 42 .text : { 43 __logical_binary_start = .; 44 __reset_start = .; 45 KEEP (*(.reset)) 46 __reset_end = .; 47 KEEP (*(.binary_info_header)) 48 __binary_info_header_end = .; 49 KEEP (*(.embedded_block)) 50 __embedded_block_end = .; 51 . = ALIGN(256); 52 KEEP (*(.vectors)) 53 *(.time_critical*) 54 *(.text*) 55 . = ALIGN(4); 56 *(.init) 57 *(.fini) 58 /* Pull all c'tors into .text */ 59 *crtbegin.o(.ctors) 60 *crtbegin?.o(.ctors) 61 *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) 62 *(SORT(.ctors.*)) 63 *(.ctors) 64 /* Followed by destructors */ 65 *crtbegin.o(.dtors) 66 *crtbegin?.o(.dtors) 67 *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) 68 *(SORT(.dtors.*)) 69 *(.dtors) 70 71 *(.eh_frame*) 72 } > RAM 73 74 .rodata : { 75 . = ALIGN(4); 76 *(.rodata*) 77 . = ALIGN(4); 78 *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) 79 . = ALIGN(4); 80 } > RAM 81 82 .ARM.extab : 83 { 84 *(.ARM.extab* .gnu.linkonce.armextab.*) 85 } > RAM 86 87 __exidx_start = .; 88 .ARM.exidx : 89 { 90 *(.ARM.exidx* .gnu.linkonce.armexidx.*) 91 } > RAM 92 __exidx_end = .; 93 94 /* Machine inspectable binary information */ 95 . = ALIGN(4); 96 __binary_info_start = .; 97 .binary_info : 98 { 99 KEEP(*(.binary_info.keep.*)) 100 *(.binary_info.*) 101 } > RAM 102 __binary_info_end = .; 103 . = ALIGN(4); 104 105 .data : { 106 __data_start__ = .; 107 *(vtable) 108 *(.data*) 109 110 . = ALIGN(4); 111 *(.after_data.*) 112 . = ALIGN(4); 113 /* preinit data */ 114 PROVIDE_HIDDEN (__mutex_array_start = .); 115 KEEP(*(SORT(.mutex_array.*))) 116 KEEP(*(.mutex_array)) 117 PROVIDE_HIDDEN (__mutex_array_end = .); 118 119 . = ALIGN(4); 120 /* preinit data */ 121 PROVIDE_HIDDEN (__preinit_array_start = .); 122 KEEP(*(SORT(.preinit_array.*))) 123 KEEP(*(.preinit_array)) 124 PROVIDE_HIDDEN (__preinit_array_end = .); 125 126 . = ALIGN(4); 127 /* init data */ 128 PROVIDE_HIDDEN (__init_array_start = .); 129 KEEP(*(SORT(.init_array.*))) 130 KEEP(*(.init_array)) 131 PROVIDE_HIDDEN (__init_array_end = .); 132 133 . = ALIGN(4); 134 /* finit data */ 135 PROVIDE_HIDDEN (__fini_array_start = .); 136 *(SORT(.fini_array.*)) 137 *(.fini_array) 138 PROVIDE_HIDDEN (__fini_array_end = .); 139 140 *(.jcr) 141 . = ALIGN(4); 142 } > RAM 143 144 .tdata : { 145 . = ALIGN(4); 146 *(.tdata .tdata.* .gnu.linkonce.td.*) 147 /* All data end */ 148 __tdata_end = .; 149 } > RAM 150 PROVIDE(__data_end__ = .); 151 152 .uninitialized_data (NOLOAD): { 153 . = ALIGN(4); 154 *(.uninitialized_data*) 155 } > RAM 156 /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ 157 __etext = LOADADDR(.data); 158 159 .tbss (NOLOAD) : { 160 . = ALIGN(4); 161 __bss_start__ = .; 162 __tls_base = .; 163 *(.tbss .tbss.* .gnu.linkonce.tb.*) 164 *(.tcommon) 165 166 __tls_end = .; 167 } > RAM 168 169 .bss (NOLOAD) : { 170 . = ALIGN(4); 171 __tbss_end = .; 172 173 *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) 174 *(COMMON) 175 . = ALIGN(4); 176 __bss_end__ = .; 177 } > RAM 178 179 .heap (NOLOAD): 180 { 181 __end__ = .; 182 end = __end__; 183 KEEP(*(.heap*)) 184 } > RAM 185 /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however 186 to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */ 187 __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); 188 189 /* Start and end symbols must be word-aligned */ 190 .scratch_x : { 191 __scratch_x_start__ = .; 192 *(.scratch_x.*) 193 . = ALIGN(4); 194 __scratch_x_end__ = .; 195 } > SCRATCH_X 196 __scratch_x_source__ = LOADADDR(.scratch_x); 197 198 .scratch_y : { 199 __scratch_y_start__ = .; 200 *(.scratch_y.*) 201 . = ALIGN(4); 202 __scratch_y_end__ = .; 203 } > SCRATCH_Y 204 __scratch_y_source__ = LOADADDR(.scratch_y); 205 206 /* .stack*_dummy section doesn't contains any symbols. It is only 207 * used for linker to calculate size of stack sections, and assign 208 * values to stack symbols later 209 * 210 * stack1 section may be empty/missing if platform_launch_core1 is not used */ 211 212 /* by default we put core 0 stack at the end of scratch Y, so that if core 1 213 * stack is not used then all of SCRATCH_X is free. 214 */ 215 .stack1_dummy (NOLOAD): 216 { 217 *(.stack1*) 218 } > SCRATCH_X 219 .stack_dummy (NOLOAD): 220 { 221 KEEP(*(.stack*)) 222 } > SCRATCH_Y 223 224 /* stack limit is poorly named, but historically is maximum heap ptr */ 225 __StackLimit = ORIGIN(RAM) + LENGTH(RAM); 226 __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); 227 __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); 228 __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); 229 __StackBottom = __StackTop - SIZEOF(.stack_dummy); 230 PROVIDE(__stack = __StackTop); 231 232 /* picolibc and LLVM */ 233 PROVIDE (__heap_start = __end__); 234 PROVIDE (__heap_end = __HeapLimit); 235 PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); 236 PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); 237 PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); 238 239 /* llvm-libc */ 240 PROVIDE (_end = __end__); 241 PROVIDE (__llvm_libc_heap_limit = __HeapLimit); 242 243 /* Check if data + heap + stack exceeds RAM limit */ 244 ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") 245 246 ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") 247 /* todo assert on extra code */ 248} 249 250