Device Linker Script: gcc_<device>.ld

Caution

Please be informed that the NMSIS-Core Device Templates may not be updated in a timely manner and thus could become outdated. We suggest referring to the specific implementation of evalsoc in the Nuclei SDK for the latest reference template. This reference template may not be actively maintained in the future.

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
 27OUTPUT_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 */
 67ENTRY(_start)
 68/* Define base address and length of flash and ram */
 69MEMORY
 70{
 71  flash (rxa!w) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
 72  ram (wxa!r) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
 73}
 74
 75REGION_ALIAS("ROM", flash)
 76REGION_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
116SECTIONS
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}