1/* 2 * Copyright 2023 NXP 3 * Copyright (c) 2013-2014 Wind River Systems, Inc. 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 9/* This is mostly a copy of arch/arm64/scripts/linker.ld with 10 * a few SOF-related changes. This is needed in order to avoid 11 * introducing sections based on CONFIG_SOF in the main ARM64 12 * linker script. 13 */ 14#include <zephyr/linker/sections.h> 15#include <zephyr/devicetree.h> 16 17#include <zephyr/linker/linker-defs.h> 18#include <zephyr/linker/linker-tool.h> 19 20/* physical address of RAM */ 21#ifdef CONFIG_XIP 22 #define ROMABLE_REGION FLASH 23#else 24 #define ROMABLE_REGION RAM 25#endif 26#define RAMABLE_REGION RAM 27 28#if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0) 29 #define ROM_ADDR RAM_ADDR 30#else 31 #define ROM_ADDR (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET) 32#endif 33 34#if CONFIG_FLASH_LOAD_SIZE > 0 35 #define ROM_SIZE CONFIG_FLASH_LOAD_SIZE 36#else 37 #define ROM_SIZE (CONFIG_FLASH_SIZE * 1K - CONFIG_FLASH_LOAD_OFFSET) 38#endif 39 40#define RAM_SIZE (CONFIG_SRAM_SIZE * 1K) 41#define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS 42 43#if defined(CONFIG_ARM_MMU) 44 _region_min_align = CONFIG_MMU_PAGE_SIZE; 45#elif defined(CONFIG_ARM_MPU) 46 _region_min_align = CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE; 47 #define BSS_ALIGN ALIGN(_region_min_align) 48#else 49 /* If building without MMU support, use default 4-byte alignment. */ 50 _region_min_align = 4; 51#endif 52 53#ifndef BSS_ALIGN 54#define BSS_ALIGN 55#endif 56 57#define MMU_ALIGN . = ALIGN(_region_min_align) 58 59MEMORY 60{ 61 FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE 62 RAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE 63 /* Used by and documented in include/linker/intlist.ld */ 64 IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K 65} 66 67ENTRY(CONFIG_KERNEL_ENTRY) 68 69SECTIONS 70{ 71 72#include <zephyr/linker/rel-sections.ld> 73 74 /* 75 * .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose', 76 * before text section. 77 */ 78 /DISCARD/ : 79 { 80 *(.plt) 81 } 82 83 /DISCARD/ : 84 { 85 *(.iplt) 86 } 87 88 GROUP_START(ROMABLE_REGION) 89 90 __rom_region_start = ROM_ADDR; 91 92 SECTION_PROLOGUE(_TEXT_SECTION_NAME,,) 93 { 94 __text_region_start = .; 95#ifndef CONFIG_XIP 96 z_mapped_start = .; 97#endif 98 99#ifdef CONFIG_AARCH64_IMAGE_HEADER 100 KEEP(*(.image_header)) 101 KEEP(*(".image_header.*")) 102#endif 103 104 _vector_start = .; 105 KEEP(*(.exc_vector_table)) 106 KEEP(*(".exc_vector_table.*")) 107 108 KEEP(*(.vectors)) 109 110 _vector_end = .; 111 112 *(.text) 113 *(".text.*") 114 *(.gnu.linkonce.t.*) 115 116 /* 117 * These are here according to 'arm-zephyr-elf-ld --verbose', 118 * after .gnu.linkonce.t.* 119 */ 120 *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) 121 122#include <zephyr/linker/kobject-text.ld> 123 124 MMU_ALIGN; 125 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 126 127 __text_region_end = .; 128 __text_region_size = __text_region_end - __text_region_start; 129 130#if defined (CONFIG_CPP) 131 SECTION_PROLOGUE(.ARM.extab,,) 132 { 133 /* 134 * .ARM.extab section containing exception unwinding information. 135 */ 136 *(.ARM.extab* .gnu.linkonce.armextab.*) 137 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 138#endif 139 140 SECTION_PROLOGUE(.ARM.exidx,,) 141 { 142 /* 143 * This section, related to stack and exception unwinding, is placed 144 * explicitly to prevent it from being shared between multiple regions. 145 * It must be defined for gcc to support 64-bit math and avoid 146 * section overlap. 147 */ 148 __exidx_start = .; 149#if defined (__GCC_LINKER_CMD__) 150 *(.ARM.exidx* gnu.linkonce.armexidx.*) 151#endif 152 __exidx_end = .; 153 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 154 155 __rodata_region_start = .; 156 157#include <zephyr/linker/common-rom.ld> 158#include <zephyr/linker/thread-local-storage.ld> 159 160 SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) 161 { 162 *(.rodata) 163 *(".rodata.*") 164 *(.gnu.linkonce.r.*) 165 166 /* 167 * The following is a workaround to allow compiling with GCC 12 and 168 * above, which may emit "GOT indirections" for the weak symbol 169 * references (see the GitHub issue zephyrproject-rtos/sdk-ng#547). 170 */ 171 *(.got) 172 *(.got.plt) 173 174/* Located in generated directory. This file is populated by the 175 * zephyr_linker_sources() Cmake function. 176 */ 177#include <snippets-rodata.ld> 178 179#include <zephyr/linker/kobject-rom.ld> 180 181 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 182 183#include <zephyr/linker/cplusplus-rom.ld> 184 MMU_ALIGN; 185 186 __rodata_region_end = .; 187 __rodata_region_size = __rodata_region_end - __rodata_region_start; 188 __rom_region_end = .; 189 190 /* 191 * These are here according to 'arm-zephyr-elf-ld --verbose', 192 * before data section. 193 */ 194 /DISCARD/ : 195 { 196 *(.igot.plt) 197 *(.igot) 198 } 199 200 GROUP_END(ROMABLE_REGION) 201 202 GROUP_START(RAMABLE_REGION) 203 204 . = RAM_ADDR; 205 /* Align the start of image RAM with the 206 * minimum granularity required by MMU. 207 */ 208 . = ALIGN(_region_min_align); 209 _image_ram_start = .; 210#ifdef CONFIG_XIP 211 z_mapped_start = .; 212#endif 213 214/* Located in generated directory. This file is populated by the 215 * zephyr_linker_sources() Cmake function. 216 */ 217#include <snippets-ram-sections.ld> 218 219#if defined(CONFIG_USERSPACE) 220#define APP_SHARED_ALIGN . = ALIGN(_region_min_align); 221#define SMEM_PARTITION_ALIGN(size) MMU_ALIGN 222 223#if defined(CONFIG_ARM_MPU) 224/* 225 * When _app_smem region is empty, alignment is also needed. If there 226 * is no alignment, the _app_smem_start used by arm mpu can be lower 227 * than __rodata_region_end, and this two regions can overlap. 228 * The Armv8-R aarch64 MPU does not allow overlapped regions. 229 */ 230#define EMPTY_APP_SHARED_ALIGN APP_SHARED_ALIGN 231#endif 232 233#include <app_smem.ld> 234 235 _app_smem_size = _app_smem_end - _app_smem_start; 236 _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); 237#endif /* CONFIG_USERSPACE */ 238 239 SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD), BSS_ALIGN) 240 { 241 /* 242 * For performance, BSS section is assumed to be 4 byte aligned and 243 * a multiple of 4 bytes 244 */ 245 . = ALIGN(4); 246 __bss_start = .; 247 __kernel_ram_start = .; 248 249 *(.bss) 250 *(".bss.*") 251 *(COMMON) 252 *(".kernel_bss.*") 253 254 /* 255 * As memory is cleared in words only, it is simpler to ensure the BSS 256 * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes. 257 */ 258 __bss_end = ALIGN(4); 259 } GROUP_NOLOAD_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) 260 261#if CONFIG_SOF 262 SECTION_PROLOGUE(.static_uuid_entries,,) 263 { 264 *(*.static_uuids) 265 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 266 267 SECTION_PROLOGUE(.static_log_entries,,) 268 { 269 *(*.static_log*) 270 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 271#endif /* CONFIG_SOF */ 272 273#include <zephyr/linker/common-noinit.ld> 274 275 SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,) 276 { 277 __data_region_start = .; 278 __data_start = .; 279 *(.data) 280 *(".data.*") 281 *(".kernel.*") 282#if CONFIG_SOF 283 _trace_ctx_start = ABSOLUTE(.); 284 *(.trace_ctx) 285 _trace_ctx_end = ABSOLUTE(.); 286#endif /* CONFIG_SOF */ 287 288/* Located in generated directory. This file is populated by the 289 * zephyr_linker_sources() Cmake function. 290 */ 291#include <snippets-rwdata.ld> 292 293 __data_end = .; 294 295 } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 296 __data_size = __data_end - __data_start; 297 __data_load_start = LOADADDR(_DATA_SECTION_NAME); 298 299 __data_region_load_start = LOADADDR(_DATA_SECTION_NAME); 300 301#include <zephyr/linker/common-ram.ld> 302#include <zephyr/linker/kobject-data.ld> 303#include <zephyr/linker/cplusplus-ram.ld> 304 305/* Located in generated directory. This file is populated by the 306 * zephyr_linker_sources() Cmake function. 307 */ 308#include <snippets-data-sections.ld> 309 310 __data_region_end = .; 311 312 313 /* Define linker symbols */ 314 315/* Located in generated directory. This file is populated by the 316 * zephyr_linker_sources() Cmake function. 317 */ 318#include <snippets-sections.ld> 319 320#define LAST_RAM_ALIGN MMU_ALIGN; 321 322#include <zephyr/linker/ram-end.ld> 323 324 GROUP_END(RAMABLE_REGION) 325 326 __kernel_ram_end = RAM_ADDR + RAM_SIZE; 327 __kernel_ram_size = __kernel_ram_end - __kernel_ram_start; 328 329#include <zephyr/linker/debug-sections.ld> 330 331 SECTION_PROLOGUE(.ARM.attributes, 0,) 332 { 333 KEEP(*(.ARM.attributes)) 334 KEEP(*(.gnu.attributes)) 335 } 336 337 /DISCARD/ : { *(.note.GNU-stack) } 338 339 340 /* Must be last in romable region */ 341 SECTION_PROLOGUE(.last_section,,) 342 { 343#ifdef CONFIG_LINKER_LAST_SECTION_ID 344 /* Fill last section with a word to ensure location counter and actual rom 345 * region data usage match. */ 346 LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN) 347#endif 348 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 349 350 /* To provide the image size as a const expression, 351 * calculate this value here. */ 352 _flash_used = LOADADDR(.last_section) + SIZEOF(.last_section) - __rom_region_start; 353 354} 355