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
 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}