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