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
281    SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
282	{
283        /*
284         * For performance, BSS section is assumed to be 4 byte aligned and
285         * a multiple of 4 bytes
286         */
287        . = ALIGN(4);
288	__bss_start = .;
289	__kernel_ram_start = .;
290
291	*(.bss)
292	*(".bss.*")
293	*(COMMON)
294	*(".kernel_bss.*")
295
296#ifdef CONFIG_CODE_DATA_RELOCATION
297#include <linker_sram_bss_relocate.ld>
298#endif
299
300        /*
301         * As memory is cleared in words only, it is simpler to ensure the BSS
302         * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
303		 */
304	__bss_end = ALIGN(4);
305	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
306
307#include <zephyr/linker/common-noinit.ld>
308
309#endif  /* CONFIG_USERSPACE */
310
311    GROUP_START(DATA_REGION)
312
313    SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
314	{
315	__data_region_start = .;
316	__data_start = .;
317	*(.data)
318	*(".data.*")
319	*(".kernel.*")
320
321/* Located in generated directory. This file is populated by the
322 * zephyr_linker_sources() Cmake function.
323 */
324#include <snippets-rwdata.ld>
325
326#ifdef CONFIG_CODE_DATA_RELOCATION
327#include <linker_sram_data_relocate.ld>
328#endif
329	__data_end = .;
330
331	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
332    __data_size = __data_end - __data_start;
333    __data_load_start = LOADADDR(_DATA_SECTION_NAME);
334
335    __data_region_load_start = LOADADDR(_DATA_SECTION_NAME);
336
337#include <zephyr/linker/common-ram.ld>
338#include <zephyr/linker/kobject-data.ld>
339
340#include <zephyr/linker/cplusplus-ram.ld>
341
342/* Located in generated directory. This file is populated by the
343 * zephyr_linker_sources() Cmake function.
344 */
345#include <snippets-data-sections.ld>
346
347    __data_region_end = .;
348
349#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay)
350GROUP_START(ITCM)
351
352	SECTION_PROLOGUE(_ITCM_SECTION_NAME,,SUBALIGN(4))
353	{
354		__itcm_start = .;
355		*(.itcm)
356		*(".itcm.*")
357
358/* Located in generated directory. This file is populated by the
359 * zephyr_linker_sources() Cmake function. */
360#include <snippets-itcm-section.ld>
361
362		__itcm_end = .;
363	} GROUP_LINK_IN(ITCM AT> ROMABLE_REGION)
364
365	__itcm_size = __itcm_end - __itcm_start;
366	__itcm_load_start = LOADADDR(_ITCM_SECTION_NAME);
367
368GROUP_END(ITCM)
369#endif
370
371#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay)
372GROUP_START(DTCM)
373
374	SECTION_PROLOGUE(_DTCM_BSS_SECTION_NAME, (NOLOAD),SUBALIGN(4))
375	{
376		__dtcm_start = .;
377		__dtcm_bss_start = .;
378		*(.dtcm_bss)
379		*(".dtcm_bss.*")
380		__dtcm_bss_end = .;
381	} GROUP_LINK_IN(DTCM)
382
383	SECTION_PROLOGUE(_DTCM_NOINIT_SECTION_NAME, (NOLOAD),SUBALIGN(4))
384	{
385		__dtcm_noinit_start = .;
386		*(.dtcm_noinit)
387		*(".dtcm_noinit.*")
388		__dtcm_noinit_end = .;
389	} GROUP_LINK_IN(DTCM)
390
391	SECTION_PROLOGUE(_DTCM_DATA_SECTION_NAME,,SUBALIGN(4))
392	{
393		__dtcm_data_start = .;
394		*(.dtcm_data)
395		*(".dtcm_data.*")
396
397/* Located in generated directory. This file is populated by the
398 * zephyr_linker_sources() Cmake function. */
399#include <snippets-dtcm-section.ld>
400
401		__dtcm_data_end = .;
402	} GROUP_LINK_IN(DTCM AT> ROMABLE_REGION)
403
404	__dtcm_end = .;
405
406	__dtcm_data_load_start = LOADADDR(_DTCM_DATA_SECTION_NAME);
407
408GROUP_END(DTCM)
409#endif
410
411/* Located in generated directory. This file is populated by the
412 * zephyr_linker_sources() Cmake function.
413 */
414#include <snippets-sections.ld>
415
416#include <zephyr/linker/debug-sections.ld>
417
418    /DISCARD/ : { *(.note.GNU-stack) }
419
420    SECTION_PROLOGUE(.ARM.attributes, 0,)
421	{
422	KEEP(*(.ARM.attributes))
423	KEEP(*(.gnu.attributes))
424	}
425
426/* Output section descriptions are needed for these sections to suppress
427 * warnings when "--orphan-handling=warn" is set for lld.
428 */
429#if defined(CONFIG_LLVM_USE_LLD)
430    SECTION_PROLOGUE(.symtab, 0,) { *(.symtab) }
431    SECTION_PROLOGUE(.strtab, 0,) { *(.strtab) }
432    SECTION_PROLOGUE(.shstrtab, 0,) { *(.shstrtab) }
433#endif
434
435    /* Sections generated from 'zephyr,memory-region' nodes */
436    LINKER_DT_SECTIONS()
437
438/* Must be last in romable region */
439SECTION_PROLOGUE(.last_section,,)
440{
441#ifdef CONFIG_LINKER_LAST_SECTION_ID
442  /* Fill last section with a word to ensure location counter and actual rom
443   * region data usage match. */
444  LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
445#endif
446} GROUP_LINK_IN(ROMABLE_REGION)
447
448/* To provide the image size as a const expression,
449 * calculate this value here. */
450_flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start;
451
452#ifndef CONFIG_USERSPACE
453   SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
454	{
455        /*
456         * For performance, BSS section is assumed to be 4 byte aligned and
457         * a multiple of 4 bytes
458         */
459        . = ALIGN(4);
460	__bss_start = .;
461	__kernel_ram_start = .;
462
463	*(.bss)
464	*(".bss.*")
465	*(COMMON)
466	*(".kernel_bss.*")
467
468#ifdef CONFIG_CODE_DATA_RELOCATION
469#include <linker_sram_bss_relocate.ld>
470#endif
471
472        /*
473         * As memory is cleared in words only, it is simpler to ensure the BSS
474         * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
475		 */
476	__bss_end = ALIGN(4);
477	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
478
479    SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),)
480        {
481        /*
482         * This section is used for non-initialized objects that
483         * will not be cleared during the boot process.
484         */
485        *(.noinit)
486        *(".noinit.*")
487	*(".kernel_noinit.*")
488
489/* Located in generated directory. This file is populated by the
490 * zephyr_linker_sources() Cmake function.
491 */
492#include <snippets-noinit.ld>
493
494        } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
495#endif /* CONFIG_USERSPACE */
496
497    /* Define linker symbols */
498
499    __kernel_ram_end = RAM_ADDR + RAM_SIZE;
500    __kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
501
502#include <zephyr/linker/ram-end.ld>
503
504    GROUP_END(RAMABLE_REGION)
505
506    }
507