1/*
2 * Copyright (c) 2021 KT-Elektronik, Klaucke und Partner GmbH
3 * Copyright (c) 2024 Renesas Electronics Corporation
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7/**
8 * @file
9 * @brief Linker command/script file
10 *
11 * Generic Linker script for the riscv platform
12 */
13
14#include <zephyr/devicetree.h>
15
16#include <zephyr/linker/sections.h>
17#include <zephyr/linker/devicetree_regions.h>
18
19#include <zephyr/linker/linker-defs.h>
20#include <zephyr/linker/linker-tool.h>
21
22#ifdef CONFIG_XIP
23#define ROMABLE_REGION	ROM
24#else
25#define ROMABLE_REGION	RAM
26#endif
27#define RAMABLE_REGION	RAM
28
29#if defined(CONFIG_ROM_END_OFFSET)
30#define ROM_END_OFFSET CONFIG_ROM_END_OFFSET
31#else
32#define ROM_END_OFFSET 0
33#endif
34
35#if defined(CONFIG_FLASH_LOAD_OFFSET)
36#define FLASH_LOAD_OFFSET CONFIG_FLASH_LOAD_OFFSET
37#else
38#define FLASH_LOAD_OFFSET 0
39#endif
40
41#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_flash), okay)
42#define ROM_START (CONFIG_FLASH_BASE_ADDRESS + FLASH_LOAD_OFFSET)
43#ifndef ROM_SIZE
44#define ROM_SIZE (DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) - ROM_END_OFFSET)
45#endif
46#endif
47
48#define RAM_START (CONFIG_SRAM_BASE_ADDRESS)
49#define RAM_SIZE  (KB(CONFIG_SRAM_SIZE))
50
51_region_min_align = 4;
52
53MEMORY
54{
55	ROM (rx) : ORIGIN = ROM_START, LENGTH = ROM_SIZE
56	RAM (rwx): ORIGIN = RAM_START, LENGTH = RAM_SIZE
57
58	LINKER_DT_REGIONS()
59	/* Used by and documented in include/linker/intlist.ld */
60	IDT_LIST (wx) : ORIGIN = 0xFFFFF780, LENGTH = 2K
61}
62
63ENTRY(CONFIG_KERNEL_ENTRY)
64
65SECTIONS
66{
67
68#include <zephyr/linker/rel-sections.ld>
69#include <zephyr/linker/llext-sections.ld>
70
71	GROUP_START(ROMABLE_REGION)
72	. = ROM_START;   /* for kernel logging */
73	PLACE_SYMBOL_HERE(__rodata_region_start);
74
75#if CONFIG_HAS_EXCEPT_VECTOR_TABLE
76	.exvectors 0xFFFFFF80: AT(0xFFFFFF80)
77	{
78		KEEP(*(.exvectors))
79	} GROUP_LINK_IN(ROMABLE_REGION)
80
81	 .fvectors 0xFFFFFFFC: AT(0xFFFFFFFC)
82	{
83		KEEP(*(.fvectors))
84	} GROUP_LINK_IN(ROMABLE_REGION)
85#else
86	.fvectors 0xFFFFFF80: AT(0xFFFFFF80)
87	{
88		KEEP(*(.fvectors))
89	} GROUP_LINK_IN(ROMABLE_REGION)
90#endif
91
92	SECTION_PROLOGUE(_TEXT_SECTION_NAME,ROM_START,)
93	{
94		. = ALIGN(4);
95		_image_text_start = .;
96/* Located in generated directory. This file is populated by the
97 * zephyr_linker_sources() Cmake function.
98 */
99#include <snippets-rom-start.ld>
100		*(.text)
101		*(.text.*)
102		*(P)
103		. = ALIGN(4);
104		etext = .;
105#include <zephyr/linker/kobject-text.ld>
106	} GROUP_LINK_IN(ROMABLE_REGION)
107
108	_image_text_end = .;
109
110	#include <zephyr/linker/common-rom.ld>
111
112/* Located in generated directory. This file is populated by calling
113 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs.
114 */
115#include <snippets-rom-sections.ld>
116
117	SECTION_PROLOGUE(.rvectors,,)
118	{
119		_rvectors_start = .;
120		KEEP(*(.rvectors))
121		_rvectors_end = .;
122	} GROUP_LINK_IN(ROMABLE_REGION)
123	SECTION_PROLOGUE(init,,)
124	{
125		KEEP(*(.init))
126		__preinit_array_start = .;
127		KEEP(*(.preinit_array))
128		__preinit_array_end = .;
129		__init_array_start = (. + 3) & ~ 3;
130		KEEP(*(.init_array))
131		KEEP(*(SORT(.init_array.*)))
132		__init_array_end = .;
133		__fini_array_start = .;
134		KEEP(*(.fini_array))
135		KEEP(*(SORT(.fini_array.*)))
136		__fini_array_end = .;
137	} GROUP_LINK_IN(ROMABLE_REGION)
138	SECTION_PROLOGUE(fini,,)
139	{
140		KEEP(*(.fini))
141	} GROUP_LINK_IN(ROMABLE_REGION)
142	SECTION_PROLOGUE(got,,)
143	{
144		*(.got)
145		*(.got.plt)
146	} GROUP_LINK_IN(ROMABLE_REGION)
147
148#include <zephyr/linker/thread-local-storage.ld>
149#include <zephyr/linker/cplusplus-rom.ld>
150
151	SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
152	{
153		*(.rodata)
154		*(.rodata.*)
155		*(.gnu.linkonce.r)
156		*(.gnu.linkonce.r.*)
157		*(C_1)
158		*(C_2)
159		*(C)
160
161/* Located in generated directory. This file is populated by the
162 * zephyr_linker_sources() Cmake function.
163 */
164#include <snippets-rodata.ld>
165#include <zephyr/linker/kobject-rom.ld>
166
167		_erodata = .;
168	} GROUP_LINK_IN(ROMABLE_REGION)
169	SECTION_PROLOGUE(eh_frame_hdr,,)
170	{
171		*(.eh_frame_hdr)
172	} GROUP_LINK_IN(ROMABLE_REGION)
173	SECTION_PROLOGUE(eh_frame,,)
174	{
175		*(.eh_frame)
176	} GROUP_LINK_IN(ROMABLE_REGION)
177	SECTION_PROLOGUE(jcr,,)
178	{
179		*(.jcr)
180	} GROUP_LINK_IN(ROMABLE_REGION)
181
182#if DT_PROP(DT_NODELABEL(code_flash), programming_enable)
183	SECTION_PROLOGUE(.pfram,ALIGN(4),)
184	{
185		_PFRAM_start = .;
186		. += _RPFRAM_end - _RPFRAM_start;
187		_PFRAM_end = .;
188	} > ROMABLE_REGION
189#endif
190
191	/* TODO: is this section necessary? There is a similar section
192	 * (_CTOR_SECTION_NAME) in common-rom.ld. This seems to be for
193	 * C++ Constructors/Destructors? */
194	SECTION_PROLOGUE(tors,,)
195	{
196		__CTOR_LIST__ = .;
197		. = ALIGN(2);
198		__ctors = .;
199		*(.ctors)
200		__ctors_end = .;
201		__CTOR_END__ = .;
202		__DTOR_LIST__ = .;
203		__dtors = .;
204		*(.dtors)
205		__dtors_end = .;
206		__DTOR_END__ = .;
207		. = ALIGN(2);
208	} GROUP_LINK_IN(ROMABLE_REGION)
209
210	PLACE_SYMBOL_HERE(__rodata_region_end);
211	GROUP_END(ROMABLE_REGION)
212
213	GROUP_START(RAMABLE_REGION)
214
215	_image_ram_start = .;
216
217#include <app_data_alignment.ld>
218
219/* Located in generated directory. This file is populated by the
220 * zephyr_linker_sources() Cmake function.
221 */
222#include <snippets-ram-sections.ld>
223
224#if defined(CONFIG_USERSPACE)
225#define APP_SHARED_ALIGN MPU_MIN_SIZE_ALIGN
226#define SMEM_PARTITION_ALIGN MPU_ALIGN
227
228#include <app_smem.ld>
229	_app_smem_size = _app_smem_end - _app_smem_start;
230	_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
231#endif /* CONFIG_USERSPACE */
232
233	#if CONFIG_SRAM_BASE_ADDRESS == 0
234		/* RX memory starts at address 0 which can be confused with NULL. To prevent this, block
235		 * the first memory page (16 Bytes).
236		 */
237		SECTION_DATA_PROLOGUE(.null_blocker,,)
238		{
239			. = 0x10;
240		} GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
241	#endif
242
243	SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
244	{
245		__data_region_start = .;
246		__data_start = .;
247		*(.data)
248		*(.data.*)
249		*(D)
250		*(D_1)
251		*(D_2)
252		*(.gnu.linkonce.*)
253
254#include <snippets-rwdata.ld>
255	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
256
257	/* the sections defined in common-ram.ld have to be initialized on
258	 * reset as well, to place them before _edata */
259#include <zephyr/linker/common-ram.ld>
260#include <zephyr/linker/kobject-data.ld>
261#include <zephyr/linker/cplusplus-ram.ld>
262
263/* Located in generated directory. This file is populated by the
264 * zephyr_linker_sources() Cmake function.
265 */
266#include <snippets-data-sections.ld>
267
268	__data_region_end = .;
269
270#if DT_PROP(DT_NODELABEL(code_flash), programming_enable)
271
272	.rpfram ALIGN(4): AT(_PFRAM_start)
273	{
274		_RPFRAM_start = .;
275		*(PFRAM)
276		. = ALIGN(4);
277		_RPFRAM_end = .;
278	} > RAMABLE_REGION
279
280#endif
281
282	SECTION_PROLOGUE(_BSS_SECTION_NAME,,)
283	{
284		_bss = .;
285		__bss_start = .;
286		*(.bss)
287		*(.bss.**)
288		*(COMMON)
289		*(B)
290		*(B_1)
291		*(B_2)
292		_ebss = .;
293		__bss_end = .;
294		. = ALIGN(128);
295		_end = .;
296	} GROUP_LINK_IN(RAMABLE_REGION)
297
298	_ebss = . ;
299
300#include <zephyr/linker/common-noinit.ld>
301
302	_image_ram_end = .;
303	_end = .;
304	PROVIDE(__end = _end);
305
306/* Located in generated directory. This file is populated by the
307 * zephyr_linker_sources() Cmake function.
308 */
309#include <snippets-sections.ld>
310
311#include <zephyr/linker/ram-end.ld>
312
313	GROUP_END(RAMABLE_REGION)
314
315#include <zephyr/linker/debug-sections.ld>
316
317}
318