kendryte.ld
1 /* 2 * The MEMORY command describes the location and size of blocks of memory 3 * in the target. You can use it to describe which memory regions may be 4 * used by the linker, and which memory regions it must avoid. 5 */ 6 MEMORY 7 { 8 /* 9 * Memory with CPU cache. 10 *6M CPU SRAM 11 */ 12 ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = (6 * 1024 * 1024) 13 /* 14 * Memory without CPU cache 15 * 6M CPU SRAM 16 */ 17 ram_nocache (wxa!ri) : ORIGIN = 0x40000000, LENGTH = (6 * 1024 * 1024) 18 } 19 20 PROVIDE( _rom_start = ORIGIN(rom) ); 21 PROVIDE( _rom_end = ORIGIN(rom) + LENGTH(rom) ); 22 PROVIDE( _ram_start = ORIGIN(ram) ); 23 PROVIDE( _ram_end = ORIGIN(ram) + LENGTH(ram) ); 24 PROVIDE( _io_start = 0x40000000 ); 25 PROVIDE( _io_end = _io_start + LENGTH(ram) ); 26 PROVIDE( _stack_size = 1 << 15 ); 27 28 29 /* 30 * The OUTPUT_ARCH command specifies the machine architecture where the 31 * argument is one of the names used in the Kendryte library. 32 */ 33 OUTPUT_ARCH( "riscv" ) 34 35 /* 36 * The ENTRY command specifies the entry point (ie. first instruction to 37 * execute). The symbol _start is defined in crt0.S 38 */ 39 ENTRY(_start) 40 41 /* 42 * The GROUP command is special since the listed archives will be 43 * searched repeatedly until there are no new undefined references. We 44 * need this since -lc depends on -lgloss and -lgloss depends on -lc. I 45 * thought gcc would automatically include -lgcc when needed, but 46 * in this file includes it explicitly here and I was seeing link errors 47 * without it. 48 */ 49 /* GROUP( -lc -lgloss -lgcc ) */ 50 51 /* 52 * The linker only pays attention to the PHDRS command when generating 53 * an ELF output file. In other cases, the linker will simply ignore PHDRS. 54 */ 55 PHDRS 56 { 57 ram_ro PT_LOAD; 58 ram_init PT_LOAD; 59 ram PT_NULL; 60 } 61 62 /* 63 * This is where we specify how the input sections map to output 64 * sections. 65 */ 66 SECTIONS 67 { 68 /* Program code segment, also known as a text segment */ 69 .text : 70 { 71 PROVIDE( _text = ABSOLUTE(.) ); 72 /* Initialization code segment */ 73 KEEP( *(.text.start) ) 74 KEEP( *(.text.systick) ) 75 *(.text.unlikely .text.unlikely.*) 76 *(.text.startup .text.startup.*) 77 /* Normal code segment */ 78 *(.text .text.*) 79 *(.gnu.linkonce.t.*) 80 81 . = ALIGN(8); 82 PROVIDE( _etext = ABSOLUTE(.) ); 83 } >ram AT>ram :ram_ro 84 85 /* Read-only data segment */ 86 .rodata : 87 { 88 *(.rdata) 89 *(.rodata .rodata.*) 90 *(.gnu.linkonce.r.*) 91 } >ram AT>ram :ram_ro 92 93 . = ALIGN(8); 94 95 /* Exception handling */ 96 .eh_frame : 97 { 98 KEEP (*(.eh_frame)) *(.eh_frame.*) 99 . = ALIGN(8); 100 } >ram AT>ram :ram_ro 101 .gnu_extab : { *(.gnu_extab) } >ram AT>ram :ram_ro 102 .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } >ram AT>ram :ram_ro 103 .exception_ranges : { *(.exception_ranges .exception_ranges*) } >ram AT>ram :ram_ro 104 105 /* Init array and fini array */ 106 .preinit_array : 107 { 108 PROVIDE_HIDDEN (__preinit_array_start = .); 109 KEEP (*(.preinit_array)) 110 PROVIDE_HIDDEN (__preinit_array_end = .); 111 } >ram AT>ram :ram_ro 112 113 .init_array : 114 { 115 PROVIDE_HIDDEN (__init_array_start = .); 116 KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) 117 KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) 118 PROVIDE_HIDDEN (__init_array_end = .); 119 } >ram AT>ram :ram_ro 120 121 .fini_array : 122 { 123 PROVIDE_HIDDEN (__fini_array_start = .); 124 KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) 125 KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) 126 PROVIDE_HIDDEN (__fini_array_end = .); 127 } >ram AT>ram :ram_ro 128 129 .ctors : 130 { 131 /* gcc uses crtbegin.o to find the start of 132 the constructors, so we make sure it is 133 first. Because this is a wildcard, it 134 doesn't matter if the user does not 135 actually link against crtbegin.o; the 136 linker won't look for a file to match a 137 wildcard. The wildcard also means that it 138 doesn't matter which directory crtbegin.o 139 is in. */ 140 KEEP (*crtbegin.o(.ctors)) 141 KEEP (*crtbegin?.o(.ctors)) 142 /* We don't want to include the .ctor section from 143 the crtend.o file until after the sorted ctors. 144 The .ctor section from the crtend file contains the 145 end of ctors marker and it must be last */ 146 KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) 147 KEEP (*(SORT(.ctors.*))) 148 KEEP (*(.ctors)) 149 } >ram AT>ram :ram_ro 150 151 .dtors : 152 { 153 KEEP (*crtbegin.o(.dtors)) 154 KEEP (*crtbegin?.o(.dtors)) 155 KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) 156 KEEP (*(SORT(.dtors.*))) 157 KEEP (*(.dtors)) 158 } >ram AT>ram :ram_ro 159 160 . = ALIGN(8); 161 162 .lalign : 163 { 164 . = ALIGN(8); 165 PROVIDE( _data_lma = . ); 166 } >ram AT>ram :ram_ro 167 168 .dalign : 169 { 170 . = ALIGN(8); 171 PROVIDE( _data = . ); 172 } >ram AT>ram :ram_init 173 174 . = ALIGN(8); 175 176 /* .data, .sdata and .srodata segment */ 177 .data : 178 { 179 /* Writable data segment (.data segment) */ 180 *(.data .data.*) 181 *(.gnu.linkonce.d.*) 182 /* Have _gp point to middle of sdata/sbss to maximize displacement range */ 183 . = ALIGN(8); 184 PROVIDE( __global_pointer$ = ABSOLUTE(.) + 0x800); 185 /* Writable small data segment (.sdata segment) */ 186 *(.sdata .sdata.*) 187 *(.gnu.linkonce.s.*) 188 /* Read-only small data segment (.srodata segment) */ 189 . = ALIGN(8); 190 *(.srodata.cst16) 191 *(.srodata.cst8) 192 *(.srodata.cst4) 193 *(.srodata.cst2) 194 *(.srodata .srodata.*) 195 /* Align _edata to cache line size */ 196 . = ALIGN(64); 197 PROVIDE( _edata = ABSOLUTE(.) ); 198 } >ram AT>ram :ram_init 199 200 /* .bss and .sbss segment */ 201 .bss : 202 { 203 PROVIDE( _bss = ABSOLUTE(.) ); 204 /* Writable uninitialized small data segment (.sbss segment)*/ 205 *(.sbss .sbss.*) 206 *(.gnu.linkonce.sb.*) 207 *(.scommon) 208 /* Uninitialized writeable data section (.bss segment)*/ 209 *(.bss .bss.*) 210 *(.gnu.linkonce.b.*) 211 *(COMMON) 212 213 . = ALIGN(8); 214 PROVIDE( _ebss = ABSOLUTE(.) ); 215 } >ram AT>ram :ram 216 217 PROVIDE( _tls_data = ABSOLUTE(.) ); 218 /* 219 * Thread Local Storage (TLS) are per-thread global variables. 220 * Compilers such as GCC provide a __thread keyword to mark global 221 * variables as per-thread. Support is required in the program loader 222 * and thread creator. 223 */ 224 225 /* Thread-local data segment, .tdata (initialized tls). */ 226 .tdata : 227 { 228 KEEP( *(.tdata.begin) ) 229 *(.tdata .tdata.*) 230 *(.gnu.linkonce.td.*) 231 KEEP( *(.tdata.end) ) 232 } >ram AT>ram :ram 233 234 /* Thread-local bss segment, .tbss (zero-initialized tls). */ 235 .tbss : 236 { 237 *(.tbss .tbss.*) 238 *(.gnu.linkonce.tb.*) 239 KEEP( *(.tbss.end) ) 240 } >ram AT>ram :ram 241 242 /* 243 * End of uninitalized data segement 244 * 245 * Actually the stack needs 16B alignment, and it won't hurt to also slightly 246 * increase the alignment to 32 or even 64 (cache line size). 247 * 248 * Align _heap_start to cache line size 249 */ 250 . = ALIGN(64); 251 PROVIDE( _end = ABSOLUTE(.) ); 252 /* Leave 2 holes for stack & TLS, the size can set in kconfig */ 253 PROVIDE( _heap_start = ABSOLUTE(.) + _stack_size * 2 ); 254 PROVIDE( _tp0 = (_end + 63) & (-64) ); 255 PROVIDE( _tp1 = _tp0 + _stack_size ); 256 PROVIDE( _sp0 = _tp0 + _stack_size ); 257 PROVIDE( _sp1 = _tp1 + _stack_size ); 258 259 /* Heap end is at the end of memory, the memory size can set in kconfig */ 260 PROVIDE( _heap_end = _ram_end ); 261 } 262