1/*
2 * Copyright (c) 2013-2014 Wind River Systems, Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7/**
8 * @file
9 * @brief Linker command/script file
10 *
11 * Linker script for the Cortex-M platforms.
12 */
13
14#include <zephyr/linker/sections.h>
15#include <zephyr/devicetree.h>
16
17#include <zephyr/linker/devicetree_regions.h>
18#include <zephyr/linker/linker-defs.h>
19#include <zephyr/linker/linker-tool.h>
20
21/* physical address of RAM */
22#ifdef CONFIG_XIP
23#define ROMABLE_REGION FLASH
24#else
25#define ROMABLE_REGION RAM
26#endif
27#define RAMABLE_REGION RAM
28
29/* Region of the irq vectors and boot-vector SP/PC */
30#if defined(CONFIG_ROMSTART_RELOCATION_ROM)
31#define ROMSTART_ADDR CONFIG_ROMSTART_REGION_ADDRESS
32#define ROMSTART_SIZE (CONFIG_ROMSTART_REGION_SIZE * 1K)
33#else
34#define ROMSTART_REGION ROMABLE_REGION
35#endif
36
37#if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0)
38#define ROM_ADDR RAM_ADDR
39#else
40#define ROM_ADDR (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET)
41#endif
42
43#if defined(CONFIG_ROM_END_OFFSET)
44#define ROM_END_OFFSET CONFIG_ROM_END_OFFSET
45#else
46#define ROM_END_OFFSET 0
47#endif
48
49#if CONFIG_FLASH_LOAD_SIZE > 0
50#define ROM_SIZE (CONFIG_FLASH_LOAD_SIZE - ROM_END_OFFSET)
51#else
52#define ROM_SIZE (CONFIG_FLASH_SIZE * 1024 - CONFIG_FLASH_LOAD_OFFSET - ROM_END_OFFSET)
53#endif
54
55#define RAM_SIZE (CONFIG_SRAM_SIZE * 1K)
56#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
57
58#if defined(CONFIG_CUSTOM_SECTION_ALIGN)
59_region_min_align = CONFIG_CUSTOM_SECTION_MIN_ALIGN_SIZE;
60#else
61/* Set alignment to CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
62 * to make linker section alignment comply with MPU granularity.
63 */
64#if defined(CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE)
65_region_min_align = CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE;
66#else
67/* If building without MPU support, use default 4-byte alignment. */
68_region_min_align = 4;
69#endif
70#endif
71
72#if !defined(CONFIG_CUSTOM_SECTION_ALIGN) && defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
73#define MPU_ALIGN(region_size) \
74    . = ALIGN(_region_min_align); \
75    . = ALIGN( 1 << LOG2CEIL(region_size))
76#else
77#define MPU_ALIGN(region_size) \
78    . = ALIGN(_region_min_align)
79#endif
80
81#include <zephyr/linker/linker-devnull.h>
82
83MEMORY
84    {
85#if defined(CONFIG_ROMSTART_RELOCATION_ROM)
86    ROMSTART_REGION (rx) : ORIGIN = ROMSTART_ADDR, LENGTH = ROMSTART_SIZE
87#endif
88    FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE
89    RAM   (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
90#if defined(CONFIG_LINKER_DEVNULL_MEMORY)
91    DEVNULL_ROM (rx) : ORIGIN = DEVNULL_ADDR, LENGTH = DEVNULL_SIZE
92#endif
93    LINKER_DT_REGIONS()
94    /* Used by and documented in include/linker/intlist.ld */
95    IDT_LIST (wx) : ORIGIN = 0xFFFF7FFF, LENGTH = 32K
96    }
97
98ENTRY(CONFIG_KERNEL_ENTRY)
99
100SECTIONS
101    {
102
103#include <zephyr/linker/rel-sections.ld>
104
105#ifdef CONFIG_LLEXT
106#include <zephyr/linker/llext-sections.ld>
107#endif
108
109    /*
110     * .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose',
111     * before text section.
112     */
113    /DISCARD/ :
114	{
115	*(.plt)
116	}
117
118    /DISCARD/ :
119	{
120	*(.iplt)
121	}
122
123    GROUP_START(ROMABLE_REGION)
124
125	__rom_region_start = ROM_ADDR;
126
127    SECTION_PROLOGUE(rom_start,,)
128	{
129
130/* Located in generated directory. This file is populated by calling
131 * zephyr_linker_sources(ROM_START ...). This typically contains the vector
132 * table and debug information.
133 */
134#include <snippets-rom-start.ld>
135
136	} GROUP_LINK_IN(ROMSTART_REGION)
137
138#ifdef CONFIG_CODE_DATA_RELOCATION
139
140#include <linker_relocate.ld>
141
142#endif /* CONFIG_CODE_DATA_RELOCATION */
143
144    SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
145	{
146	__text_region_start = .;
147
148#include <zephyr/linker/kobject-text.ld>
149
150	*(.text)
151	*(".text.*")
152	*(".TEXT.*")
153	*(.gnu.linkonce.t.*)
154
155	/*
156	 * These are here according to 'arm-zephyr-elf-ld --verbose',
157	 * after .gnu.linkonce.t.*
158	 */
159	*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
160	. = ALIGN(4);
161
162	} GROUP_LINK_IN(ROMABLE_REGION)
163
164	__text_region_end = .;
165
166#if defined (CONFIG_CPP) || defined(CONFIG_RUST)
167	SECTION_PROLOGUE(.ARM.extab,,)
168	{
169	/*
170	 * .ARM.extab section containing exception unwinding information.
171	 */
172	*(.ARM.extab* .gnu.linkonce.armextab.*)
173	} GROUP_LINK_IN(ROMABLE_REGION)
174#endif
175
176	SECTION_PROLOGUE(.ARM.exidx,,)
177	{
178	/*
179	 * This section, related to stack and exception unwinding, is placed
180	 * explicitly to prevent it from being shared between multiple regions.
181	 * It  must be defined for gcc to support 64-bit math and avoid
182	 * section overlap.
183	 */
184	__exidx_start = .;
185#if defined (__GCC_LINKER_CMD__) || defined (__LLD_LINKER_CMD__)
186	*(.ARM.exidx* gnu.linkonce.armexidx.*)
187#endif
188	__exidx_end = .;
189	} GROUP_LINK_IN(ROMABLE_REGION)
190
191	__rodata_region_start = .;
192
193#include <zephyr/linker/common-rom.ld>
194/* Located in generated directory. This file is populated by calling
195 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs.
196 */
197#include <snippets-rom-sections.ld>
198#include <zephyr/linker/thread-local-storage.ld>
199
200    SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
201	{
202	*(.rodata)
203	*(".rodata.*")
204	*(.gnu.linkonce.r.*)
205
206/* Located in generated directory. This file is populated by the
207 * zephyr_linker_sources() Cmake function.
208 */
209#include <snippets-rodata.ld>
210
211#include <zephyr/linker/kobject-rom.ld>
212
213	/*
214	 * For XIP images, in order to avoid the situation when __data_rom_start
215	 * is 32-bit aligned, but the actual data is placed right after rodata
216	 * section, which may not end exactly at 32-bit border, pad rodata
217	 * section, so __data_rom_start points at data and it is 32-bit aligned.
218	 *
219	 * On non-XIP images this may enlarge image size up to 3 bytes. This
220	 * generally is not an issue, since modern ROM and FLASH memory is
221	 * usually 4k aligned.
222	 */
223	. = ALIGN(4);
224	} GROUP_LINK_IN(ROMABLE_REGION)
225
226#include <zephyr/linker/cplusplus-rom.ld>
227
228#if defined(CONFIG_BUILD_ALIGN_LMA)
229    /*
230     * Include a padding section here to make sure that the LMA address
231     * of the sections in the RAMABLE_REGION are aligned with those
232     * section's VMA alignment requirements.
233     */
234    SECTION_PROLOGUE(padding_section,,)
235	{
236	__rodata_region_end = .;
237	MPU_ALIGN(__rodata_region_end - ADDR(rom_start));
238	} GROUP_LINK_IN(ROMABLE_REGION)
239#else
240	__rodata_region_end = .;
241	MPU_ALIGN(__rodata_region_end - ADDR(rom_start));
242#endif
243	__rom_region_end = __rom_region_start + . - ADDR(rom_start);
244
245    GROUP_END(ROMABLE_REGION)
246
247    /*
248     * These are here according to 'arm-zephyr-elf-ld --verbose',
249     * before data section.
250     */
251    /DISCARD/ : {
252	*(.got.plt)
253	*(.igot.plt)
254	*(.got)
255	*(.igot)
256	}
257
258    GROUP_START(RAMABLE_REGION)
259
260	. = RAM_ADDR;
261	/* Align the start of image RAM with the
262	 * minimum granularity required by MPU.
263	 */
264	. = ALIGN(_region_min_align);
265	_image_ram_start = .;
266
267/* Located in generated directory. This file is populated by the
268 * zephyr_linker_sources() Cmake function.
269 */
270#include <snippets-ram-sections.ld>
271
272#if defined(CONFIG_USERSPACE)
273#define APP_SHARED_ALIGN . = ALIGN(_region_min_align);
274#define SMEM_PARTITION_ALIGN MPU_ALIGN
275
276#include <app_smem.ld>
277
278	_app_smem_size = _app_smem_end - _app_smem_start;
279	_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
280#endif  /* CONFIG_USERSPACE */
281
282    GROUP_START(DATA_REGION)
283
284    SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
285	{
286	__data_region_start = .;
287	__data_start = .;
288	*(.data)
289	*(".data.*")
290	*(".kernel.*")
291
292/* Located in generated directory. This file is populated by the
293 * zephyr_linker_sources() Cmake function.
294 */
295#include <snippets-rwdata.ld>
296
297#ifdef CONFIG_CODE_DATA_RELOCATION
298#include <linker_sram_data_relocate.ld>
299#endif
300	__data_end = .;
301
302	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
303    __data_size = __data_end - __data_start;
304    __data_load_start = LOADADDR(_DATA_SECTION_NAME);
305
306    __data_region_load_start = LOADADDR(_DATA_SECTION_NAME);
307
308#include <zephyr/linker/common-ram.ld>
309#include <zephyr/linker/kobject-data.ld>
310
311#include <zephyr/linker/cplusplus-ram.ld>
312
313/* Located in generated directory. This file is populated by the
314 * zephyr_linker_sources() Cmake function.
315 */
316#include <snippets-data-sections.ld>
317
318    __data_region_end = .;
319
320#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay)
321GROUP_START(ITCM)
322
323	SECTION_PROLOGUE(_ITCM_SECTION_NAME,,SUBALIGN(4))
324	{
325		__itcm_start = .;
326		*(.itcm)
327		*(".itcm.*")
328
329/* Located in generated directory. This file is populated by the
330 * zephyr_linker_sources() Cmake function. */
331#include <snippets-itcm-section.ld>
332
333		__itcm_end = .;
334	} GROUP_LINK_IN(ITCM AT> ROMABLE_REGION)
335
336	__itcm_size = __itcm_end - __itcm_start;
337	__itcm_load_start = LOADADDR(_ITCM_SECTION_NAME);
338
339GROUP_END(ITCM)
340#endif
341
342#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay)
343GROUP_START(DTCM)
344
345	SECTION_PROLOGUE(_DTCM_BSS_SECTION_NAME, (NOLOAD),SUBALIGN(4))
346	{
347		__dtcm_start = .;
348		__dtcm_bss_start = .;
349		*(.dtcm_bss)
350		*(".dtcm_bss.*")
351		__dtcm_bss_end = .;
352	} GROUP_LINK_IN(DTCM)
353
354	SECTION_PROLOGUE(_DTCM_NOINIT_SECTION_NAME, (NOLOAD),SUBALIGN(4))
355	{
356		__dtcm_noinit_start = .;
357		*(.dtcm_noinit)
358		*(".dtcm_noinit.*")
359		__dtcm_noinit_end = .;
360	} GROUP_LINK_IN(DTCM)
361
362	SECTION_PROLOGUE(_DTCM_DATA_SECTION_NAME,,SUBALIGN(4))
363	{
364		__dtcm_data_start = .;
365		*(.dtcm_data)
366		*(".dtcm_data.*")
367
368/* Located in generated directory. This file is populated by the
369 * zephyr_linker_sources() Cmake function. */
370#include <snippets-dtcm-section.ld>
371
372		__dtcm_data_end = .;
373	} GROUP_LINK_IN(DTCM AT> ROMABLE_REGION)
374
375	__dtcm_end = .;
376
377	__dtcm_data_load_start = LOADADDR(_DTCM_DATA_SECTION_NAME);
378
379GROUP_END(DTCM)
380#endif
381
382/* Located in generated directory. This file is populated by the
383 * zephyr_linker_sources() Cmake function.
384 */
385#include <snippets-sections.ld>
386
387#include <zephyr/linker/debug-sections.ld>
388
389    /DISCARD/ : { *(.note.GNU-stack) }
390
391    SECTION_PROLOGUE(.ARM.attributes, 0,)
392	{
393	KEEP(*(.ARM.attributes))
394	KEEP(*(.gnu.attributes))
395	}
396
397/* Output section descriptions are needed for these sections to suppress
398 * warnings when "--orphan-handling=warn" is set for lld.
399 */
400#if defined(CONFIG_LLVM_USE_LLD)
401    SECTION_PROLOGUE(.symtab, 0,) { *(.symtab) }
402    SECTION_PROLOGUE(.strtab, 0,) { *(.strtab) }
403    SECTION_PROLOGUE(.shstrtab, 0,) { *(.shstrtab) }
404#endif
405
406    /* Sections generated from 'zephyr,memory-region' nodes */
407    LINKER_DT_SECTIONS()
408
409/* Must be last in romable region */
410SECTION_PROLOGUE(.last_section,,)
411{
412#ifdef CONFIG_LINKER_LAST_SECTION_ID
413  /* Fill last section with a word to ensure location counter and actual rom
414   * region data usage match. */
415  LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
416#endif
417} GROUP_LINK_IN(ROMABLE_REGION)
418
419/* To provide the image size as a const expression,
420 * calculate this value here. */
421_flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start;
422
423    SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
424	{
425        /*
426         * For performance, BSS section is assumed to be 4 byte aligned and
427         * a multiple of 4 bytes
428         */
429        . = ALIGN(4);
430	__bss_start = .;
431	__kernel_ram_start = .;
432
433	*(.bss)
434	*(".bss.*")
435	*(COMMON)
436	*(".kernel_bss.*")
437
438#ifdef CONFIG_CODE_DATA_RELOCATION
439#include <linker_sram_bss_relocate.ld>
440#endif
441
442        /*
443         * As memory is cleared in words only, it is simpler to ensure the BSS
444         * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
445		 */
446	__bss_end = ALIGN(4);
447	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
448
449#include <zephyr/linker/common-noinit.ld>
450
451    /* Define linker symbols */
452
453    __kernel_ram_end = RAM_ADDR + RAM_SIZE;
454    __kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
455
456#include <zephyr/linker/ram-end.ld>
457
458    GROUP_END(RAMABLE_REGION)
459
460    }
461