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 Common linker sections 10 * 11 * This script defines the memory location of the various sections that make up 12 * a Zephyr Kernel image. This file is used by the linker. 13 * 14 * This script places the various sections of the image according to what 15 * features are enabled by the kernel's configuration options. 16 * 17 * For a build that does not use the execute in place (XIP) feature, the script 18 * generates an image suitable for loading into and executing from RAMABLE_REGION by 19 * placing all the sections adjacent to each other. There is also no separate 20 * load address for the DATA section which means it doesn't have to be copied 21 * into RAMABLE_REGION. 22 * 23 * For builds using XIP, there is a different load memory address (LMA) and 24 * virtual memory address (VMA) for the DATA section. In this case the DATA 25 * section is copied into RAMABLE_REGION at runtime. 26 * 27 * When building an XIP image the data section is placed into ROMABLE_REGION. In this 28 * case, the LMA is set to __data_rom_start so the data section is concatenated 29 * at the end of the RODATA section. At runtime, the DATA section is copied 30 * into the RAMABLE_REGION region so it can be accessed with read and write permission. 31 * 32 * Most symbols defined in the sections below are subject to be referenced in 33 * the Zephyr Kernel image. If a symbol is used but not defined the linker will 34 * emit an undefined symbol error. 35 * 36 * Please do not change the order of the section as the kernel expects this 37 * order when programming the MMU. 38 */ 39 40#include <zephyr/linker/linker-defs.h> 41#include <zephyr/offsets.h> 42#include <zephyr/sys/util.h> 43#include <zephyr/kernel/mm.h> 44 45#include <zephyr/linker/linker-tool.h> 46 47#if defined(CONFIG_XIP) || defined(K_MEM_IS_VM_KERNEL) 48 #define ROMABLE_REGION ROM 49 #define RAMABLE_REGION RAM 50#else 51 #define ROMABLE_REGION RAM 52 #define RAMABLE_REGION RAM 53#endif 54 55#ifdef CONFIG_MMU 56 #define MMU_PAGE_ALIGN . = ALIGN(CONFIG_MMU_PAGE_SIZE); 57#else 58 #define MMU_PAGE_ALIGN 59#endif 60 61/* Used to align areas with separate memory permission characteristics 62 * so that the page permissions can be set in the MMU. Without this, 63 * the kernel is just one blob with the same RWX permissions on all RAM 64 */ 65#ifdef CONFIG_SRAM_REGION_PERMISSIONS 66 #define MMU_PAGE_ALIGN_PERM MMU_PAGE_ALIGN 67#else 68 #define MMU_PAGE_ALIGN_PERM 69#endif 70 71epoint = K_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY); 72ENTRY(epoint) 73 74/* SECTIONS definitions */ 75SECTIONS 76 { 77 78#include <zephyr/linker/rel-sections.ld> 79 80#ifdef CONFIG_LLEXT 81#include <zephyr/linker/llext-sections.ld> 82#endif 83 84 /DISCARD/ : 85 { 86 *(.plt) 87 } 88 89 /DISCARD/ : 90 { 91 *(.iplt) 92 } 93 94#if defined(CONFIG_SOC_FAMILY_INTEL_ISH) && defined(CONFIG_PM) 95#include <zephyr/arch/x86/ia32/scripts/ish_aon.ld> 96#endif 97 98#ifdef CONFIG_LINKER_USE_BOOT_SECTION 99 100 SECTION_PROLOGUE(boot.text,,) 101 { 102#include <snippets-rom-start.ld> 103 104 MMU_PAGE_ALIGN 105 lnkr_boot_start = .; 106 z_mapped_start = .; 107 108 lnkr_boot_text_start = .; 109 110 KEEP(*(.boot_text.__start)) 111 *(.boot_text) 112 *(.boot_text.*) 113 114 MMU_PAGE_ALIGN_PERM 115 116 lnkr_boot_text_end = .; 117 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 118 119 SECTION_PROLOGUE(boot.rodata,,) 120 { 121 MMU_PAGE_ALIGN_PERM 122 123 lnkr_boot_rodata_start = .; 124 125 *(.boot_rodata) 126 *(.boot_rodata.*) 127 128 MMU_PAGE_ALIGN_PERM 129 130 lnkr_boot_rodata_end = .; 131 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 132 133 SECTION_PROLOGUE(boot.data,,) 134 { 135 MMU_PAGE_ALIGN_PERM 136 137 . = ALIGN(4); 138 139 lnkr_boot_data_start = .; 140 141 *(.boot_data) 142 *(.boot_data.*) 143 144 lnkr_boot_data_end = .; 145 } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 146 147 SECTION_PROLOGUE(boot.bss, (NOLOAD),) 148 { 149 . = ALIGN(4); 150 151 lnkr_boot_bss_start = .; 152 153 *(.boot_bss) 154 *(.boot_bss.*) 155 156 lnkr_boot_bss_end = .; 157 } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 158 159 SECTION_PROLOGUE(boot.noinit, (NOLOAD),) 160 { 161 . = ALIGN(4); 162 163 lnkr_boot_noinit_start = .; 164 165 *(.boot_noinit) 166 *(.boot_noinit.*) 167 168 lnkr_boot_noinit_end = .; 169 170 MMU_PAGE_ALIGN 171 172 lnkr_boot_end = .; 173 } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 174 175 lnkr_boot_text_size = lnkr_boot_text_end - lnkr_boot_text_start; 176 lnkr_boot_rodata_size = lnkr_boot_rodata_end - lnkr_boot_rodata_start; 177 lnkr_boot_data_size = lnkr_boot_data_end - lnkr_boot_data_start; 178 lnkr_boot_bss_size = lnkr_boot_bss_end - lnkr_boot_bss_start; 179 lnkr_boot_noinit_size = lnkr_boot_noinit_end - lnkr_boot_noinit_start; 180 181#endif /* CONFIG_LINKER_USE_BOOT_SECTION */ 182 183#ifdef CONFIG_LINKER_USE_PINNED_SECTION 184 185 SECTION_PROLOGUE(pinned.text,,) 186 { 187#ifndef CONFIG_LINKER_USE_BOOT_SECTION 188#include <snippets-rom-start.ld> 189#endif 190 191 MMU_PAGE_ALIGN 192 193 lnkr_pinned_start = .; 194 195#ifndef CONFIG_LINKER_USE_BOOT_SECTION 196 z_mapped_start = .; 197#endif 198 199 lnkr_pinned_text_start = .; 200 201 *(.pinned_text) 202 *(.pinned_text.*) 203 204 *(.gnu.linkonce.t.exc_*) 205 206#include <zephyr/linker/kobject-text.ld> 207 208 MMU_PAGE_ALIGN_PERM 209 210 lnkr_pinned_text_end = .; 211 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 212 213 MMU_PAGE_ALIGN_PERM 214 215 lnkr_pinned_rodata_start = .; 216 217#include <zephyr/linker/common-rom.ld> 218/* Located in generated directory. This file is populated by calling 219 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs. 220 */ 221#include <snippets-rom-sections.ld> 222#include <zephyr/linker/thread-local-storage.ld> 223 224 SECTION_PROLOGUE(pinned.rodata,,) 225 { 226#include <zephyr/arch/x86/ia32/scripts/static_intr.ld> 227 228 *(.pinned_rodata) 229 *(.pinned_rodata.*) 230 231#include <snippets-rodata.ld> 232 233#include <zephyr/linker/kobject-rom.ld> 234 235 MMU_PAGE_ALIGN_PERM 236 237 lnkr_pinned_rodata_end = .; 238 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 239 240 SECTION_PROLOGUE(pinned.data,,) 241 { 242 MMU_PAGE_ALIGN_PERM 243 244 lnkr_pinned_data_start = .; 245 246 . = ALIGN(4); 247 248#include <zephyr/arch/x86/ia32/scripts/shared_kernel_pages.ld> 249#include <zephyr/arch/x86/ia32/scripts/dynamic_intr.ld> 250 251 *(.pinned_data) 252 *(.pinned_data.*) 253 254 } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 255 256#include <zephyr/linker/common-ram.ld> 257#include <zephyr/arch/x86/pagetables.ld> 258#include <zephyr/linker/kobject-data.ld> 259 260 lnkr_pinned_data_end = .; 261 262 SECTION_PROLOGUE(pinned.bss, (NOLOAD),) 263 { 264 . = ALIGN(4); 265 266 lnkr_pinned_bss_start = .; 267 268 *(.pinned_bss) 269 *(.pinned_bss.*) 270 271 lnkr_pinned_bss_end = .; 272 } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 273 274 SECTION_PROLOGUE(pinned.noinit, (NOLOAD),) 275 { 276 . = ALIGN(4); 277 278 lnkr_pinned_noinit_start = .; 279 280 *(.pinned_noinit) 281 *(.pinned_noinit.*) 282 283 lnkr_pinned_noinit_end = .; 284 285 MMU_PAGE_ALIGN 286 287 lnkr_pinned_end = .; 288 289 } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 290 291 lnkr_pinned_text_size = lnkr_pinned_text_end - lnkr_pinned_text_start; 292 lnkr_pinned_rodata_size = lnkr_pinned_rodata_end - lnkr_pinned_rodata_start; 293 lnkr_pinned_data_size = lnkr_pinned_data_end - lnkr_pinned_data_start; 294 lnkr_pinned_bss_size = lnkr_pinned_bss_end - lnkr_pinned_bss_start; 295 lnkr_pinned_noinit_size = lnkr_pinned_noinit_end - lnkr_pinned_noinit_start; 296 297#endif /* CONFIG_LINKER_USE_PINNED_SECTION */ 298 299 GROUP_START(ROMABLE_REGION) 300 301 . = ALIGN(8); 302 303#ifdef CONFIG_XIP 304 __rom_region_start = PHYS_LOAD_ADDR; 305#endif 306 SECTION_PROLOGUE(_TEXT_SECTION_NAME,,) 307 { 308 __text_region_start = .; 309 310#if !defined(CONFIG_LINKER_USE_BOOT_SECTION) || \ 311 !defined(CONFIG_LINKER_USE_PINNED_SECTION) 312#ifndef CONFIG_XIP 313 z_mapped_start = .; 314#endif 315#endif 316 317#if !defined(CONFIG_LINKER_USE_BOOT_SECTION) || \ 318 !defined(CONFIG_LINKER_USE_PINNED_SECTION) 319/* Located in generated directory. This file is populated by calling 320 * zephyr_linker_sources(ROM_START ...). This typically contains the vector 321 * table and debug information. 322 */ 323#include <snippets-rom-start.ld> 324#endif 325 326 /* Needs KEEP() as ENTRY() is given a physical address */ 327 KEEP(*(.text.__start)) 328/* 329 * We need these sections to extract interrupt information, but they 330 * will be removed with "--gc-sections" by LLVM lld, so add keep 331 * command to save them. 332 */ 333#ifndef CONFIG_LLVM_USE_LD 334 KEEP(*(.text.irqstubs)) 335 KEEP(*(".gnu.linkonce.t.exc_*_stub")) 336#endif 337 *(.text) 338 *(".text.*") 339 *(.gnu.linkonce.t.*) 340 *(.init) 341 *(.fini) 342 *(.eini) 343 344#ifndef CONFIG_LINKER_USE_PINNED_SECTION 345#include <zephyr/linker/kobject-text.ld> 346#endif 347 348 MMU_PAGE_ALIGN_PERM 349 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 350 351 __text_region_end = .; 352 __text_region_size = __text_region_end - __text_region_start; 353 __rodata_region_start = .; 354 355#ifndef CONFIG_LINKER_USE_PINNED_SECTION 356#include <zephyr/linker/common-rom.ld> 357/* Located in generated directory. This file is populated by calling 358 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs. 359 */ 360#include <snippets-rom-sections.ld> 361#include <zephyr/linker/thread-local-storage.ld> 362#endif 363 364 SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) 365 { 366 *(.rodata) 367 *(".rodata.*") 368 *(.gnu.linkonce.r.*) 369 370#ifndef CONFIG_DYNAMIC_INTERRUPTS 371#ifndef CONFIG_LINKER_USE_PINNED_SECTION 372#include <zephyr/arch/x86/ia32/scripts/static_intr.ld> 373#endif /* !CONFIG_LINKER_USE_PINNED_SECTION */ 374#endif /* CONFIG_DYNAMIC_INTERRUPTS */ 375 376#ifndef CONFIG_LINKER_USE_PINNED_SECTION 377/* Located in generated directory. This file is populated by the 378 * zephyr_linker_sources() Cmake function. 379 */ 380#include <snippets-rodata.ld> 381 382#include <zephyr/linker/kobject-rom.ld> 383#endif 384 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 385 386#include <zephyr/linker/cplusplus-rom.ld> 387 388 MMU_PAGE_ALIGN_PERM 389 /* ROM ends here, position counter will now be in RAM areas */ 390#ifdef CONFIG_XIP 391 __rom_region_end = .; 392 __rom_region_size = __rom_region_end - __rom_region_start; 393#endif 394 __rodata_region_end = .; 395 __rodata_region_size = __rodata_region_end - __rodata_region_start; 396 GROUP_END(ROMABLE_REGION) 397 /* 398 * Needed for dynamic linking which we do not have, do discard 399 */ 400 /DISCARD/ : { 401 *(.got.plt) 402 *(.igot.plt) 403 *(.got) 404 *(.igot) 405 } 406 /* RAMABLE_REGION */ 407 GROUP_START(RAMABLE_REGION) 408 409#ifdef CONFIG_XIP 410 MMU_PAGE_ALIGN 411 z_mapped_start = .; 412#endif 413/* Located in generated directory. This file is populated by the 414 * zephyr_linker_sources() Cmake function. 415 */ 416#include <snippets-ram-sections.ld> 417 418#ifdef CONFIG_USERSPACE 419 /* APP SHARED MEMORY REGION */ 420#define SMEM_PARTITION_ALIGN(size) MMU_PAGE_ALIGN_PERM 421#define APP_SHARED_ALIGN MMU_PAGE_ALIGN_PERM 422 423#include <app_smem.ld> 424 425 _image_ram_start = _app_smem_start; 426 _app_smem_size = _app_smem_end - _app_smem_start; 427 _app_smem_num_words = _app_smem_size >> 2; 428 _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); 429 _app_smem_num_words = _app_smem_size >> 2; 430#endif /* CONFIG_USERSPACE */ 431 432 SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,) 433 { 434 435 MMU_PAGE_ALIGN_PERM 436 __data_region_start = .; 437 __data_start = .; 438 439 *(.data) 440 *(".data.*") 441 *(".kernel.*") 442 443#ifdef CONFIG_DYNAMIC_INTERRUPTS 444#ifndef CONFIG_LINKER_USE_PINNED_SECTION 445#include <zephyr/arch/x86/ia32/scripts/dynamic_intr.ld> 446#endif /* !CONFIG_LINKER_USE_PINNED_SECTION */ 447#endif /* CONFIG_DYNAMIC_INTERRUPTS */ 448 449/* Located in generated directory. This file is populated by the 450 * zephyr_linker_sources() Cmake function. 451 */ 452#include <snippets-rwdata.ld> 453 454#ifndef CONFIG_LINKER_USE_PINNED_SECTION 455#include <zephyr/arch/x86/ia32/scripts/shared_kernel_pages.ld> 456#endif /* !CONFIG_LINKER_USE_PINNED_SECTION */ 457 458 . = ALIGN(4); 459 __data_end = .; 460 461 } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 462 __data_size = __data_end - __data_start; 463 __data_load_start = LOADADDR(_DATA_SECTION_NAME); 464 465 __data_region_load_start = LOADADDR(_DATA_SECTION_NAME); 466 467#include <zephyr/linker/cplusplus-ram.ld> 468 469#ifndef CONFIG_LINKER_USE_PINNED_SECTION 470#include <zephyr/linker/common-ram.ld> 471#include <zephyr/arch/x86/pagetables.ld> 472 473/* Must be last in RAM */ 474#include <zephyr/linker/kobject-data.ld> 475#endif /* !CONFIG_LINKER_USE_PINNED_SECTION */ 476 477/* Located in generated directory. This file is populated by the 478 * zephyr_linker_sources() Cmake function. 479 */ 480#include <snippets-data-sections.ld> 481 482 MMU_PAGE_ALIGN 483 __data_region_end = .; 484 485 SECTION_PROLOGUE(_BSS_SECTION_NAME, (NOLOAD),) 486 { 487 MMU_PAGE_ALIGN_PERM 488#if !defined(CONFIG_USERSPACE) 489 _image_ram_start = .; 490#endif 491 /* 492 * For performance, BSS section is forced to be both 4 byte aligned and 493 * a multiple of 4 bytes. 494 */ 495 . = ALIGN(4); 496 __kernel_ram_start = .; 497 __bss_start = .; 498 499 *(.bss) 500 *(".bss.*") 501 *(COMMON) 502 *(".kernel_bss.*") 503 504 /* 505 * As memory is cleared in words only, it is simpler to ensure the BSS 506 * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes. 507 */ 508 . = ALIGN(4); 509 __bss_end = .; 510 } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 511 512 __bss_num_words = (__bss_end - __bss_start) >> 2; 513 514#include <zephyr/linker/common-noinit.ld> 515 516 MMU_PAGE_ALIGN_PERM 517 518 /* All unused memory also owned by the kernel for heaps */ 519 __kernel_ram_end = KERNEL_BASE_ADDR + KERNEL_RAM_SIZE; 520 __kernel_ram_size = __kernel_ram_end - __kernel_ram_start; 521 522 _image_ram_all = (KERNEL_BASE_ADDR + KERNEL_RAM_SIZE) - _image_ram_start; 523 524 z_mapped_end = .; 525 z_mapped_size = z_mapped_end - z_mapped_start; 526 527#ifndef LINKER_ZEPHYR_FINAL 528 /* static interrupts */ 529 SECTION_PROLOGUE(intList,,) 530 { 531 KEEP(*(.spurIsr)) 532 KEEP(*(.spurNoErrIsr)) 533 KEEP(*(.intList)) 534 KEEP(*(.gnu.linkonce.intList.*)) 535 } > IDT_LIST 536#else 537 /DISCARD/ : 538 { 539 KEEP(*(.spurIsr)) 540 KEEP(*(.spurNoErrIsr)) 541 KEEP(*(.intList)) 542 KEEP(*(.gnu.linkonce.intList.*)) 543 } 544#endif 545 546 547 548/* Located in generated directory. This file is populated by the 549 * zephyr_linker_sources() Cmake function. 550 */ 551#include <snippets-sections.ld> 552 553#include <zephyr/linker/ram-end.ld> 554 555 GROUP_END(RAMABLE_REGION) 556 557#include <zephyr/linker/debug-sections.ld> 558 559 /DISCARD/ : { *(.note.GNU-stack) } 560/* 561 * eh_frame section won't be removed even with "--gc-sections" by LLVM lld. 562 */ 563#if !defined(CONFIG_CPP_EXCEPTIONS) 564 /DISCARD/ : { *(.eh_frame) } 565#endif 566 567/* 568 * The sections below are still treated as warnings 569 * with "--orphan-handling=warn" by LLVM lld. 570 */ 571#if !defined(CONFIG_LLVM_USE_LD) 572 .symtab 0 : { *(.symtab) } 573 .strtab 0 : { *(.strtab) } 574 .shstrtab 0 : { *(.shstrtab) } 575#endif 576 577 /* Sections generated from 'zephyr,memory-region' nodes */ 578 LINKER_DT_SECTIONS() 579} 580 581#ifdef CONFIG_XIP 582/* 583 * Round up number of words for DATA section to ensure that XIP copies the 584 * entire data section. XIP copy is done in words only, so there may be up 585 * to 3 extra bytes copied in next section (BSS). At run time, the XIP copy 586 * is done first followed by clearing the BSS section. 587 */ 588__data_size = (__data_region_end - __data_region_start); 589__data_num_words = (__data_size + 3) >> 2; 590#endif 591