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