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