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-A 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 * 1K - CONFIG_FLASH_LOAD_OFFSET - ROM_END_OFFSET)
45#endif
46
47#define RAM_SIZE (CONFIG_SRAM_SIZE * 1K)
48#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
49
50#if defined(CONFIG_ARM_MMU)
51  _region_min_align = CONFIG_MMU_PAGE_SIZE;
52#elif defined(CONFIG_ARM_MPU)
53  _region_min_align = CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE;
54  #define BSS_ALIGN ALIGN(_region_min_align)
55#else
56  /* If building without MMU support, use default 8-byte alignment. */
57  _region_min_align = 8;
58#endif
59
60#ifndef BSS_ALIGN
61#define BSS_ALIGN
62#endif
63
64#define MMU_ALIGN    . = ALIGN(_region_min_align)
65
66MEMORY
67{
68    FLASH     (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE
69    RAM       (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
70    LINKER_DT_REGIONS()
71    /* Used by and documented in include/linker/intlist.ld */
72    IDT_LIST  (wx) : ORIGIN = 0xFFFF8000, LENGTH = 32K
73#ifdef CONFIG_LINKER_USE_ONDEMAND_SECTION
74    ONDEMAND (rx) : ORIGIN = (CONFIG_KERNEL_VM_BASE), LENGTH = (CONFIG_KERNEL_VM_SIZE)
75#endif
76}
77
78ENTRY(CONFIG_KERNEL_ENTRY)
79
80SECTIONS
81{
82
83#include <zephyr/linker/rel-sections.ld>
84#include <zephyr/linker/llext-sections.ld>
85
86    /*
87     * .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose',
88     * before text section.
89     */
90    /DISCARD/ :
91    {
92        *(.plt)
93    }
94
95    /DISCARD/ :
96    {
97        *(.iplt)
98    }
99
100    GROUP_START(ROMABLE_REGION)
101
102    __rom_region_start = ROM_ADDR;
103
104    SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
105    {
106        __text_region_start = .;
107#ifndef CONFIG_XIP
108        z_mapped_start = .;
109#endif
110
111#ifdef CONFIG_AARCH64_IMAGE_HEADER
112        KEEP(*(.image_header))
113        KEEP(*(".image_header.*"))
114#endif
115
116        _vector_start = .;
117        KEEP(*(.exc_vector_table))
118        KEEP(*(".exc_vector_table.*"))
119
120#if LINKER_ZEPHYR_FINAL && defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION)
121        INCLUDE isr_tables_vt.ld
122#else
123        KEEP(*(.vectors))
124#endif
125        _vector_end = .;
126
127        *(.text)
128        *(".text.*")
129        *(.gnu.linkonce.t.*)
130
131#include <snippets-text-sections.ld>
132
133#include <zephyr/linker/kobject-text.ld>
134
135        MMU_ALIGN;
136    } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
137
138    __text_region_end = .;
139    __text_region_size = __text_region_end - __text_region_start;
140
141    MMU_ALIGN;
142    __rodata_region_start = .;
143
144#if defined (CONFIG_CPP)
145    SECTION_PROLOGUE(.ARM.extab,,)
146    {
147        /*
148         * .ARM.extab section containing exception unwinding information.
149         */
150        *(.ARM.extab* .gnu.linkonce.armextab.*)
151    } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
152#endif
153
154    SECTION_PROLOGUE(.ARM.exidx,,)
155    {
156        /*
157         * This section, related to stack and exception unwinding, is placed
158         * explicitly to prevent it from being shared between multiple regions.
159         * It  must be defined for gcc to support 64-bit math and avoid
160         * section overlap.
161         */
162        __exidx_start = .;
163#if defined (__GCC_LINKER_CMD__)
164        *(.ARM.exidx* gnu.linkonce.armexidx.*)
165#endif
166        __exidx_end = .;
167    } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
168
169#include <zephyr/linker/common-rom.ld>
170#include <snippets-rom-sections.ld>
171#include <zephyr/linker/thread-local-storage.ld>
172
173    SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
174    {
175        *(.rodata)
176        *(".rodata.*")
177        *(.gnu.linkonce.r.*)
178
179        /*
180         * The following is a workaround to allow compiling with GCC 12 and
181         * above, which may emit "GOT indirections" for the weak symbol
182         * references (see the GitHub issue zephyrproject-rtos/sdk-ng#547).
183         */
184        *(.got)
185        *(.got.plt)
186
187#include <snippets-rodata.ld>
188
189#include <zephyr/linker/kobject-rom.ld>
190
191    } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
192
193#include <zephyr/linker/cplusplus-rom.ld>
194
195    MMU_ALIGN;
196    __rodata_region_end = .;
197    __rodata_region_size = __rodata_region_end - __rodata_region_start;
198    __rom_region_end = .;
199
200    /*
201     * These are here according to 'arm-zephyr-elf-ld --verbose',
202     * before data section.
203     */
204    /DISCARD/ :
205    {
206        *(.igot.plt)
207        *(.igot)
208    }
209
210    GROUP_END(ROMABLE_REGION)
211
212    GROUP_START(RAMABLE_REGION)
213
214#ifdef CONFIG_XIP
215    . = RAM_ADDR;
216#endif
217    MMU_ALIGN;
218    _image_ram_start = .;
219#ifdef CONFIG_XIP
220    z_mapped_start = .;
221#endif
222
223#if defined(CONFIG_USERSPACE)
224#define APP_SHARED_ALIGN . = ALIGN(_region_min_align);
225#define SMEM_PARTITION_ALIGN(size) MMU_ALIGN
226
227#if defined(CONFIG_ARM_MPU)
228/*
229 * When _app_smem region is empty, alignment is also needed. If there
230 * is no alignment, the _app_smem_start used by arm mpu can be lower
231 * than __rodata_region_end, and this two regions can overlap.
232 * The Armv8-R aarch64 MPU does not allow overlapped regions.
233 */
234#define EMPTY_APP_SHARED_ALIGN APP_SHARED_ALIGN
235#endif
236
237#include <app_smem.ld>
238
239    _app_smem_size = _app_smem_end - _app_smem_start;
240    _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
241#endif  /* CONFIG_USERSPACE */
242
243    __kernel_ram_start = .;
244    __data_region_start = .;
245
246    SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
247    {
248        MMU_ALIGN;
249	__data_start = .;
250        *(.data)
251        *(".data.*")
252        *(".kernel.*")
253
254#include <snippets-rwdata.ld>
255
256        __data_end = .;
257    } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
258    __data_size = __data_end - __data_start;
259    __data_load_start = LOADADDR(_DATA_SECTION_NAME);
260
261#include <snippets-ram-sections.ld>
262
263#include <zephyr/linker/common-ram.ld>
264#include <zephyr/linker/kobject-data.ld>
265#include <zephyr/linker/cplusplus-ram.ld>
266
267#include <snippets-data-sections.ld>
268
269    __data_region_end = .;
270    __data_region_load_start = LOADADDR(_DATA_SECTION_NAME);
271
272    SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD), BSS_ALIGN)
273    {
274        . = ALIGN(8);
275        __bss_start = .;
276
277        *(.bss)
278        *(".bss.*")
279        *(COMMON)
280        *(".kernel_bss.*")
281
282        __bss_end = ALIGN(8);
283    } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
284
285#include <zephyr/linker/common-noinit.ld>
286
287    /* Define linker symbols */
288    __kernel_ram_end = RAM_ADDR + RAM_SIZE;
289    __kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
290
291#include <snippets-sections.ld>
292
293#define LAST_RAM_ALIGN MMU_ALIGN;
294
295#include <zephyr/linker/ram-end.ld>
296
297    GROUP_END(RAMABLE_REGION)
298
299#ifdef CONFIG_LINKER_USE_ONDEMAND_SECTION
300    . = z_mapped_end;
301    MMU_ALIGN;
302    lnkr_ondemand_start = .;
303
304    ONDEMAND_TEXT_SECTION_NAME (.) : AT(ADDR(_BSS_SECTION_NAME))
305    {
306        lnkr_ondemand_text_start = .;
307        *(.ondemand_text)
308        *(.ondemand_text.*)
309        MMU_ALIGN;
310        lnkr_ondemand_text_end = .;
311    } > ONDEMAND
312    lnkr_ondemand_text_size = SIZEOF(ONDEMAND_TEXT_SECTION_NAME);
313
314    ONDEMAND_RODATA_SECTION_NAME :
315    {
316        lnkr_ondemand_rodata_start = .;
317        *(.ondemand_rodata)
318        *(.ondemand_rodata.*)
319        MMU_ALIGN;
320        lnkr_ondemand_rodata_end = .;
321    } > ONDEMAND
322    lnkr_ondemand_rodata_size = SIZEOF(ONDEMAND_RODATA_SECTION_NAME);
323
324    lnkr_ondemand_end = .;
325    lnkr_ondemand_load_start = LOADADDR(ONDEMAND_TEXT_SECTION_NAME);
326#endif
327
328#include <zephyr/linker/debug-sections.ld>
329
330    SECTION_PROLOGUE(.ARM.attributes, 0,)
331    {
332        KEEP(*(.ARM.attributes))
333        KEEP(*(.gnu.attributes))
334    }
335
336    /DISCARD/ : { *(.note.GNU-stack) }
337
338/* Output section descriptions are needed for these sections to suppress
339 * warnings when "--orphan-handling=warn" is set for lld.
340 */
341#if defined(CONFIG_LLVM_USE_LLD)
342    SECTION_PROLOGUE(.symtab, 0,) { *(.symtab) }
343    SECTION_PROLOGUE(.strtab, 0,) { *(.strtab) }
344    SECTION_PROLOGUE(.shstrtab, 0,) { *(.shstrtab) }
345#endif
346
347    /* Sections generated from 'zephyr,memory-region' nodes */
348    LINKER_DT_SECTIONS()
349
350    /* Must be last in romable region */
351    SECTION_PROLOGUE(.last_section,,)
352    {
353      /* .last_section contains a fixed word to ensure location counter and actual
354       * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
355      KEEP(*(.last_section))
356    } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
357
358    /* To provide the image size as a const expression,
359     * calculate this value here. */
360    _flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start;
361
362}
363