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