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 FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 2048k 27 RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k 28 SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k 29 SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k 30} 31 32ENTRY(_entry_point) 33 34SECTIONS 35{ 36 /* Second stage bootloader is prepended to the image. It must be 256 bytes big 37 and checksummed. It is usually built by the boot_stage2 target 38 in the Raspberry Pi Pico SDK 39 */ 40 41 .flash_begin : { 42 __flash_binary_start = .; 43 } > FLASH 44 45 .boot2 : { 46 __boot2_start__ = .; 47 KEEP (*(.boot2)) 48 __boot2_end__ = .; 49 } > FLASH 50 51 ASSERT(__boot2_end__ - __boot2_start__ == 256, 52 "ERROR: Pico second stage bootloader must be 256 bytes in size") 53 54 /* The second stage will always enter the image at the start of .text. 55 The debugger will use the ELF entry point, which is the _entry_point 56 symbol if present, otherwise defaults to start of .text. 57 This can be used to transfer control back to the bootrom on debugger 58 launches only, to perform proper flash setup. 59 */ 60 61 .flashtext : { 62 __logical_binary_start = .; 63 KEEP (*(.vectors)) 64 KEEP (*(.binary_info_header)) 65 __binary_info_header_end = .; 66 KEEP (*(.reset)) 67 } 68 69 .rodata : { 70 /* segments not marked as .flashdata are instead pulled into .data (in RAM) to avoid accidental flash accesses */ 71 *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) 72 . = ALIGN(4); 73 } > FLASH 74 75 .ARM.extab : 76 { 77 *(.ARM.extab* .gnu.linkonce.armextab.*) 78 } > FLASH 79 80 __exidx_start = .; 81 .ARM.exidx : 82 { 83 *(.ARM.exidx* .gnu.linkonce.armexidx.*) 84 } > FLASH 85 __exidx_end = .; 86 87 /* Machine inspectable binary information */ 88 . = ALIGN(4); 89 __binary_info_start = .; 90 .binary_info : 91 { 92 KEEP(*(.binary_info.keep.*)) 93 *(.binary_info.*) 94 } > FLASH 95 __binary_info_end = .; 96 . = ALIGN(4); 97 98 /* Vector table goes first in RAM, to avoid large alignment hole */ 99 .ram_vector_table (NOLOAD): { 100 *(.ram_vector_table) 101 } > RAM 102 103 .text : { 104 __ram_text_start__ = .; 105 *(.init) 106 *(.text*) 107 *(.fini) 108 /* Pull all c'tors into .text */ 109 *crtbegin.o(.ctors) 110 *crtbegin?.o(.ctors) 111 *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) 112 *(SORT(.ctors.*)) 113 *(.ctors) 114 /* Followed by destructors */ 115 *crtbegin.o(.dtors) 116 *crtbegin?.o(.dtors) 117 *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) 118 *(SORT(.dtors.*)) 119 *(.dtors) 120 121 *(.eh_frame*) 122 . = ALIGN(4); 123 __ram_text_end__ = .; 124 } > RAM AT> FLASH 125 __ram_text_source__ = LOADADDR(.text); 126 . = ALIGN(4); 127 128 .data : { 129 __data_start__ = .; 130 *(vtable) 131 132 *(.time_critical*) 133 134 . = ALIGN(4); 135 *(.rodata*) 136 . = ALIGN(4); 137 138 *(.data*) 139 140 . = ALIGN(4); 141 *(.after_data.*) 142 . = ALIGN(4); 143 /* preinit data */ 144 PROVIDE_HIDDEN (__mutex_array_start = .); 145 KEEP(*(SORT(.mutex_array.*))) 146 KEEP(*(.mutex_array)) 147 PROVIDE_HIDDEN (__mutex_array_end = .); 148 149 . = ALIGN(4); 150 /* preinit data */ 151 PROVIDE_HIDDEN (__preinit_array_start = .); 152 KEEP(*(SORT(.preinit_array.*))) 153 KEEP(*(.preinit_array)) 154 PROVIDE_HIDDEN (__preinit_array_end = .); 155 156 . = ALIGN(4); 157 /* init data */ 158 PROVIDE_HIDDEN (__init_array_start = .); 159 KEEP(*(SORT(.init_array.*))) 160 KEEP(*(.init_array)) 161 PROVIDE_HIDDEN (__init_array_end = .); 162 163 . = ALIGN(4); 164 /* finit data */ 165 PROVIDE_HIDDEN (__fini_array_start = .); 166 *(SORT(.fini_array.*)) 167 *(.fini_array) 168 PROVIDE_HIDDEN (__fini_array_end = .); 169 170 *(.jcr) 171 . = ALIGN(4); 172 /* All data end */ 173 __data_end__ = .; 174 } > RAM AT> FLASH 175 /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ 176 __etext = LOADADDR(.data); 177 178 .uninitialized_data (NOLOAD): { 179 . = ALIGN(4); 180 *(.uninitialized_data*) 181 } > RAM 182 183 /* Start and end symbols must be word-aligned */ 184 .scratch_x : { 185 __scratch_x_start__ = .; 186 *(.scratch_x.*) 187 . = ALIGN(4); 188 __scratch_x_end__ = .; 189 } > SCRATCH_X AT > FLASH 190 __scratch_x_source__ = LOADADDR(.scratch_x); 191 192 .scratch_y : { 193 __scratch_y_start__ = .; 194 *(.scratch_y.*) 195 . = ALIGN(4); 196 __scratch_y_end__ = .; 197 } > SCRATCH_Y AT > FLASH 198 __scratch_y_source__ = LOADADDR(.scratch_y); 199 200 .bss : { 201 . = ALIGN(4); 202 __bss_start__ = .; 203 *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) 204 *(COMMON) 205 . = ALIGN(4); 206 __bss_end__ = .; 207 } > RAM 208 209 .heap (NOLOAD): 210 { 211 __end__ = .; 212 end = __end__; 213 KEEP(*(.heap*)) 214 __HeapLimit = .; 215 } > RAM 216 217 /* .stack*_dummy section doesn't contains any symbols. It is only 218 * used for linker to calculate size of stack sections, and assign 219 * values to stack symbols later 220 * 221 * stack1 section may be empty/missing if platform_launch_core1 is not used */ 222 223 /* by default we put core 0 stack at the end of scratch Y, so that if core 1 224 * stack is not used then all of SCRATCH_X is free. 225 */ 226 .stack1_dummy (NOLOAD): 227 { 228 *(.stack1*) 229 } > SCRATCH_X 230 .stack_dummy (NOLOAD): 231 { 232 KEEP(*(.stack*)) 233 } > SCRATCH_Y 234 235 .flash_end : { 236 __flash_binary_end = .; 237 } > FLASH 238 239 /* stack limit is poorly named, but historically is maximum heap ptr */ 240 __StackLimit = ORIGIN(RAM) + LENGTH(RAM); 241 __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); 242 __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); 243 __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); 244 __StackBottom = __StackTop - SIZEOF(.stack_dummy); 245 PROVIDE(__stack = __StackTop); 246 247 /* Check if data + heap + stack exceeds RAM limit */ 248 ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") 249 250 ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") 251 /* todo assert on extra code */ 252} 253 254