Device Linker Script: gcc_<device>.ld

The Linker Script File gcc_<device>.ld contains:
  • Memory base address and size.

  • Code, data section, vector table etc. location.

  • Stack & heap location and size.

The file exists for each supported toolchain and is the only toolchain specific NMSIS file.

To adapt the file to a new device only when you need change the memory base address, size, data and code location etc.

gcc_Device.ld Template File

Here we provided gcc_Device.ld template file as below:

  1 /*
  2  * Copyright (c) 2019 Nuclei Limited. All rights reserved.
  3  *
  4  * SPDX-License-Identifier: Apache-2.0
  5  *
  6  * Licensed under the Apache License, Version 2.0 (the License); you may
  7  * not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at
  9  *
 10  * www.apache.org/licenses/LICENSE-2.0
 11  *
 12  * Unless required by applicable law or agreed to in writing, software
 13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  * See the License for the specific language governing permissions and
 16  * limitations under the License.
 17  */
 18 /******************************************************************************
 19  * @file     gcc_<Device>.ld
 20  * @brief    GNU Linker Script for Device <Device>
 21  * @version  V2.1.0
 22  * @date     19. Dec 2023
 23  ******************************************************************************/
 24 
 25 /*********** Use Configuration Wizard in Context Menu *************************/
 26 
 27 OUTPUT_ARCH( "riscv" )
 28 /********************* Flash Configuration ************************************
 29  * <h> Flash Configuration
 30  * <o0> Flash Base Address <0x0-0xFFFFFFFF:8>
 31  * <o1> Flash Size (in Bytes) <0x0-0xFFFFFFFF:8>
 32  * </h>
 33  */
 34 __ROM_BASE = 0x20000000;
 35 __ROM_SIZE = 0x00400000;
 36 
 37 /*--------------------- ILM RAM Configuration ---------------------------
 38  * <h> ILM RAM Configuration
 39  * <o0> ILM RAM Base Address    <0x0-0xFFFFFFFF:8>
 40  * <o1> ILM RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
 41  * </h>
 42  */
 43 __ILM_RAM_BASE = 0x80000000;
 44 __ILM_RAM_SIZE = 0x00010000;
 45 
 46 /*--------------------- Embedded RAM Configuration ---------------------------
 47  * <h> RAM Configuration
 48  * <o0> RAM Base Address    <0x0-0xFFFFFFFF:8>
 49  * <o1> RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
 50  * </h>
 51 */
 52 __RAM_BASE = 0x90000000;
 53 __RAM_SIZE = 0x00010000;
 54 
 55 /********************* Stack / Heap Configuration ****************************
 56  * <h> Stack / Heap Configuration
 57  * <o0> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
 58  * <o1> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
 59  * </h>
 60  */
 61 __STACK_SIZE = 0x00000800;
 62 __HEAP_SIZE  = 0x00000800;
 63 
 64 /**************************** end of configuration section ********************/
 65 
 66 /* Define entry label of program */
 67 ENTRY(_start)
 68 /* Define base address and length of flash and ram */
 69 MEMORY
 70 {
 71   flash (rxa!w) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
 72   ram (wxa!r) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
 73 }
 74 
 75 REGION_ALIAS("ROM", flash)
 76 REGION_ALIAS("RAM", ram)
 77 
 78 /* Linker script to place sections and symbol values. Should be used together
 79  * with other linker script that defines memory regions FLASH,ILM and RAM.
 80  * It references following symbols, which must be defined in code:
 81  *   _start : Entry of reset handler
 82  *
 83  * It defines following symbols, which code can use without definition:
 84  *   _ilm_lma ; deprecated
 85  *   _ilm     ; deprecated
 86  *   _eilm    ; deprecated
 87  *   _text_lma
 88  *   _text
 89  *   _etext
 90  *   __etext
 91  *   etext
 92  *   __preinit_array_start
 93  *   __preinit_array_end
 94  *   __init_array_start
 95  *   __init_array_end
 96  *   __fini_array_start
 97  *   __fini_array_end
 98  *   _data_lma
 99  *   _edata
100  *   edata
101  *   __data_end__
102  *   __bss_start
103  *   __fbss
104  *   _end
105  *   end
106  *   __heap_start
107  *   __heap_end
108  *   __heap_limit
109  *   __StackLimit
110  *   __StackBottom
111  *   __StackTop
112  *   __HEAP_SIZE
113  *   __STACK_SIZE
114  */
115 
116 SECTIONS
117 {
118   /* To provide symbol __STACK_SIZE, __HEAP_SIZE and __SMP_CPU_CNT */
119   PROVIDE(__STACK_SIZE = 2K);
120   PROVIDE(__HEAP_SIZE = 2K);
121   PROVIDE(__SMP_CPU_CNT = 1);
122   __TOT_STACK_SIZE = __STACK_SIZE * __SMP_CPU_CNT;
123 
124   .init           :
125   {
126     /* vector table locate at ROM */
127     *(.text.vtable)
128     *(.text.vtable_s)
129     *(.text.init)
130     KEEP (*(SORT_NONE(.init)))
131     . = ALIGN(4);
132   } >ROM AT>ROM
133 
134   /* Code section located at ROM */
135   .text           :
136   {
137     *(.text.unlikely .text.unlikely.*)
138     *(.text.startup .text.startup.*)
139     . = ALIGN(8);
140     PROVIDE( __jvt_base$ = . );
141     *(.text.tbljal .text.tbljal.*)
142     *(.text .text.*)
143     *(.gnu.linkonce.t.*)
144     /* readonly data placed in ROM */
145     . = ALIGN(8);
146     *(.srodata.cst16)
147     *(.srodata.cst8)
148     *(.srodata.cst4)
149     *(.srodata.cst2)
150     *(.srodata .srodata.*)
151     *(.rdata)
152     *(.rodata .rodata.*)
153     *(.gnu.linkonce.r.*)
154     /* rtt */
155     . = ALIGN(8);
156     __rt_init_start = .;
157     KEEP(*(SORT(.rti_fn*)))
158     __rt_init_end = .;
159     . = ALIGN(8);
160     __fsymtab_start = .;
161     KEEP(*(FSymTab))
162     __fsymtab_end = .;
163     . = ALIGN(8);
164     __vsymtab_start = .;
165     KEEP(*(VSymTab))
166     __vsymtab_end = .;
167     /* .fini */
168     . = ALIGN(8);
169     KEEP (*(SORT_NONE(.fini)))
170     /* .preinit_array */
171     . = ALIGN(8);
172     PROVIDE_HIDDEN (__preinit_array_start = .);
173     KEEP (*(.preinit_array))
174     PROVIDE_HIDDEN (__preinit_array_end = .);
175     /* .init_array */
176     . = ALIGN(8);
177     PROVIDE_HIDDEN (__init_array_start = .);
178     KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
179     KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
180     PROVIDE_HIDDEN (__init_array_end = .);
181     /* .fini_array */
182     . = ALIGN(8);
183     PROVIDE_HIDDEN (__fini_array_start = .);
184     PROVIDE_HIDDEN (__libc_fini = _fini);
185     KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
186     KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
187     PROVIDE_HIDDEN (__fini_array_end = .);
188     /* .ctors */
189     . = ALIGN(8);
190     KEEP (*crtbegin.o(.ctors))
191     KEEP (*crtbegin?.o(.ctors))
192     KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
193     KEEP (*(SORT(.ctors.*)))
194     KEEP (*(.ctors))
195     /* .dtors */
196     . = ALIGN(8);
197     KEEP (*crtbegin.o(.dtors))
198     KEEP (*crtbegin?.o(.dtors))
199     KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
200     KEEP (*(SORT(.dtors.*)))
201     KEEP (*(.dtors))
202   } >ROM AT>ROM
203 
204   PROVIDE( _ilm_lma = LOADADDR(.text) );
205   PROVIDE( _ilm = ADDR(.text) );
206   PROVIDE( _eilm = . );
207   PROVIDE( _text_lma = LOADADDR(.text) );
208   PROVIDE( _text = ADDR(.text) );
209   PROVIDE (_etext = .);
210   PROVIDE (__etext = .);
211   PROVIDE (etext = .);
212 
213   .data            : ALIGN(8)
214   {
215     KEEP(*(.data.ctest*))
216     *(.data .data.*)
217     *(.gnu.linkonce.d.*)
218     . = ALIGN(8);
219     PROVIDE( __global_pointer$ = . + 0x800 );
220     *(.sdata .sdata.* .sdata*)
221     *(.gnu.linkonce.s.*)
222     . = ALIGN(8);
223   } >RAM AT>ROM
224 
225   .tdata           : ALIGN(8)
226   {
227     PROVIDE( __tls_base = . );
228     *(.tdata .tdata.* .gnu.linkonce.td.*)
229   } >RAM AT>ROM
230 
231   PROVIDE( _data_lma = LOADADDR(.data) );
232   PROVIDE( _data = ADDR(.data) );
233   PROVIDE( _edata = . );
234   PROVIDE( edata = . );
235 
236   PROVIDE( _fbss = . );
237   PROVIDE( __bss_start = . );
238 
239   .tbss (NOLOAD)   : ALIGN(8)
240   {
241     *(.tbss .tbss.* .gnu.linkonce.tb.*)
242     *(.tcommon)
243     PROVIDE( __tls_end = . );
244   } >RAM AT>RAM
245 
246   .tbss_space (NOLOAD) : ALIGN(8)
247   {
248     . = . + SIZEOF(.tbss);
249   } >RAM AT>RAM
250 
251   .bss (NOLOAD)   : ALIGN(8)
252   {
253     *(.sbss*)
254     *(.gnu.linkonce.sb.*)
255     *(.bss .bss.*)
256     *(.gnu.linkonce.b.*)
257     *(COMMON)
258     . = ALIGN(4);
259   } >RAM AT>RAM
260 
261   PROVIDE( _end = . );
262   PROVIDE( end = . );
263 
264   /* Nuclei C Runtime Library requirements:
265    * 1. heap need to be align at 16 bytes
266    * 2. __heap_start and __heap_end symbol need to be defined
267    * 3. reserved at least __HEAP_SIZE space for heap
268    */
269   .heap (NOLOAD)   : ALIGN(16)
270   {
271     . = ALIGN(16);
272     PROVIDE( __heap_start = . );
273     . += __HEAP_SIZE;
274     . = ALIGN(16);
275     PROVIDE( __heap_limit = . );
276   } >RAM AT>RAM
277 
278   .stack ORIGIN(RAM) + LENGTH(RAM) - __TOT_STACK_SIZE (NOLOAD) :
279   {
280     . = ALIGN(16);
281     PROVIDE( _heap_end = . );
282     PROVIDE( __heap_end = . );
283     PROVIDE( __StackLimit = . );
284     PROVIDE( __StackBottom = . );
285     . += __TOT_STACK_SIZE;
286     . = ALIGN(16);
287     PROVIDE( __StackTop = . );
288     PROVIDE( _sp = . );
289   } >RAM AT>RAM
290 }