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