1/* 2 * Copyright (c) 2013-2014 Wind River Systems, Inc. 3 * Copyright (c) 2021 Intel Corporation 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8#include <zephyr/devicetree.h> 9#include <zephyr/offsets.h> 10#include <zephyr/linker/linker-defs.h> 11#include <zephyr/linker/linker-tool.h> 12#include <zephyr/sys/util.h> 13#include <zephyr/kernel/mm.h> 14 15 16/* Bounds of physical RAM from DTS */ 17#define PHYS_RAM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_sram)) 18#define PHYS_RAM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) 19 20/* Bounds of flash from DTS */ 21#define FLASH_ROM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) 22#define FLASH_ROM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) 23 24/* Virtual base address for the kernel; with CONFIG_MMU this is not necessarily 25 * the same as its physical location, although an identity mapping for RAM 26 * is still supported by setting CONFIG_KERNEL_VM_BASE=CONFIG_SRAM_BASE_ADDRESS. 27 */ 28#ifdef K_MEM_IS_VM_KERNEL 29 30#define KERNEL_BASE_ADDR \ 31 (CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) 32 33#define KERNEL_RAM_SIZE \ 34 (CONFIG_KERNEL_VM_SIZE - CONFIG_KERNEL_VM_OFFSET) 35 36#define PHYS_RAM_AVAIL \ 37 (PHYS_RAM_SIZE - CONFIG_SRAM_OFFSET) 38 39#else 40 41#define KERNEL_BASE_ADDR (PHYS_RAM_ADDR + CONFIG_SRAM_OFFSET) 42#define KERNEL_RAM_SIZE (PHYS_RAM_SIZE - CONFIG_SRAM_OFFSET) 43 44#endif 45 46/* "kernel RAM" for linker VMA allocations starts at the offset */ 47 48/* Physical RAM location where the kernel image is loaded */ 49#define PHYS_LOAD_ADDR (PHYS_RAM_ADDR + CONFIG_SRAM_OFFSET) 50 51#ifdef CONFIG_USERSPACE 52#define SMEM_PARTITION_ALIGN(size) MMU_PAGE_ALIGN_PERM 53#define APP_SHARED_ALIGN MMU_PAGE_ALIGN_PERM 54#endif 55 56MEMORY 57 { 58#if defined(K_MEM_IS_VM_KERNEL) 59 ROM (rx) : ORIGIN = PHYS_LOAD_ADDR, LENGTH = PHYS_RAM_AVAIL 60#endif 61 RAM (wx) : ORIGIN = KERNEL_BASE_ADDR, LENGTH = KERNEL_RAM_SIZE 62 63#if defined(CONFIG_DEMAND_PAGING) && !defined(CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT) 64 FLASH (rw) : ORIGIN = FLASH_ROM_ADDR, LENGTH = FLASH_ROM_SIZE 65#endif 66 67 /* 68 * On 32-bit x86, fake memory area for build-time IDT generation data. 69 * 70 * It doesn't matter where this region goes as it is stripped from the 71 * final ELF image. The address doesn't even have to be valid on the 72 * target. However, it shouldn't overlap any other regions. 73 */ 74 75 IDT_LIST : ORIGIN = 0xFFFF1000, LENGTH = 2K 76 } 77 78#if defined(K_MEM_IS_VM_KERNEL) 79 #define ROMABLE_REGION ROM 80 #define RAMABLE_REGION RAM 81#else 82 #define ROMABLE_REGION RAM 83 #define RAMABLE_REGION RAM 84#endif 85 86#ifdef CONFIG_MMU 87 #define MMU_PAGE_ALIGN . = ALIGN(CONFIG_MMU_PAGE_SIZE); 88#else 89 #define MMU_PAGE_ALIGN 90#endif 91 92#if defined(CONFIG_DEMAND_PAGING) && !defined(CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT) 93 94#undef SECTION_PROLOGUE 95#define SECTION_PROLOGUE(name, options, align) \ 96 name options : ALIGN_WITH_INPUT align 97 98#undef SECTION_DATA_PROLOGUE 99#define SECTION_DATA_PROLOGUE(name, options, align) \ 100 name options : ALIGN_WITH_INPUT align 101 102#undef GROUP_ROM_LINK_IN 103#define GROUP_ROM_LINK_IN(vregion, lregion) > vregion AT > lregion 104 105#undef GROUP_DATA_LINK_IN 106#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion 107 108#undef GROUP_NOLOAD_LINK_IN 109#define GROUP_NOLOAD_LINK_IN(vregion, lregion) > vregion AT > lregion 110 111#endif 112 113/* Used to align areas with separate memory permission characteristics 114 * so that the page permissions can be set in the MMU. Without this, 115 * the kernel is just one blob with the same RWX permissions on all RAM 116 */ 117#ifdef CONFIG_SRAM_REGION_PERMISSIONS 118 #define MMU_PAGE_ALIGN_PERM MMU_PAGE_ALIGN 119#else 120 #define MMU_PAGE_ALIGN_PERM 121#endif 122 123/* For all source files under arch/x86/. */ 124#define LIB_ARCH_X86_IN_SECT(lsect) \ 125 *libarch__x86__core.a.a:(.##lsect) \ 126 *libarch__x86__core.a:(.##lsect##.*) 127 128#ifdef CONFIG_MINIMAL_LIBC 129/* For all source files under lib/libc/minimal/. 130 * These files includes, for example, math and string functions. 131 */ 132#define LIB_C_IN_SECT(lsect) \ 133 *liblib__libc__minimal.a:(.##lsect) \ 134 *liblib__libc__minimal.a:(.##lsect##.*) 135 136#endif /* CONFIG_MINIMAL_LIBC */ 137 138#ifdef CONFIG_NEWLIB_LIBC 139/* For Newlib libc-hook.c. */ 140#define LIB_C_IN_SECT(lsect) \ 141 *liblib__libc__newlib.a:libc-hooks.c.obj(.##lsect) \ 142 *liblib__libc__newlib.a:libc-hooks.c.obj(.##lsect##.*) 143 144#endif /* CONFIG_NEWLIB_LIBC */ 145 146#ifdef CONFIG_PICOLIBC 147/* For Picolibc, all files under lib/libc/picolibc */ 148#define LIB_C_IN_SECT(lsect) \ 149 *liblib__libc__picolibc.a:(.##lsect) \ 150 *liblib__libc__picolibc.a:(.##lsect##.*) 151 152#endif /* CONFIG_PICOLIBC */ 153 154/* 155 * For drivers that are usually used (e.g. serial) 156 */ 157#define LIB_DRIVERS_IN_SECT(lsect) \ 158 *libdrivers__serial.a:(.##lsect) \ 159 *libdrivers__serial.a:(.##lsect##.*) \ 160 *hpet.c.obj(.##lsect) \ 161 *hpet.c.obj(.##lsect##.*) \ 162 *intc_ioapic.c.obj(.##lsect) \ 163 *intc_ioapic.c.obj(.##lsect##.*) \ 164 *intc_loapic.c.obj(.##lsect) \ 165 *intc_loapic.c.obj(.##lsect##.*) \ 166 *intc_system_apic.c.obj(.##lsect) \ 167 *intc_system_apic.c.obj(.##lsect##.*) \ 168 *random_timer.c.obj(.##lsect) \ 169 *random_timer.c.obj(.##lsect##.*) \ 170 *uart_console.c.obj(.##lsect) \ 171 *uart_console.c.obj(.##lsect##.*) 172 173/* For all source files under kernel/. and kernel related files */ 174#define LIB_KERNEL_IN_SECT(lsect) \ 175 *libkernel.a:(.##lsect) \ 176 *libkernel.a:(.##lsect##.*) \ 177 *libsubsys__demand_paging__*.a:(.##lsect) \ 178 *libsubsys__demand_paging__*.a:(.##lsect##.*) 179 180/* For particular file packaged in libzephyr.a. */ 181#define LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, objfile) \ 182 *libzephyr.a:objfile.c.obj(.##lsect) \ 183 *libzephyr.a:objfile.c.obj(.##lsect##.*) 184 185/* For source files under lib/os/ with commonly used functions. */ 186#define LIB_ZEPHYR_IN_SECT(lsect) \ 187 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, assert) \ 188 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, bitarray) \ 189 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, cbprintf_complete) \ 190 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, cbprintf_nano) \ 191 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, configs) \ 192 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, coverage) \ 193 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, heap) \ 194 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, heap-validate) \ 195 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, mutex) \ 196 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, notify) \ 197 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, printk) \ 198 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, sem) \ 199 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, stdout_console) \ 200 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, sys_clock_init) \ 201 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, rb) \ 202 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, tracing_none) \ 203 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, tracing_tracking) \ 204 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, thread_entry) \ 205 LIB_ZEPHYR_OBJECT_FILE_IN_SECT(lsect, work_q) 206 207/* 208 * Catch all for all internal/external kernel functions 209 * as they are usually defined as "static inline" where 210 * they are attached to the source which uses them. 211 * Hence the need to specify them here so they can be pinned. 212 */ 213#define ZEPHYR_KERNEL_FUNCS_IN_SECT \ 214 *(.text.atomic_*) \ 215 *(.text.k_*) \ 216 *(.text.sys_*_bit) \ 217 *(.text.sys_bitfield_*) \ 218 *(.text.sys_clock_hw_cycles_per_sec) \ 219 *(.text.sys_cache_*) \ 220 *(.text.sys_dcache_*) \ 221 *(.text.sys_icache_*) \ 222 *(.text.sys_mutex_*) \ 223 *(.text.sys_notify_*) \ 224 *(.text.sys_dlist_*) \ 225 *(.text.sys_slist_*) \ 226 *(.text.sys_sflist_*) \ 227 *(.text.sys_sfnode_*) \ 228 *(.text.sys_io_*) \ 229 *(.text.sys_in*) \ 230 *(.text.sys_out*) \ 231 *(.text.sys_read*) \ 232 *(.text.sys_write*) \ 233 *(.text.sys_get_be*) \ 234 *(.text.sys_get_le*) \ 235 *(.text.sys_put_be*) \ 236 *(.text.sys_put_le*) \ 237 *(.text.sys_mem_swap) \ 238 *(.text.sys_memcpy_swap) \ 239 *(.text.z_*) 240 241/* For logging subsys */ 242#define LIB_SUBSYS_LOGGING_IN_SECT(lsect) \ 243 *log_*.c.obj(.##lsect) \ 244 *log_*.c.obj(.##lsect.*) \ 245 *mpsc_pbuf.c.obj(.##lsect) \ 246 *mpsc_pbuf.c.obj(.##lsect.*) 247 248epoint = K_MEM_PHYS_ADDR(CONFIG_KERNEL_ENTRY); 249ENTRY(epoint) 250 251/* SECTIONS definitions */ 252SECTIONS 253 { 254 255#include <zephyr/linker/rel-sections.ld> 256 257#ifdef CONFIG_LLEXT 258#include <zephyr/linker/llext-sections.ld> 259#endif 260 261 /DISCARD/ : 262 { 263 *(.plt) 264 } 265 266 /DISCARD/ : 267 { 268 *(.iplt) 269 } 270 271#ifdef CONFIG_LINKER_USE_BOOT_SECTION 272 273 SECTION_PROLOGUE(boot.text,,) 274 { 275#include <snippets-rom-start.ld> 276 277 MMU_PAGE_ALIGN 278 lnkr_boot_start = .; 279 z_mapped_start = .; 280 281 lnkr_boot_text_start = .; 282 283 KEEP(*(.boot_text.__start)) 284 *(.boot_text) 285 *(.boot_text.*) 286 287 *(.text.k_mem_paging_backing_store_init) 288 *(.text.k_mem_paging_eviction_init) 289 290 MMU_PAGE_ALIGN_PERM 291 292 lnkr_boot_text_end = .; 293 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 294 295 SECTION_PROLOGUE(boot.rodata,,) 296 { 297 MMU_PAGE_ALIGN_PERM 298 299 lnkr_boot_rodata_start = .; 300 301 *(.boot_rodata) 302 *(.boot_rodata.*) 303 304 MMU_PAGE_ALIGN_PERM 305 306 lnkr_boot_rodata_end = .; 307 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 308 309 SECTION_PROLOGUE(boot.data,,) 310 { 311 MMU_PAGE_ALIGN_PERM 312 313 . = ALIGN(4); 314 315 lnkr_boot_data_start = .; 316 317 *(.boot_data) 318 *(.boot_data.*) 319 320 lnkr_boot_data_end = .; 321 } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 322 323 SECTION_PROLOGUE(boot.bss, (NOLOAD),) 324 { 325 . = ALIGN(4); 326 327 lnkr_boot_bss_start = .; 328 329 *(.boot_bss) 330 *(.boot_bss.*) 331 332 lnkr_boot_bss_end = .; 333 } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 334 335 SECTION_PROLOGUE(boot.noinit, (NOLOAD),) 336 { 337 . = ALIGN(4); 338 339 lnkr_boot_noinit_start = .; 340 341 *(.boot_noinit) 342 *(.boot_noinit.*) 343 344 lnkr_boot_noinit_end = .; 345 346 MMU_PAGE_ALIGN 347 348 lnkr_boot_end = .; 349 } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 350 351 lnkr_boot_text_size = lnkr_boot_text_end - lnkr_boot_text_start; 352 lnkr_boot_rodata_size = lnkr_boot_rodata_end - lnkr_boot_rodata_start; 353 lnkr_boot_data_size = lnkr_boot_data_end - lnkr_boot_data_start; 354 lnkr_boot_bss_size = lnkr_boot_bss_end - lnkr_boot_bss_start; 355 lnkr_boot_noinit_size = lnkr_boot_noinit_end - lnkr_boot_noinit_start; 356 357#endif /* CONFIG_LINKER_USE_BOOT_SECTION */ 358 359#ifdef CONFIG_LINKER_USE_PINNED_SECTION 360 361 SECTION_PROLOGUE(pinned.text,,) 362 { 363#ifndef CONFIG_LINKER_USE_BOOT_SECTION 364#include <snippets-rom-start.ld> 365#endif 366 367 MMU_PAGE_ALIGN 368 369 lnkr_pinned_start = .; 370 371#ifndef CONFIG_LINKER_USE_BOOT_SECTION 372 z_mapped_start = .; 373#endif 374 375 lnkr_pinned_text_start = .; 376 377 LIB_KERNEL_IN_SECT(text) 378 LIB_ARCH_X86_IN_SECT(text) 379 *(.text._OffsetAbsSyms) 380 381 *(.pinned_text) 382 *(.pinned_text.*) 383 384 LIB_ZEPHYR_IN_SECT(text) 385 LIB_C_IN_SECT(text) 386 LIB_DRIVERS_IN_SECT(text) 387 LIB_SUBSYS_LOGGING_IN_SECT(text) 388 389 *_divdi3.o(.text) 390 *_udivdi3.o(.text) 391 *_udivmoddi4.o(.text) 392 *_umoddi3.o(.text) 393 *_popcountsi2.o(.text) 394 395 *(.gnu.linkonce.t.exc_*) 396 397 *(.text.*.constprop) 398 *(.text.*.constprop.*) 399 400#if defined(CONFIG_NEWLIB_LIBC) || defined(CONFIG_PICOLIBC) 401 *libc*.a:(.text) 402 *libc*.a:(.text.*) 403#endif 404 405#ifdef CONFIG_COVERAGE 406 *(.text._sub_I_00100_0) 407#endif 408 409 ZEPHYR_KERNEL_FUNCS_IN_SECT 410 411#include <zephyr/linker/kobject-text.ld> 412 413 MMU_PAGE_ALIGN_PERM 414 415 lnkr_pinned_text_end = .; 416 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 417 418 MMU_PAGE_ALIGN_PERM 419 420 lnkr_pinned_rodata_start = .; 421 422#include <zephyr/linker/common-rom.ld> 423/* Located in generated directory. This file is populated by calling 424 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs. 425 */ 426#include <snippets-rom-sections.ld> 427#include <zephyr/linker/thread-local-storage.ld> 428 429 SECTION_PROLOGUE(pinned.rodata,,) 430 { 431#include <zephyr/arch/x86/ia32/scripts/static_intr.ld> 432 433 LIB_KERNEL_IN_SECT(rodata) 434 LIB_ARCH_X86_IN_SECT(rodata) 435 436 *(.pinned_rodata) 437 *(.pinned_rodata.*) 438 439 LIB_ZEPHYR_IN_SECT(rodata) 440 LIB_C_IN_SECT(rodata) 441 LIB_DRIVERS_IN_SECT(rodata) 442 LIB_SUBSYS_LOGGING_IN_SECT(rodata) 443 444 /* Static strings */ 445 *(.rodata.str*.*) 446 *(.rodata.*.str*.*) 447 448#if defined(CONFIG_NEWLIB_LIBC) || defined(CONFIG_PICOLIBC) 449 *libc*.a:(.rodata) 450 *libc*.a:(.rodata.*) 451#endif 452 453#include <snippets-rodata.ld> 454#include <snippets-pinned-rodata.ld> 455 456#include <zephyr/linker/kobject-rom.ld> 457 458 MMU_PAGE_ALIGN_PERM 459 460 lnkr_pinned_rodata_end = .; 461 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 462 463 SECTION_PROLOGUE(pinned.data,,) 464 { 465 MMU_PAGE_ALIGN_PERM 466 467 lnkr_pinned_data_start = .; 468 469 . = ALIGN(4); 470 471#include <zephyr/arch/x86/ia32/scripts/shared_kernel_pages.ld> 472#include <zephyr/arch/x86/ia32/scripts/dynamic_intr.ld> 473 474 LIB_KERNEL_IN_SECT(data) 475 LIB_ARCH_X86_IN_SECT(data) 476 477 *(.pinned_data) 478 *(.pinned_data.*) 479 480 LIB_ZEPHYR_IN_SECT(data) 481 LIB_C_IN_SECT(data) 482 LIB_DRIVERS_IN_SECT(data) 483 LIB_SUBSYS_LOGGING_IN_SECT(data) 484 485#ifdef CONFIG_COVERAGE 486 *(.data.__gcov_.*) 487 488 /* 489 * This is for the struct gcov_info for 490 * various functions. 491 */ 492 *(.data..LPBX*) 493#endif 494 495 } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 496 497#include <zephyr/linker/common-ram.ld> 498#include <zephyr/arch/x86/pagetables.ld> 499#include <zephyr/linker/kobject-data.ld> 500 501/* Located in generated directory. This file is populated by the 502 * zephyr_linker_sources() Cmake function. 503 */ 504#include <snippets-pinned-data-sections.ld> 505 506 lnkr_pinned_data_end = .; 507 508/* Located in generated directory. This file is populated by the 509 * zephyr_linker_sources() Cmake function. 510 */ 511#include <snippets-pinned-ram-sections.ld> 512 513 SECTION_PROLOGUE(pinned.bss, (NOLOAD),) 514 { 515 . = ALIGN(4); 516 517 lnkr_pinned_bss_start = .; 518 519 LIB_KERNEL_IN_SECT(bss) 520 LIB_ARCH_X86_IN_SECT(bss) 521 522 *(.pinned_bss) 523 *(.pinned_bss.*) 524 525 LIB_ZEPHYR_IN_SECT(bss) 526 LIB_C_IN_SECT(bss) 527 LIB_DRIVERS_IN_SECT(bss) 528 LIB_SUBSYS_LOGGING_IN_SECT(bss) 529 530#ifdef CONFIG_COVERAGE 531 *(.bss.__gcov0.*) 532#endif 533 534 lnkr_pinned_bss_end = .; 535 } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 536 537#ifdef CONFIG_USERSPACE 538 /* PINNED APP SHARED MEMORY REGION */ 539#include <app_smem_pinned.ld> 540 541 _app_smem_pinned_size = _app_smem_pinned_end - _app_smem_pinned_start; 542 _app_smem_pinned_num_words = _app_smem_pinned_size >> 2; 543#endif /* CONFIG_USERSPACE */ 544 545 SECTION_PROLOGUE(pinned.noinit, (NOLOAD),) 546 { 547 . = ALIGN(4); 548 549 lnkr_pinned_noinit_start = .; 550 551 LIB_KERNEL_IN_SECT(noinit) 552 LIB_ARCH_X86_IN_SECT(noinit) 553 554 *(.pinned_noinit) 555 *(.pinned_noinit.*) 556 557 LIB_ZEPHYR_IN_SECT(noinit) 558 LIB_C_IN_SECT(noinit) 559 LIB_DRIVERS_IN_SECT(noinit) 560 LIB_SUBSYS_LOGGING_IN_SECT(noinit) 561 562#ifdef CONFIG_ZTEST 563 /* For tests/kernel/mem_slab/ tests */ 564 *(.noinit.*.k_mem_slab_buf_*) 565 566 /* For tests/kernel/mem_heap tests */ 567 *(.noinit.*.kheap_buf_*) 568 569 /* Pin ztest_thread_stack. 570 * This must be done or else double fault 571 * may arise: testing exceptions while 572 * page fault for the ztest stack. 573 */ 574 *libsubsys__testsuite__ztest.a:(.noinit.*) 575#endif 576 577 lnkr_pinned_noinit_end = .; 578 579 MMU_PAGE_ALIGN 580 581 lnkr_pinned_end = .; 582 583 } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 584 585 lnkr_pinned_text_size = lnkr_pinned_text_end - lnkr_pinned_text_start; 586 lnkr_pinned_rodata_size = lnkr_pinned_rodata_end - lnkr_pinned_rodata_start; 587 lnkr_pinned_data_size = lnkr_pinned_data_end - lnkr_pinned_data_start; 588 lnkr_pinned_bss_size = lnkr_pinned_bss_end - lnkr_pinned_bss_start; 589 lnkr_pinned_noinit_size = lnkr_pinned_noinit_end - lnkr_pinned_noinit_start; 590 591#endif /* CONFIG_LINKER_USE_PINNED_SECTION */ 592 593#if defined(CONFIG_DEMAND_PAGING) && !defined(CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT) 594/* From now on, put symbols into FLASH */ 595#undef ROMABLE_REGION 596#define ROMABLE_REGION FLASH 597 598 /* This is to align the following sections in flash 599 * to their corresponding virtual addresses. 600 * In other words, the offset from start of flash 601 * for these sections would be the same from start of 602 * their virtual addresses. This provides a simple and 603 * direct mapping from backing store. 604 */ 605 flash_load_offset : 606 { 607 . = FLASH_ROM_ADDR + (lnkr_pinned_end - KERNEL_BASE_ADDR); 608 } > FLASH AT > FLASH 609 610#endif 611 612 GROUP_START(ROMABLE_REGION) 613 614 . = ALIGN(8); 615 616 SECTION_PROLOGUE(_TEXT_SECTION_NAME,,) 617 { 618 __text_region_start = .; 619 620#if !defined(CONFIG_LINKER_USE_BOOT_SECTION) || \ 621 !defined(CONFIG_LINKER_USE_PINNED_SECTION) 622 z_mapped_start = .; 623#endif 624 625#if !defined(CONFIG_LINKER_USE_BOOT_SECTION) || \ 626 !defined(CONFIG_LINKER_USE_PINNED_SECTION) 627/* Located in generated directory. This file is populated by calling 628 * zephyr_linker_sources(ROM_START ...). This typically contains the vector 629 * table and debug information. 630 */ 631#include <snippets-rom-start.ld> 632#endif 633 634 /* Needs KEEP() as ENTRY() is given a physical address */ 635 KEEP(*(.text.__start)) 636 *(.text) 637 *(".text.*") 638 *(.gnu.linkonce.t.*) 639 *(.init) 640 *(.fini) 641 *(.eini) 642 643#ifndef CONFIG_LINKER_USE_PINNED_SECTION 644#include <zephyr/linker/kobject-text.ld> 645#endif 646 647 MMU_PAGE_ALIGN_PERM 648 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 649 650 __text_region_end = .; 651 __text_region_size = __text_region_end - __text_region_start; 652 __rodata_region_start = .; 653 654#ifndef CONFIG_LINKER_USE_PINNED_SECTION 655#include <zephyr/linker/common-rom.ld> 656/* Located in generated directory. This file is populated by calling 657 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs. 658 */ 659#include <snippets-rom-sections.ld> 660#include <zephyr/linker/thread-local-storage.ld> 661#endif 662 663 SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) 664 { 665 *(.rodata) 666 *(".rodata.*") 667 *(.gnu.linkonce.r.*) 668 669#ifndef CONFIG_DYNAMIC_INTERRUPTS 670#ifndef CONFIG_LINKER_USE_PINNED_SECTION 671#include <zephyr/arch/x86/ia32/scripts/static_intr.ld> 672#endif /* !CONFIG_LINKER_USE_PINNED_SECTION */ 673#endif /* CONFIG_DYNAMIC_INTERRUPTS */ 674 675#ifndef CONFIG_LINKER_USE_PINNED_SECTION 676/* Located in generated directory. This file is populated by the 677 * zephyr_linker_sources() Cmake function. 678 */ 679#include <snippets-rodata.ld> 680 681#include <zephyr/linker/kobject-rom.ld> 682#endif 683 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 684 685#include <zephyr/linker/cplusplus-rom.ld> 686 687 MMU_PAGE_ALIGN_PERM 688 /* ROM ends here, position counter will now be in RAM areas */ 689 __rodata_region_end = .; 690 __rodata_region_size = __rodata_region_end - __rodata_region_start; 691 GROUP_END(ROMABLE_REGION) 692 /* 693 * Needed for dynamic linking which we do not have, do discard 694 */ 695 /DISCARD/ : { 696 *(.got.plt) 697 *(.igot.plt) 698 *(.got) 699 *(.igot) 700 } 701 /* RAMABLE_REGION */ 702 GROUP_START(RAMABLE_REGION) 703 704/* Located in generated directory. This file is populated by the 705 * zephyr_linker_sources() Cmake function. 706 */ 707#include <snippets-ram-sections.ld> 708 709#ifdef CONFIG_USERSPACE 710 /* APP SHARED MEMORY REGION */ 711#include <app_smem.ld> 712 713 _image_ram_start = _app_smem_start; 714 _app_smem_size = _app_smem_end - _app_smem_start; 715 _app_smem_num_words = _app_smem_size >> 2; 716 _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); 717#endif /* CONFIG_USERSPACE */ 718 719 SECTION_PROLOGUE(_BSS_SECTION_NAME, (NOLOAD),) 720 { 721 MMU_PAGE_ALIGN_PERM 722#if !defined(CONFIG_USERSPACE) 723 _image_ram_start = .; 724#endif 725 /* 726 * For performance, BSS section is forced to be both 4 byte aligned and 727 * a multiple of 4 bytes. 728 */ 729 . = ALIGN(4); 730 __kernel_ram_start = .; 731 __bss_start = .; 732 733 *(.bss) 734 *(".bss.*") 735 *(COMMON) 736 *(".kernel_bss.*") 737 738 /* 739 * As memory is cleared in words only, it is simpler to ensure the BSS 740 * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes. 741 */ 742 . = ALIGN(4); 743 __bss_end = .; 744 } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 745 746 __bss_num_words = (__bss_end - __bss_start) >> 2; 747 748#include <zephyr/linker/common-noinit.ld> 749 750 MMU_PAGE_ALIGN_PERM 751 752 SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,) 753 { 754 755 __data_ram_start = .; 756 757 *(.data) 758 *(".data.*") 759 *(".kernel.*") 760 761#ifdef CONFIG_DYNAMIC_INTERRUPTS 762#ifndef CONFIG_LINKER_USE_PINNED_SECTION 763#include <zephyr/arch/x86/ia32/scripts/dynamic_intr.ld> 764#endif /* !CONFIG_LINKER_USE_PINNED_SECTION */ 765#endif /* CONFIG_DYNAMIC_INTERRUPTS */ 766 767/* Located in generated directory. This file is populated by the 768 * zephyr_linker_sources() Cmake function. 769 */ 770#include <snippets-rwdata.ld> 771 772#ifndef CONFIG_LINKER_USE_PINNED_SECTION 773#include <zephyr/arch/x86/ia32/scripts/shared_kernel_pages.ld> 774#endif /* !CONFIG_LINKER_USE_PINNED_SECTION */ 775 776 . = ALIGN(4); 777 } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 778 779 __data_rom_start = LOADADDR(_DATA_SECTION_NAME); 780 781#include <zephyr/linker/cplusplus-ram.ld> 782 783#ifndef CONFIG_LINKER_USE_PINNED_SECTION 784#include <zephyr/linker/common-ram.ld> 785#include <zephyr/arch/x86/pagetables.ld> 786 787/* Must be last in RAM */ 788#include <zephyr/linker/kobject-data.ld> 789#endif /* !CONFIG_LINKER_USE_PINNED_SECTION */ 790 791/* Located in generated directory. This file is populated by the 792 * zephyr_linker_sources() Cmake function. 793 */ 794#include <snippets-data-sections.ld> 795 796 MMU_PAGE_ALIGN 797 __data_ram_end = .; 798 799 /* All unused memory also owned by the kernel for heaps */ 800 __kernel_ram_end = KERNEL_BASE_ADDR + KERNEL_RAM_SIZE; 801 __kernel_ram_size = __kernel_ram_end - __kernel_ram_start; 802 803 _image_ram_all = (KERNEL_BASE_ADDR + KERNEL_RAM_SIZE) - _image_ram_start; 804 805 z_mapped_size = z_mapped_end - z_mapped_start; 806 807#ifndef LINKER_ZEPHYR_FINAL 808 /* static interrupts */ 809 SECTION_PROLOGUE(intList,,) 810 { 811 KEEP(*(.spurIsr)) 812 KEEP(*(.spurNoErrIsr)) 813 KEEP(*(.intList)) 814 KEEP(*(.gnu.linkonce.intList.*)) 815 } > IDT_LIST 816#else 817 /DISCARD/ : 818 { 819 KEEP(*(.spurIsr)) 820 KEEP(*(.spurNoErrIsr)) 821 KEEP(*(.intList)) 822 KEEP(*(.gnu.linkonce.intList.*)) 823 } 824#endif 825 826 827 828/* Located in generated directory. This file is populated by the 829 * zephyr_linker_sources() Cmake function. 830 */ 831#include <snippets-sections.ld> 832 833#define LAST_RAM_ALIGN MMU_PAGE_ALIGN 834 835#include <zephyr/linker/ram-end.ld> 836 837 GROUP_END(RAMABLE_REGION) 838 839#include <zephyr/linker/debug-sections.ld> 840 841 /DISCARD/ : { *(.note.GNU-stack) } 842 843 } 844