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