1/* 2 * Copyright 2020 ETH Zurich 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 * SPDX-License-Identifier: Apache-2.0 17 * Author: Robert Balas (balasr@iis.ee.ethz.ch) 18 */ 19 20OUTPUT_ARCH(riscv) 21ENTRY(_start) 22MEMORY 23{ 24 L2 : ORIGIN = 0x1c000004, LENGTH = 0x0007fffc 25 L2_aliased : ORIGIN = 0x00000004, LENGTH = 0x00003ffc 26} 27 28/* 29 * This linker script try to put FC data in L2 private bank0 and FC code 30 * in L2 private bank1 to avoid contention between FC code and data 31 * as FC has no instruction cache and is so often accessing L2 to 32 * get instructions. Everything can be shifted in case one bank is full. 33 * 34 * Cluster code and initialized data are put in shared banks to not polute 35 * private banks which are quite small, and also avoid contentions between 36 * cluster cache refill and FC. 37 */ 38 39 40SECTIONS 41{ 42 43 PROVIDE(__boot_address = 0x1c008080); 44 /* stack and heap related settings */ 45 __stack_size = DEFINED(__stack_size) ? __stack_size : 0x800; 46 PROVIDE(__stack_size = __stack_size); 47 /* __heap_size = DEFINED(__heap_size) ? __heap_size : 0x400; */ 48 __heap_size = 0x06000; 49 PROVIDE(__heap_size = __heap_size); 50 51 /* 52 * L2 PRIVATE BANK0 53 * 54 * Contains FC tiny data and code 55 */ 56 57 /* This section is for tiny FC data which benefits 58 * from the alias at 0 59 */ 60 /* TODO: what do we really want to put here when we have the gp */ 61 .data_tiny_fc : ALIGN(4) 62 { 63 *(.data_tiny_fc) 64 *(.data_tiny_fc.*) 65 } > L2_aliased AT> L2 66 67 68 /* text */ 69 .init : ALIGN(4) 70 { 71 KEEP( *(.init) ) 72 } > L2 73 74 .vectors MAX(0x1c000800, ALIGN(256)) : /* lets leak the first 2k free for now "half zero page" */ 75 { 76 __irq_vector_base = .; 77 __vector_start = .; 78 KEEP(*(.vectors)) 79 } > L2 80 81 .text __boot_address : 82 { 83 _stext = .; 84 *(.text.start) 85 *(.text) 86 *(.text.*) 87 _etext = .; /* man 3 end: first addr after text */ 88 *(.lit) 89 *(.shdata) 90 _endtext = .; 91 . = ALIGN(4); 92 93 /* section information for finsh shell */ 94 . = ALIGN(4); 95 __fsymtab_start = .; 96 KEEP(*(FSymTab)) 97 __fsymtab_end = .; 98 . = ALIGN(4); 99 __vsymtab_start = .; 100 KEEP(*(VSymTab)) 101 __vsymtab_end = .; 102 . = ALIGN(4); 103 104 /* section information for initial. */ 105 . = ALIGN(4); 106 __rt_init_start = .; 107 KEEP(*(SORT(.rti_fn*))) 108 __rt_init_end = .; 109 . = ALIGN(4); 110 111 /* section information for utest */ 112 . = ALIGN(4); 113 __rt_utest_tc_tab_start = .; 114 KEEP(*(UtestTcTab)) 115 __rt_utest_tc_tab_end = .; 116 } > L2 117 118 .fini : ALIGN(4) 119 { 120 KEEP( *(.fini) ) 121 } > L2 122 123 124 __l2_priv0_end = ALIGN(4); 125 126 127 /* 128 * L2 PRIVATE BANK1 129 * 130 * Contains FC data 131 */ 132 133 134 /* make sure we start filling fc data into the correct bank */ 135 /* read-only sections */ 136 .rodata MAX(0x1c008000, ALIGN(4)) : 137 { 138 *(.rodata .rodata.* .gnu.linkonce.r.*) 139 } > L2 140 .rodata1 : 141 { 142 *(.rodata1) 143 } > L2 144 145 146 .boot : ALIGN(4) 147 { 148 *(.boot) 149 *(.boot.data) 150 } > L2 151 152 /* .got : ALIGN(4) */ 153 /* { */ 154 /* *(.got.plt) * (.igot.plt) *(.got) *(.igot) */ 155 /* } > L2 */ 156 157 .talias : 158 { 159 } > L2 160 161 162 /* gcc language agnostic exception related sections (try-catch-finally) */ 163 .eh_frame_hdr : 164 { 165 *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) 166 } > L2 167 .eh_frame : ONLY_IF_RO 168 { 169 KEEP (*(.eh_frame)) *(.eh_frame.*) 170 } > L2 171 .gcc_except_table : ONLY_IF_RO 172 { 173 *(.gcc_except_table .gcc_except_table.*) 174 } > L2 175 .gnu_extab : ONLY_IF_RO 176 { 177 *(.gnu_extab*) 178 } > L2 179 180 181 /* Exception handling */ 182 .eh_frame : ONLY_IF_RW 183 { 184 KEEP (*(.eh_frame)) *(.eh_frame.*) 185 } > L2 186 .gnu_extab : ONLY_IF_RW 187 { 188 *(.gnu_extab) 189 } > L2 190 .gcc_except_table : ONLY_IF_RW 191 { 192 *(.gcc_except_table .gcc_except_table.*) 193 } > L2 194 .exception_ranges : ONLY_IF_RW 195 { 196 *(.exception_ranges .exception_ranges*) 197 } > L2 198 199 200 /* Thread Local Storage sections */ 201 .tdata : 202 { 203 PROVIDE_HIDDEN (__tdata_start = .); 204 *(.tdata .tdata.* .gnu.linkonce.td.*) 205 } > L2 206 .tbss : 207 { 208 *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) 209 } > L2 210 211 212 /* constructors / destructors */ 213 .preinit_array : ALIGN(4) 214 { 215 PROVIDE_HIDDEN (__preinit_array_start = .); 216 KEEP (*(.preinit_array)) 217 PROVIDE_HIDDEN (__preinit_array_end = .); 218 } > L2 219 220 .init_array : ALIGN(4) 221 { 222 PROVIDE_HIDDEN (__init_array_start = .); 223 KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) 224 KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) 225 PROVIDE_HIDDEN (__init_array_end = .); 226 } > L2 227 228 .fini_array : ALIGN(4) 229 { 230 PROVIDE_HIDDEN (__fini_array_start = .); 231 KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) 232 KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) 233 PROVIDE_HIDDEN (__fini_array_end = .); 234 } > L2 235 236 .ctors : 237 { 238 /* gcc uses crtbegin.o to find the start of 239 the constructors, so we make sure it is 240 first. Because this is a wildcard, it 241 doesn't matter if the user does not 242 actually link against crtbegin.o; the 243 linker won't look for a file to match a 244 wildcard. The wildcard also means that it 245 doesn't matter which directory crtbegin.o 246 is in. */ 247 KEEP (*crtbegin.o(.ctors)) 248 KEEP (*crtbegin?.o(.ctors)) 249 /* We don't want to include the .ctor section from 250 the crtend.o file until after the sorted ctors. 251 The .ctor section from the crtend file contains the 252 end of ctors marker and it must be last */ 253 KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) 254 KEEP (*(SORT(.ctors.*))) 255 KEEP (*(.ctors)) 256 } > L2 257 258 .dtors : 259 { 260 KEEP (*crtbegin.o(.dtors)) 261 KEEP (*crtbegin?.o(.dtors)) 262 KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) 263 KEEP (*(SORT(.dtors.*))) 264 KEEP (*(.dtors)) 265 } > L2 266 267 268 /* Open MP */ 269 .gnu.offload_funcs : ALIGN(4) 270 { 271 KEEP(*(.gnu.offload_funcs)) 272 } > L2 273 274 275 .gnu.offload_vars : ALIGN(4) 276 { 277 KEEP(*(.gnu.offload_vars)) 278 } > L2 279 280 281 .data : ALIGN(4) 282 { 283 sdata = .; 284 _sdata = .; 285 __data_begin = .; 286 *(.data_fc) 287 *(.data_fc.*) 288 *(.data); 289 *(.data.*) 290 __sdata_begin = .; 291 *(.sdata); 292 *(.sdata.*) 293 *(.sdata2.*) /* FreeRTOS xISRStackTop, __global_impure_ptr */ 294 *(.heapl2ram) 295 *(.fcTcdm) 296 *(.fcTcdm.*) 297 *(.fcTcdm_g) 298 *(.fcTcdm_g.*) 299 . = ALIGN(4); 300 edata = .; 301 _edata = .; /* man 3 end: first addr after data */ 302 } > L2 303 304 305 .bss : ALIGN(8) 306 { 307 _bss_start = .; 308 __bss_start = .; 309 *(.shbss) /* don't even know where this is from */ 310 *(.bss) 311 *(.bss.*) 312 *(.sbss) 313 *(.sbss.*) 314 *(COMMON) 315 . = ALIGN(4); 316 __bss_end = .; 317 _bss_end = .; 318 _end = .; /* man 3 end: first addr after bss */ 319 } > L2 320 321 322 /* The compiler uses this to access data in the .sdata, .data, .sbss and .bss 323 sections with fewer instructions (relaxation). This reduces code size. */ 324 PROVIDE(__global_pointer$ = MIN(__sdata_begin + 0x800, 325 MAX(__data_begin + 0x800, __bss_end - 0x800))); 326 327 .heap : ALIGN(16) 328 { 329 __heap_start = .; 330 . += __heap_size; 331 /* __heap_end = .; */ /* Will be automatically filled by the ucHeap array */ 332 /* . = ALIGN(16); */ 333 KEEP(*(.heap)) 334 __heap_end = .; 335 ASSERT((__heap_start + __heap_size < __heap_end), "Error (Linkerscript): Heap is too large"); 336 } > L2 337 338 339 .stack : ALIGN(16) 340 { 341 stack_start = .; 342 __stack_bottom = .; 343 . += __stack_size; 344 __stack_top = .; 345 PROVIDE( __rt_rvstack = . ); 346 __freertos_irq_stack_top = .; /* sytem stack */ 347 stack = .; 348 } > L2 349 350 351 __l2_priv1_end = ALIGN(4); 352 353 354 /* 355 * L2 SHARED BANKS 356 * 357 * Contains other data such as peripheral data and cluster code and data 358 */ 359 360 .l2_data MAX(0x1c010000, ALIGN(4)) : 361 { 362 __cluster_text_start = .; 363 *(.cluster.text) 364 *(.cluster.text.*) 365 . = ALIGN(4); 366 __cluster_text_end = .; 367 *(.l2_data) 368 *(.l2_data.*) 369 *(.data_fc_shared) 370 *(.data_fc_shared.*) 371 . = ALIGN(4); 372 } > L2 373 374 __l2_shared_end = LOADADDR(.l2_data) + SIZEOF(.l2_data); 375 376} 377