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