1/* 2 * Copyright (c) 2016 Cadence Design 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 Xtensa platform. 12 */ 13 14#include <xtensa/config/core-isa.h> 15 16#include <zephyr/linker/sections.h> 17 18#include <zephyr/devicetree.h> 19#include <zephyr/linker/linker-defs.h> 20#include <zephyr/linker/linker-tool.h> 21 22#define RAMABLE_REGION RAM :sram0_phdr 23#define ROMABLE_REGION RAM :sram0_phdr 24 25#ifdef CONFIG_MMU 26#define MMU_PAGE_ALIGN . = ALIGN(CONFIG_MMU_PAGE_SIZE); 27#define HDR_MMU_PAGE_ALIGN ALIGN(CONFIG_MMU_PAGE_SIZE) 28#define HDR_4K_OR_MMU_PAGE_ALIGN ALIGN(CONFIG_MMU_PAGE_SIZE) 29#define LAST_RAM_ALIGN MMU_PAGE_ALIGN 30#else 31#define MMU_PAGE_ALIGN . = ALIGN(4); 32#define HDR_MMU_PAGE_ALIGN ALIGN(4) 33#define HDR_4K_OR_MMU_PAGE_ALIGN ALIGN(4096) 34#endif 35 36#define PHYS_SRAM0_ADDR (DT_REG_ADDR(DT_NODELABEL(sram0))) 37#define PHYS_SRAM0_SIZE (DT_REG_SIZE(DT_NODELABEL(sram0))) 38 39#define PHYS_ROM0_ADDR (DT_REG_ADDR(DT_NODELABEL(rom0))) 40#define PHYS_ROM0_SIZE (DT_REG_SIZE(DT_NODELABEL(rom0))) 41 42/* Usable RAM is after the exception vectors and page-aligned. */ 43#define PHYS_RAM_ADDR (PHYS_SRAM0_ADDR + CONFIG_SRAM_OFFSET) 44#define PHYS_RAM_SIZE (PHYS_SRAM0_SIZE - CONFIG_SRAM_OFFSET) 45 46MEMORY 47{ 48 vectors : org = 0x00002000, len = 0x2400 49#ifdef CONFIG_XTENSA_MMU 50 vec_helpers : org = 0x00002400, len = (PHYS_RAM_ADDR - 0x00002400) 51#endif 52 RAM : org = PHYS_RAM_ADDR, len = PHYS_RAM_SIZE 53 54 /* Although ROM is of size 0x02000000, we limit it to 8KB so 55 * fewer L2 page table entries are needed. 56 */ 57 rom0_seg : org = PHYS_ROM0_ADDR, len = PHYS_ROM0_SIZE 58 59#ifdef CONFIG_GEN_ISR_TABLES 60 /* The space before exception vectors is not being used. 61 * So we stuff the temporary IDT_LIST there to avoid 62 * some linker issues which would balloon the size of 63 * the intermediate files (like zephyr_pre0.elf, to 64 * couple hundred MBs or even GBs). 65 */ 66 IDT_LIST : org = 0x00000000, len = 0x2000 67#endif 68} 69 70PHDRS 71{ 72 vectors_phdr PT_LOAD; 73#ifdef CONFIG_XTENSA_MMU 74 vec_helpers_phdr PT_LOAD; 75#endif 76 77 rom0_phdr PT_LOAD; 78 sram0_phdr PT_LOAD; 79 sram0_bss_phdr PT_LOAD; 80} 81 82 83/* Default entry point: */ 84ENTRY(CONFIG_KERNEL_ENTRY) 85 86_rom_store_table = 0; 87PROVIDE(_memmap_vecbase_reset = 0x00002000); 88PROVIDE(_memmap_reset_vector = 0xFE000000); 89/* Various memory-map dependent cache attribute settings: 90 * 91 * Note that there is no cacheattr register which means thah 92 * cacheattr is emulated through TLB way 6 (8x 512MB regions). 93 * So the attributes here are the MMU memory attributes: 94 * 0x3 - rwx, bypass cache 95 * 0x7 - rwx, cache write back 96 * 0xB - wrx, cache write through 97 * Refer to the ISA manual for other attributes. 98 */ 99_memmap_cacheattr_wb_base = 0x70000007; 100_memmap_cacheattr_wt_base = 0xB000000B; 101_memmap_cacheattr_bp_base = 0x30000003; 102_memmap_cacheattr_unused_mask = 0x0FFFFFF0; 103_memmap_cacheattr_wb_strict = 0x7FFFFFF7; 104_memmap_cacheattr_wt_strict = 0xBFFFFFFB; 105_memmap_cacheattr_bp_strict = 0x3FFFFFF3; 106_memmap_cacheattr_wb_allvalid = 0x73333337; 107_memmap_cacheattr_wt_allvalid = 0xB333333B; 108_memmap_cacheattr_bp_allvalid = 0x33333333; 109PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_allvalid); 110 111SECTIONS 112{ 113 114#include <zephyr/linker/rel-sections.ld> 115 116#ifdef CONFIG_LLEXT 117#include <zephyr/linker/llext-sections.ld> 118#endif 119 120#ifdef CONFIG_GEN_ISR_TABLES 121#include <zephyr/linker/intlist.ld> 122#endif 123 124/* Auto-generated vector linkage, to "vectors" memory region */ 125#include <xtensa_vectors.ld> 126 >vectors :vectors_phdr 127 128#define LIB_OBJ_FUNC_IN_SECT(library, obj_file, func) \ 129 *##library##:##obj_file##(.literal.##func .text.##func) \ 130 131#ifdef CONFIG_XTENSA_MMU 132 .vec_helpers : 133 { 134 /* There is quite some space between .DoubleExceptionVector 135 * and the beginning of .text. We can put exception handling 136 * code here to avoid TLB misses, thus speed up exception 137 * handling a little bit. 138 * 139 * Note: DO NOT PUT MMU init code here as this will be 140 * mapped in TLB manually. This manual entry will 141 * conflict with auto-refill TLB resulting in 142 * TLB multi-hit exception. 143 */ 144 145 *libarch__xtensa__core.a:xtensa_asm2_util.S.obj(.literal .text) 146 *libarch__xtensa__core.a:xtensa_asm2_util.S.obj(.iram.text .iram0.text) 147 148 *libarch__xtensa__core.a:window_vectors.S.obj(.iram.text) 149 150 *libarch__xtensa__core.a:crt1.S.obj(.literal .text) 151 152 LIB_OBJ_FUNC_IN_SECT(libarch__xtensa__core.a,xtensa_asm2.c.obj,*) 153 LIB_OBJ_FUNC_IN_SECT(libarch__xtensa__core.a,fatal.c.obj,*) 154 LIB_OBJ_FUNC_IN_SECT(libarch__xtensa__core.a,cpu_idle.c.obj,*) 155 156 *(.text.arch_is_in_isr) 157 158 /* To support backtracing */ 159 LIB_OBJ_FUNC_IN_SECT(libarch__xtensa__core.a,xtensa_backtrace.c.obj,*) 160 161 *libarch__xtensa__core.a:debug_helpers_asm.S.obj(.iram1.literal .iram1) 162 163 /* Userspace related stuff */ 164 LIB_OBJ_FUNC_IN_SECT(libarch__xtensa__core.a,userspace.S.obj,xtensa_do_syscall) 165 LIB_OBJ_FUNC_IN_SECT(libarch__xtensa__core.a,ptables.c.obj,xtensa_swap_update_page_tables) 166 167 /* Below are to speed up execution by avoiding TLB misses 168 * on frequently used functions. 169 * 170 * There is almost 1MB space (due to TLB pinning) so we can 171 * be generous. 172 */ 173 LIB_OBJ_FUNC_IN_SECT(libkernel.a,,*) 174 175 LIB_OBJ_FUNC_IN_SECT(libdrivers__console.a,,*) 176 LIB_OBJ_FUNC_IN_SECT(libdrivers__timer.a,,*) 177 178 *(.literal.z_vrfy_* .text.z_vrfy_*) 179 *(.literal.z_mrsh_* .text.z_mrsh_*) 180 *(.literal.z_impl_* .text.z_impl_*) 181 *(.literal.z_obj_* .text.z_obj_*) 182 183 *(.literal.k_sys_fatal_error_handler .text.k_sys_fatal_error_handler) 184 } >vec_helpers :vec_helpers_phdr 185#endif /* CONFIG_XTENSA_MMU */ 186 187#ifdef CONFIG_CODE_DATA_RELOCATION 188#include <linker_relocate.ld> 189#endif 190 191 .ResetVector.text : ALIGN(4) 192 { 193 __rom_region_start = ABSOLUTE(.); 194 _ResetVector_text_start = ABSOLUTE(.); 195 KEEP (*(.ResetVector.text)) 196 _ResetVector_text_end = ABSOLUTE(.); 197 } >rom0_seg :rom0_phdr 198 199 .text : HDR_MMU_PAGE_ALIGN 200 { 201 _stext = .; 202 __text_region_start = .; 203 z_mapped_start = .; 204 _text_start = ABSOLUTE(.); 205 *(.entry.text) 206 *(.init.literal) 207 *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) 208 *(.iram1.literal .iram1) 209 KEEP(*(.init)) 210 *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 211 *(.fini.literal) 212 KEEP(*(.fini)) 213 *(.gnu.version) 214 215 #include <zephyr/linker/kobject-text.ld> 216 217 MMU_PAGE_ALIGN 218 219 _text_end = ABSOLUTE(.); 220 _etext = .; 221 } >RAMABLE_REGION 222 __text_region_end = .; 223 224 .rodata : HDR_MMU_PAGE_ALIGN 225 { 226 __rodata_region_start = ABSOLUTE(.); 227 *(.rodata) 228 *(.rodata.*) 229 *(.gnu.linkonce.r.*) 230 *(.rodata1) 231 232 . = ALIGN(4); 233 #include <snippets-rodata.ld> 234 #include <zephyr/linker/kobject-rom.ld> 235 } >RAMABLE_REGION 236 237#include <zephyr/linker/common-rom.ld> 238/* Located in generated directory. This file is populated by calling 239 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs. 240 */ 241#include <snippets-rom-sections.ld> 242 243#include <zephyr/linker/thread-local-storage.ld> 244 245#include <zephyr/linker/cplusplus-rom.ld> 246 247 .rodata_end : ALIGN(4) 248 { 249 . = ALIGN(4); /* this table MUST be 4-byte aligned */ 250 _bss_table_start = ABSOLUTE(.); 251 LONG(_bss_start) 252 LONG(_bss_end) 253 _bss_table_end = ABSOLUTE(.); 254 255 MMU_PAGE_ALIGN 256 257 __rodata_region_end = ABSOLUTE(.); 258 } >RAMABLE_REGION 259 260#ifdef CONFIG_USERSPACE 261#define SMEM_PARTITION_ALIGN(size) MMU_PAGE_ALIGN 262#define APP_SHARED_ALIGN MMU_PAGE_ALIGN 263 264#include <app_smem.ld> 265 266 _image_ram_start = _app_smem_start; 267 _app_smem_size = _app_smem_end - _app_smem_start; 268 _app_smem_num_words = _app_smem_size >> 2; 269 _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); 270 _app_smem_num_words = _app_smem_size >> 2; 271#endif /* CONFIG_USERSPACE */ 272 273 .data : HDR_MMU_PAGE_ALIGN 274 { 275#ifndef CONFIG_USERSPACE 276 _image_ram_start = ABSOLUTE(.); 277#endif 278 __data_start = ABSOLUTE(.); 279 *(.data) 280 *(.data.*) 281 *(.gnu.linkonce.d.*) 282 KEEP(*(.gnu.linkonce.d.*personality*)) 283 *(.data1) 284 *(.sdata) 285 *(.sdata.*) 286 *(.gnu.linkonce.s.*) 287 *(.sdata2) 288 *(.sdata2.*) 289 *(.gnu.linkonce.s2.*) 290 KEEP(*(.jcr)) 291 292 . = ALIGN(4); 293 #include <snippets-rwdata.ld> 294 . = ALIGN(4); 295 296 MMU_PAGE_ALIGN 297 298 __data_end = ABSOLUTE(.); 299 } >RAMABLE_REGION 300 301#include <snippets-sections.ld> 302 303#include <snippets-data-sections.ld> 304 305#include <zephyr/linker/common-ram.ld> 306 307#include <zephyr/linker/cplusplus-ram.ld> 308 309#include <snippets-ram-sections.ld> 310 311 .bss (NOLOAD) : HDR_MMU_PAGE_ALIGN 312 { 313 . = ALIGN (8); 314 _bss_start = ABSOLUTE(.); 315 *(.dynsbss) 316 *(.sbss) 317 *(.sbss.*) 318 *(.gnu.linkonce.sb.*) 319 *(.scommon) 320 *(.sbss2) 321 *(.sbss2.*) 322 *(.gnu.linkonce.sb2.*) 323 *(.dynbss) 324 *(.bss) 325 *(.bss.*) 326 *(.gnu.linkonce.b.*) 327 *(COMMON) 328 *(.sram.bss) 329 . = ALIGN (8); 330 _bss_end = ABSOLUTE(.); 331 332 MMU_PAGE_ALIGN 333 334 } >RAM :sram0_bss_phdr 335 336#include <zephyr/linker/common-noinit.ld> 337 338/* Must be last in RAM */ 339#include <zephyr/linker/kobject-data.ld> 340 341#include <zephyr/linker/ram-end.ld> 342 343 _heap_start = .; 344 345 PROVIDE(_heap_sentry = ORIGIN(RAM) + LENGTH(RAM)); 346 PROVIDE(_heap_end = ORIGIN(RAM) + LENGTH(RAM)); 347 348 PROVIDE(__stack = z_interrupt_stacks + CONFIG_ISR_STACK_SIZE); 349 350#include <zephyr/linker/debug-sections.ld> 351 352 .xtensa.info 0 : { *(.xtensa.info) } 353 .xt.insn 0 : 354 { 355 KEEP (*(.xt.insn)) 356 KEEP (*(.gnu.linkonce.x.*)) 357 } 358 .xt.prop 0 : 359 { 360 KEEP (*(.xt.prop)) 361 KEEP (*(.xt.prop.*)) 362 KEEP (*(.gnu.linkonce.prop.*)) 363 } 364 .xt.lit 0 : 365 { 366 KEEP (*(.xt.lit)) 367 KEEP (*(.xt.lit.*)) 368 KEEP (*(.gnu.linkonce.p.*)) 369 } 370 .debug.xt.callgraph 0 : 371 { 372 KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*)) 373 } 374} 375