1/*
2 * Copyright (c) 2013-2014 Wind River Systems, Inc.
3 * Copyright (c) 2016-2017 Jean-Paul Etienne <fractalclone@gmail.com>
4 * Copyright (c) 2018 Foundries.io Ltd
5 *
6 * This file is based on:
7 *
8 * - include/arch/arm/cortex_m/scripts/linker.ld
9 * - include/arch/riscv/common/linker.ld
10 * - include/arch/riscv/pulpino/linker.ld
11 *
12 * SPDX-License-Identifier: Apache-2.0
13 */
14
15#include <zephyr/devicetree.h>
16
17#include <zephyr/linker/sections.h>
18#include <zephyr/linker/linker-defs.h>
19#include <zephyr/linker/linker-tool.h>
20
21/*
22 * Extra efforts would need to be taken to ensure the IRQ handlers are within
23 * jumping distance of the vector table in non-XIP builds, so avoid them.
24 */
25#define ROMABLE_REGION              ROM
26#define RAMABLE_REGION              RAM
27
28#define VECTOR_SIZE 0x100
29
30#ifdef CONFIG_USE_DT_CODE_PARTITION
31
32#ifdef CONFIG_BOOTLOADER_MCUBOOT
33
34
35#define ROM_BASE (DT_REG_ADDR(DT_CHOSEN(zephyr_code_partition)))
36#define ROM_SIZE (DT_REG_SIZE(DT_CHOSEN(zephyr_code_partition)))
37
38#define VECTOR_BASE (ROM_BASE + CONFIG_ROM_START_OFFSET)
39
40#else
41
42#define ROM_BASE (DT_REG_ADDR(DT_CHOSEN(zephyr_code_partition)))
43#define ROM_SIZE (DT_REG_SIZE(DT_CHOSEN(zephyr_code_partition)) - VECTOR_BASE)
44
45#define VECTOR_BASE (ROM_BASE + ROM_SIZE)
46
47#endif
48
49#else
50
51#define ROM_BASE DT_REG_ADDR(DT_CHOSEN(zephyr_flash))
52#define ROM_SIZE (DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) - VECTOR_SIZE)
53
54#define VECTOR_BASE (ROM_BASE + ROM_SIZE)
55
56#endif
57
58#define RAM_BASE CONFIG_SRAM_BASE_ADDRESS
59#define RAM_SIZE KB(CONFIG_SRAM_SIZE)
60
61MEMORY
62    {
63    ROM (rx)      : ORIGIN = ROM_BASE,    LENGTH = ROM_SIZE
64    /*
65     * Each RISC-V core on this chip (RI5CY and ZERO-RISCY) has
66     * a vector table at the end of its flash bank. They are relocatable
67     * at runtime, but we need to put the reset vectors in hardcoded places.
68     *
69     * (The Arm core vector tables are at the beginning of each
70     * flash bank.)
71     */
72#ifndef CONFIG_BOOTLOADER_MCUBOOT
73    VECTORS (rx)  : ORIGIN = VECTOR_BASE, LENGTH = VECTOR_SIZE
74#endif
75    RAM (rwx)     : ORIGIN = RAM_BASE,    LENGTH = RAM_SIZE
76    /*
77     * Special section, not included in the final binary, used
78     * to generate interrupt tables. See include/linker/intlist.ld.
79     */
80    IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K
81    }
82
83ENTRY(CONFIG_KERNEL_ENTRY)
84
85SECTIONS
86    {
87
88#include <zephyr/linker/rel-sections.ld>
89
90#ifdef CONFIG_LLEXT
91#include <zephyr/linker/llext-sections.ld>
92#endif
93
94    SECTION_PROLOGUE(.plt,,)
95	{
96		*(.plt)
97	}
98
99    SECTION_PROLOGUE(.iplt,,)
100	{
101		*(.iplt)
102	}
103
104    GROUP_START(ROM)
105    __rom_region_start = ROM_BASE;
106
107    SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
108	{
109
110/* Located in generated directory. This file is populated by calling
111 * zephyr_linker_sources(ROM_START ...). This typically contains the vector
112 * table and debug information.
113 */
114#include <snippets-rom-start.ld>
115
116	__text_region_start = .;
117
118	*(.text .text.*)
119	*(.gnu.linkonce.t.*)
120	*(.eh_frame)
121	} GROUP_LINK_IN(ROM)
122
123    __text_region_end = .;
124
125    __rodata_region_start = .;
126
127#include <zephyr/linker/common-rom.ld>
128/* Located in generated directory. This file is populated by calling
129 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs.
130 */
131#include <snippets-rom-sections.ld>
132#include <zephyr/linker/thread-local-storage.ld>
133
134    SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
135	{
136	. = ALIGN(4);
137	*(.srodata)
138	*(".srodata.*")
139	*(.rodata)
140	*(.rodata.*)
141	*(.gnu.linkonce.r.*)
142
143/* Located in generated directory. This file is populated by the
144 * zephyr_linker_sources() Cmake function.
145 */
146#include <snippets-rodata.ld>
147
148	} GROUP_LINK_IN(ROMABLE_REGION)
149
150#include <zephyr/linker/cplusplus-rom.ld>
151
152    __rodata_region_end = .;
153    __rom_region_end = .;
154
155#ifndef CONFIG_BOOTLOADER_MCUBOOT
156    /* The vector table goes into core-dependent flash locations. */
157    SECTION_PROLOGUE(vectors,,)
158	{
159	_vector_start = .;
160	KEEP(*(.vectors.*))
161	} GROUP_LINK_IN(VECTORS)
162    _vector_end = .;
163#endif
164
165    GROUP_END(ROM)
166
167    GROUP_START(RAM)
168
169    SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
170	{
171	. = ALIGN(4);
172	_image_ram_start = .;
173	__data_region_start = .;
174	__data_start = .;
175
176	*(.data)
177	*(.data.*)
178	*(.gnu.linkonce.s.*)
179
180	/* https://groups.google.com/a/groups.riscv.org/d/msg/sw-dev/60IdaZj27dY/TKT3hbNlAgAJ */
181	*(.sdata .sdata.* .gnu.linkonce.s.*)
182	*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
183
184/* Located in generated directory. This file is populated by the
185 * zephyr_linker_sources() Cmake function.
186 */
187#include <snippets-rwdata.ld>
188
189	__data_end = .;
190
191	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
192	__data_size = __data_end - __data_start;
193	__data_load_start = LOADADDR(_DATA_SECTION_NAME);
194
195#include <zephyr/linker/common-ram.ld>
196#include <zephyr/linker/cplusplus-ram.ld>
197
198/* Located in generated directory. This file is populated by the
199 * zephyr_linker_sources() Cmake function.
200 */
201#include <snippets-data-sections.ld>
202
203    __data_region_end = .;
204    __data_region_load_start = LOADADDR(_DATA_SECTION_NAME);
205
206    SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
207	{
208	/*
209	 * For performance, BSS section is assumed to be 4 byte aligned and
210	 * a multiple of 4 bytes, so it can be cleared in words.
211	 */
212	 . = ALIGN(4);
213	 __bss_start = .;
214
215	 *(.bss .bss.*)
216	 *(.sbss .sbss.*)
217	 COMMON_SYMBOLS
218
219	 /* Ensure 4 byte alignment for the entire section. */
220	 . = ALIGN(4);
221	  __bss_end = .;
222	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
223
224    SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),)
225	{
226	/*
227	 * This section is used for non-initialized objects that
228	 * will not be cleared during the boot process.
229	 */
230	 *(.noinit .noinit.*)
231
232/* Located in generated directory. This file is populated by the
233 * zephyr_linker_sources() Cmake function.
234 */
235#include <snippets-noinit.ld>
236
237	} GROUP_LINK_IN(RAMABLE_REGION)
238
239/* Located in generated directory. This file is populated by the
240 * zephyr_linker_sources() Cmake function.
241 */
242#include <snippets-ram-sections.ld>
243
244/* Located in generated directory. This file is populated by the
245 * zephyr_linker_sources() Cmake function.
246 */
247#include <snippets-sections.ld>
248
249#include <zephyr/linker/ram-end.ld>
250
251    GROUP_END(RAMABLE_REGION)
252
253#ifdef CONFIG_GEN_ISR_TABLES
254/* Bogus section, post-processed during the build to initialize interrupts. */
255#include <zephyr/linker/intlist.ld>
256#endif
257
258#include <zephyr/linker/debug-sections.ld>
259
260    SECTION_PROLOGUE(.riscv.attributes, 0,)
261	{
262	KEEP(*(.riscv.attributes))
263	KEEP(*(.gnu.attributes))
264	}
265    /*
266     * Pulpino toolchains emit these sections; we don't care about them,
267     * but need to avoid build system warnings about orphaned sections.
268     */
269    SECTION_PROLOGUE(.Pulp_Chip.Info,,)
270	{
271		*(.Pulp_Chip.*)
272	}
273
274    }
275