1/* 2 * Copyright (c) 2023 NXP 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 NXP i.MX8ULP platform 12 */ 13 14OUTPUT_ARCH(xtensa) 15 16#include <zephyr/devicetree.h> 17#include <xtensa/config/core-isa.h> 18#include <memory.h> 19#include <zephyr/linker/sections.h> 20 21#include <zephyr/linker/linker-defs.h> 22#include <zephyr/linker/linker-tool.h> 23 24PROVIDE(__memctl_default = 0x00000000); 25PROVIDE(_MemErrorHandler = 0x00000000); 26 27#define RAMABLE_REGION sdram0 :sdram0_phdr 28#define ROMABLE_REGION sdram0 :sdram0_phdr 29 30MEMORY 31{ 32 vector_reset_text : 33 org = XCHAL_RESET_VECTOR0_PADDR_IRAM, 34 len = MEM_RESET_TEXT_SIZE 35 vector_reset_lit : 36 org = XCHAL_RESET_VECTOR0_PADDR_IRAM + MEM_RESET_TEXT_SIZE, 37 len = MEM_RESET_LIT_SIZE 38 vector_base_text : 39 org = XCHAL_VECBASE_RESET_PADDR_IRAM, 40 len = MEM_VECBASE_LIT_SIZE 41 vector_int2_lit : 42 org = XCHAL_INTLEVEL2_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, 43 len = MEM_VECT_LIT_SIZE 44 vector_int2_text : 45 org = XCHAL_INTLEVEL2_VECTOR_PADDR_IRAM, 46 len = MEM_VECT_TEXT_SIZE 47 vector_int3_lit : 48 org = XCHAL_INTLEVEL3_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, 49 len = MEM_VECT_LIT_SIZE 50 vector_int3_text : 51 org = XCHAL_INTLEVEL3_VECTOR_PADDR_IRAM, 52 len = MEM_VECT_TEXT_SIZE 53 vector_int4_lit : 54 org = XCHAL_INTLEVEL4_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, 55 len = MEM_VECT_LIT_SIZE 56 vector_int4_text : 57 org = XCHAL_INTLEVEL4_VECTOR_PADDR_IRAM, 58 len = MEM_VECT_TEXT_SIZE 59 vector_int5_lit : 60 org = XCHAL_INTLEVEL5_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, 61 len = MEM_VECT_LIT_SIZE 62 vector_int5_text : 63 org = XCHAL_INTLEVEL5_VECTOR_PADDR_IRAM, 64 len = MEM_VECT_TEXT_SIZE 65 vector_kernel_lit : 66 org = XCHAL_KERNEL_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, 67 len = MEM_VECT_LIT_SIZE 68 vector_kernel_text : 69 org = XCHAL_KERNEL_VECTOR_PADDR_IRAM, 70 len = MEM_VECT_TEXT_SIZE 71 vector_user_lit : 72 org = XCHAL_USER_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, 73 len = MEM_VECT_LIT_SIZE 74 vector_user_text : 75 org = XCHAL_USER_VECTOR_PADDR_IRAM, 76 len = MEM_VECT_TEXT_SIZE 77 vector_double_lit : 78 org = XCHAL_DOUBLEEXC_VECTOR_PADDR_IRAM - MEM_VECT_LIT_SIZE, 79 len = MEM_VECT_LIT_SIZE 80 vector_double_text : 81 org = XCHAL_DOUBLEEXC_VECTOR_PADDR_IRAM, 82 len = MEM_VECT_TEXT_SIZE 83 iram_text_start : 84 org = XCHAL_DOUBLEEXC_VECTOR_PADDR_IRAM + MEM_VECT_TEXT_SIZE, 85 len = (IRAM_BASE + IRAM_SIZE) - (XCHAL_DOUBLEEXC_VECTOR_PADDR + MEM_VECT_TEXT_SIZE) 86 sdram0 : 87 org = SDRAM0_BASE, 88 len = SDRAM0_SIZE 89 sdram1 : 90 org = SDRAM1_BASE + SOF_MAILBOX_SIZE, 91 len = SDRAM1_SIZE - SOF_MAILBOX_SIZE 92#ifdef CONFIG_GEN_ISR_TABLES 93 IDT_LIST : 94 org = IDT_BASE, 95 len = IDT_SIZE 96#endif 97 98 static_uuid_entries_seg (!ari) : 99 org = UUID_ENTRY_ELF_BASE, 100 len = UUID_ENTRY_ELF_SIZE 101 static_log_entries_seg (!ari) : 102 org = LOG_ENTRY_ELF_BASE, 103 len = LOG_ENTRY_ELF_SIZE 104 fw_metadata_seg (!ari) : 105 org = EXT_MANIFEST_ELF_BASE, 106 len = EXT_MANIFEST_ELF_SIZE 107} 108 109PHDRS 110{ 111 vector_reset_text_phdr PT_LOAD; 112 vector_reset_lit_phdr PT_LOAD; 113 vector_base_text_phdr PT_LOAD; 114 vector_base_lit_phdr PT_LOAD; 115 vector_int2_text_phdr PT_LOAD; 116 vector_int2_lit_phdr PT_LOAD; 117 vector_int3_text_phdr PT_LOAD; 118 vector_int3_lit_phdr PT_LOAD; 119 vector_int4_text_phdr PT_LOAD; 120 vector_int4_lit_phdr PT_LOAD; 121 vector_int5_text_phdr PT_LOAD; 122 vector_int5_lit_phdr PT_LOAD; 123 vector_kernel_text_phdr PT_LOAD; 124 vector_kernel_lit_phdr PT_LOAD; 125 vector_user_text_phdr PT_LOAD; 126 vector_user_lit_phdr PT_LOAD; 127 vector_double_text_phdr PT_LOAD; 128 vector_double_lit_phdr PT_LOAD; 129 iram_text_start_phdr PT_LOAD; 130 sdram0_phdr PT_LOAD; 131 sdram1_phdr PT_LOAD; 132 static_uuid_entries_phdr PT_NOTE; 133 static_log_entries_phdr PT_NOTE; 134 metadata_entries_phdr PT_NOTE; 135} 136 137_rom_store_table = 0; 138 139PROVIDE(_memmap_vecbase_reset = XCHAL_VECBASE_RESET_PADDR); 140 141ENTRY(CONFIG_KERNEL_ENTRY) 142 143/* Various memory-map dependent cache attribute settings: */ 144_memmap_cacheattr_wb_base = 0x44024000; 145_memmap_cacheattr_wt_base = 0x11021000; 146_memmap_cacheattr_bp_base = 0x22022000; 147_memmap_cacheattr_unused_mask = 0x00F00FFF; 148_memmap_cacheattr_wb_trapnull = 0x4422422F; 149_memmap_cacheattr_wba_trapnull = 0x4422422F; 150_memmap_cacheattr_wbna_trapnull = 0x25222222; 151_memmap_cacheattr_wt_trapnull = 0x1122122F; 152_memmap_cacheattr_bp_trapnull = 0x2222222F; 153_memmap_cacheattr_wb_strict = 0x44F24FFF; 154_memmap_cacheattr_wt_strict = 0x11F21FFF; 155_memmap_cacheattr_bp_strict = 0x22F22FFF; 156_memmap_cacheattr_wb_allvalid = 0x44224222; 157_memmap_cacheattr_wt_allvalid = 0x11221222; 158_memmap_cacheattr_bp_allvalid = 0x22222222; 159/* 160 * Every 512M in 4GB space has dedicate cache attribute. 161 * 1: write through 162 * 2: cache bypass 163 * 4: write back 164 * F: invalid access 165 */ 166_memmap_cacheattr_imx8_wt_allvalid = 0x222222221; 167PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_imx8_wt_allvalid); 168 169_EXT_MAN_ALIGN_ = 16; 170EXTERN(ext_man_fw_ver) 171 172SECTIONS 173{ 174 175#include <zephyr/linker/rel-sections.ld> 176 177#ifdef CONFIG_LLEXT 178#include <zephyr/linker/llext-sections.ld> 179#endif 180 .ResetVector.text : ALIGN(4) 181 { 182 _ResetVector_text_start = ABSOLUTE(.); 183 KEEP (*(.ResetVector.text)) 184 _ResetVector_text_end = ABSOLUTE(.); 185 } >vector_reset_text :vector_reset_text_phdr 186 187 .ResetVector.literal : ALIGN(4) 188 { 189 _ResetVector_literal_start = ABSOLUTE(.); 190 *(.ResetVector.literal) 191 _ResetVector_literal_end = ABSOLUTE(.); 192 } >vector_reset_lit :vector_reset_lit_phdr 193 194 .WindowVectors.text : ALIGN(4) 195 { 196 _WindowVectors_text_start = ABSOLUTE(.); 197 KEEP (*(.WindowVectors.text)) 198 _WindowVectors_text_end = ABSOLUTE(.); 199 } >vector_base_text :vector_base_text_phdr 200 201 .Level2InterruptVector.literal : ALIGN(4) 202 { 203 _Level2InterruptVector_literal_start = ABSOLUTE(.); 204 *(.Level2InterruptVector.literal) 205 _Level2InterruptVector_literal_end = ABSOLUTE(.); 206 } >vector_int2_lit :vector_int2_lit_phdr 207 208 .Level2InterruptVector.text : ALIGN(4) 209 { 210 _Level2InterruptVector_text_start = ABSOLUTE(.); 211 KEEP (*(.Level2InterruptVector.text)) 212 _Level2InterruptVector_text_end = ABSOLUTE(.); 213 } >vector_int2_text :vector_int2_text_phdr 214 215 .Level3InterruptVector.literal : ALIGN(4) 216 { 217 _Level3InterruptVector_literal_start = ABSOLUTE(.); 218 *(.Level3InterruptVector.literal) 219 _Level3InterruptVector_literal_end = ABSOLUTE(.); 220 } >vector_int3_lit :vector_int3_lit_phdr 221 222 .Level3InterruptVector.text : ALIGN(4) 223 { 224 _Level3InterruptVector_text_start = ABSOLUTE(.); 225 KEEP (*(.Level3InterruptVector.text)) 226 _Level3InterruptVector_text_end = ABSOLUTE(.); 227 } >vector_int3_text :vector_int3_text_phdr 228 229 .DebugExceptionVector.literal : ALIGN(4) 230 { 231 _DebugExceptionVector_literal_start = ABSOLUTE(.); 232 *(.DebugExceptionVector.literal) 233 _DebugExceptionVector_literal_end = ABSOLUTE(.); 234 } >vector_int4_lit :vector_int4_lit_phdr 235 236 .DebugExceptionVector.text : ALIGN(4) 237 { 238 _DebugExceptionVector_text_start = ABSOLUTE(.); 239 KEEP (*(.DebugExceptionVector.text)) 240 _DebugExceptionVector_text_end = ABSOLUTE(.); 241 } >vector_int4_text :vector_int4_text_phdr 242 243 .NMIExceptionVector.literal : ALIGN(4) 244 { 245 _NMIExceptionVector_literal_start = ABSOLUTE(.); 246 *(.NMIExceptionVector.literal) 247 _NMIExceptionVector_literal_end = ABSOLUTE(.); 248 } >vector_int5_lit :vector_int5_lit_phdr 249 250 .NMIExceptionVector.text : ALIGN(4) 251 { 252 _NMIExceptionVector_text_start = ABSOLUTE(.); 253 KEEP (*(.NMIExceptionVector.text)) 254 _NMIExceptionVector_text_end = ABSOLUTE(.); 255 } >vector_int5_text :vector_int5_text_phdr 256 257 .KernelExceptionVector.literal : ALIGN(4) 258 { 259 _KernelExceptionVector_literal_start = ABSOLUTE(.); 260 *(.KernelExceptionVector.literal) 261 _KernelExceptionVector_literal_end = ABSOLUTE(.); 262 } >vector_kernel_lit :vector_kernel_lit_phdr 263 264 .KernelExceptionVector.text : ALIGN(4) 265 { 266 _KernelExceptionVector_text_start = ABSOLUTE(.); 267 KEEP (*(.KernelExceptionVector.text)) 268 _KernelExceptionVector_text_end = ABSOLUTE(.); 269 } >vector_kernel_text :vector_kernel_text_phdr 270 271 .UserExceptionVector.literal : ALIGN(4) 272 { 273 _UserExceptionVector_literal_start = ABSOLUTE(.); 274 *(.UserExceptionVector.literal) 275 _UserExceptionVector_literal_end = ABSOLUTE(.); 276 } >vector_user_lit :vector_user_lit_phdr 277 278 .UserExceptionVector.text : ALIGN(4) 279 { 280 _UserExceptionVector_text_start = ABSOLUTE(.); 281 KEEP (*(.UserExceptionVector.text)) 282 _UserExceptionVector_text_end = ABSOLUTE(.); 283 } >vector_user_text :vector_user_text_phdr 284 285 .DoubleExceptionVector.literal : ALIGN(4) 286 { 287 _DoubleExceptionVector_literal_start = ABSOLUTE(.); 288 *(.DoubleExceptionVector.literal) 289 _DoubleExceptionVector_literal_end = ABSOLUTE(.); 290 } >vector_double_lit :vector_double_lit_phdr 291 292 .DoubleExceptionVector.text : ALIGN(4) 293 { 294 _DoubleExceptionVector_text_start = ABSOLUTE(.); 295 KEEP (*(.DoubleExceptionVector.text)) 296 _DoubleExceptionVector_text_end = ABSOLUTE(.); 297 } >vector_double_text :vector_double_text_phdr 298 299 .iram.text : ALIGN(4) 300 { 301 _stext = .; 302 _iram_text_start = ABSOLUTE(.); 303 *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) 304 _iram_text_end = ABSOLUTE(.); 305 } >iram_text_start :iram_text_start_phdr 306 307 .rodata : ALIGN(4) 308 { 309 __rodata_region_start = ABSOLUTE(.); 310 *(.rodata) 311 *(.rodata.*) 312 *(.gnu.linkonce.r.*) 313 *(.rodata1) 314 __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); 315 KEEP (*(.xt_except_table)) 316 KEEP (*(.gcc_except_table .gcc_except_table.*)) 317 *(.gnu.linkonce.e.*) 318 *(.gnu.version_r) 319 KEEP (*(.eh_frame)) 320 KEEP (*crtbegin.o(.ctors)) 321 KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) 322 KEEP (*(SORT(.ctors.*))) 323 KEEP (*(.ctors)) 324 KEEP (*crtbegin.o(.dtors)) 325 KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) 326 KEEP (*(SORT(.dtors.*))) 327 KEEP (*(.dtors)) 328 __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); 329 *(.xt_except_desc) 330 *(.gnu.linkonce.h.*) 331 __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); 332 *(.xt_except_desc_end) 333 *(.dynamic) 334 *(.gnu.version_d) 335 . = ALIGN(4); 336 _bss_table_start = ABSOLUTE(.); 337 LONG(_bss_start) 338 LONG(_bss_end) 339 _bss_table_end = ABSOLUTE(.); 340 __rodata_region_end = ABSOLUTE(.); 341 } >sdram0 :sdram0_phdr 342 343 .module_init : ALIGN(4) 344 { 345 _module_init_start = ABSOLUTE(.); 346 *(*.initcall) 347 _module_init_end = ABSOLUTE(.); 348 } >sdram0 :sdram0_phdr 349 350 .text : ALIGN(4) 351 { 352 _stext = .; 353 _text_start = ABSOLUTE(.); 354 KEEP (*(.ResetVector.text)) 355 *(.ResetVector.literal) 356 *(.entry.text) 357 *(.init.literal) 358 KEEP(*(.init)) 359 *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 360 *(.fini.literal) 361 KEEP(*(.fini)) 362 *(.gnu.version) 363 _text_end = ABSOLUTE(.); 364 _etext = .; 365 } >sdram0 :sdram0_phdr 366 367#include <zephyr/linker/common-rom.ld> 368/* Located in generated directory. This file is populated by calling 369 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs. 370 */ 371#include <snippets-rom-sections.ld> 372 373 .fw_ready : ALIGN(4) 374 { 375 KEEP(*(".fw_ready")); 376 KEEP (*(.fw_ready_metadata)) 377 } >sdram0 :sdram0_phdr 378 379 .noinit : ALIGN(4) 380 { 381 *(.noinit) 382 *(.noinit.*) 383 } >sdram0 :sdram0_phdr 384 385 .data : ALIGN(4) 386 { 387 __data_start = ABSOLUTE(.); 388 *(.data) 389 *(.data.*) 390 *(.gnu.linkonce.d.*) 391 KEEP(*(.gnu.linkonce.d.*personality*)) 392 *(.data1) 393 *(.sdata) 394 *(.sdata.*) 395 *(.gnu.linkonce.s.*) 396 *(.sdata2) 397 *(.sdata2.*) 398 *(.gnu.linkonce.s2.*) 399 KEEP(*(.jcr)) 400 _trace_ctx_start = ABSOLUTE(.); 401 *(.trace_ctx) 402 _trace_ctx_end = ABSOLUTE(.); 403 . = ALIGN(4); 404 *(.gna_model) 405 __data_end = ABSOLUTE(.); 406 . = ALIGN(4096); 407 } >sdram0 :sdram0_phdr 408 409 .lit4 : ALIGN(4) 410 { 411 _lit4_start = ABSOLUTE(.); 412 *(*.lit4) 413 *(.lit4.*) 414 *(.gnu.linkonce.lit4.*) 415 _lit4_end = ABSOLUTE(.); 416 } >sdram0 :sdram0_phdr 417 418#include <zephyr/linker/common-ram.ld> 419 420 .bss (NOLOAD) : ALIGN(8) 421 { 422 . = ALIGN (8); 423 _bss_start = ABSOLUTE(.); 424 *(.dynsbss) 425 *(.sbss) 426 *(.sbss.*) 427 *(.gnu.linkonce.sb.*) 428 *(.scommon) 429 *(.sbss2) 430 *(.sbss2.*) 431 *(.gnu.linkonce.sb2.*) 432 *(.dynbss) 433 *(.bss) 434 *(.bss.*) 435 *(.gnu.linkonce.b.*) 436 *(COMMON) 437 . = ALIGN (8); 438 _bss_end = ABSOLUTE(.); 439 } >sdram0 :sdram0_phdr 440 441 .heap_mem (NOLOAD) : ALIGN(8) 442 { 443 . = ALIGN (8); 444 _heap_mem_start = ABSOLUTE(.); 445 *(*.heap_mem) 446 _heap_mem_end = ABSOLUTE(.); 447 } >sdram1 :sdram1_phdr 448 449 /* stack */ 450 _end = ALIGN (8); 451 PROVIDE(end = ALIGN (8)); 452 453 __stack = SDRAM1_BASE + SDRAM1_SIZE; 454 .comment 0 : { *(.comment) } 455 .debug 0 : { *(.debug) } 456 .line 0 : { *(.line) } 457 .debug_srcinfo 0 : { *(.debug_srcinfo) } 458 .debug_sfnames 0 : { *(.debug_sfnames) } 459 .debug_aranges 0 : { *(.debug_aranges) } 460 .debug_pubnames 0 : { *(.debug_pubnames) } 461 .debug_info 0 : { *(.debug_info) } 462 .debug_abbrev 0 : { *(.debug_abbrev) } 463 .debug_line 0 : { *(.debug_line) } 464 .debug_frame 0 : { *(.debug_frame) } 465 .debug_str 0 : { *(.debug_str) } 466 .debug_loc 0 : { *(.debug_loc) } 467 .debug_macinfo 0 : { *(.debug_macinfo) } 468 .debug_weaknames 0 : { *(.debug_weaknames) } 469 .debug_funcnames 0 : { *(.debug_funcnames) } 470 .debug_typenames 0 : { *(.debug_typenames) } 471 .debug_varnames 0 : { *(.debug_varnames) } 472 .debug_ranges 0 : { *(.debug_ranges) } 473 .debug_addr 0 : { *(.debug_addr) } 474 .debug_line_str 0 : { *(.debug_line_str) } 475 .debug_loclists 0 : { *(.debug_loclists) } 476 .debug_macro 0 : { *(.debug_macro) } 477 .debug_names 0 : { *(.debug_names) } 478 .debug_rnglists 0 : { *(.debug_rnglists) } 479 .debug_str_offsets 0 : { *(.debug_str_offsets) } 480 .debug_sup 0 : { *(.debug_sup) } 481 .xtensa.info 0 : { *(.xtensa.info) } 482 .xt.insn 0 : 483 { 484 KEEP (*(.xt.insn)) 485 KEEP (*(.gnu.linkonce.x.*)) 486 } 487 .xt.prop 0 : 488 { 489 KEEP (*(.xt.prop)) 490 KEEP (*(.xt.prop.*)) 491 KEEP (*(.gnu.linkonce.prop.*)) 492 } 493 .xt.lit 0 : 494 { 495 KEEP (*(.xt.lit)) 496 KEEP (*(.xt.lit.*)) 497 KEEP (*(.gnu.linkonce.p.*)) 498 } 499 .xt.profile_range 0 : 500 { 501 KEEP (*(.xt.profile_range)) 502 KEEP (*(.gnu.linkonce.profile_range.*)) 503 } 504 .xt.profile_ranges 0 : 505 { 506 KEEP (*(.xt.profile_ranges)) 507 KEEP (*(.gnu.linkonce.xt.profile_ranges.*)) 508 } 509 .xt.profile_files 0 : 510 { 511 KEEP (*(.xt.profile_files)) 512 KEEP (*(.gnu.linkonce.xt.profile_files.*)) 513 } 514#ifdef CONFIG_GEN_ISR_TABLES 515#include <zephyr/linker/intlist.ld> 516#endif 517 518 .static_uuid_entries (COPY) : ALIGN(1024) 519 { 520 *(*.static_uuids) 521 } > static_uuid_entries_seg :static_uuid_entries_phdr 522 523 .static_log_entries (COPY) : ALIGN(1024) 524 { 525 *(*.static_log*) 526 } > static_log_entries_seg :static_log_entries_phdr 527 528 .fw_metadata (COPY) : ALIGN(1024) 529 { 530 KEEP (*(.fw_metadata)) 531 . = ALIGN(_EXT_MAN_ALIGN_); 532 } >fw_metadata_seg :metadata_entries_phdr 533 534 /DISCARD/ : { *(.note.GNU-stack) } 535} 536