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