1/* 2 * Copyright (c) 2016-2017 Jean-Paul Etienne <fractalclone@gmail.com> 3 * Copyright (c) 2021 Andes Technology Corporation 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8/** 9 * @file 10 * @brief Linker command/script file 11 * 12 * Linker script for the ae350 platform 13 */ 14 15#include <soc.h> 16#include <devicetree.h> 17 18#include <autoconf.h> 19#include <linker/sections.h> 20#include <linker/devicetree_regions.h> 21 22#include <linker/linker-defs.h> 23#include <linker/linker-tool.h> 24 25#ifdef CONFIG_XIP 26#define ROMABLE_REGION ROM 27#else 28#define ROMABLE_REGION RAM 29#endif 30#define RAMABLE_REGION RAM 31 32#define _VECTOR_SECTION_NAME vector 33#define _EXCEPTION_SECTION_NAME exceptions 34#define _RESET_SECTION_NAME reset 35 36#ifdef CONFIG_XIP 37#if DT_NODE_HAS_COMPAT_STATUS(DT_CHOSEN(zephyr_flash), soc_nv_flash, okay) 38#ifdef CONFIG_FLASH_LOAD_OFFSET 39#define ROM_BASE (DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) + \ 40 CONFIG_FLASH_LOAD_OFFSET) 41#else /* !CONFIG_FLASH_LOAD_OFFSET */ 42#define ROM_BASE DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) 43#endif /* CONFIG_FLASH_LOAD_OFFSET */ 44#define ROM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) 45#elif DT_NODE_HAS_COMPAT_STATUS(DT_CHOSEN(zephyr_flash), jedec_spi_nor, okay) 46/* For jedec,spi-nor we expect the spi controller to memory map the flash 47 * and for that mapping to be the second register property of the spi 48 * controller. 49 */ 50#define SPI_CTRL DT_PARENT(DT_CHOSEN(zephyr_flash)) 51#define ROM_BASE DT_REG_ADDR_BY_IDX(SPI_CTRL, 1) 52#define ROM_SIZE DT_REG_SIZE_BY_IDX(SPI_CTRL, 1) 53#endif 54#else /* CONFIG_XIP */ 55#define ROM_BASE CONFIG_SRAM_BASE_ADDRESS 56#define ROM_SIZE KB(CONFIG_SRAM_SIZE) 57#endif /* CONFIG_XIP */ 58 59#define RAM_BASE CONFIG_SRAM_BASE_ADDRESS 60#define RAM_SIZE KB(CONFIG_SRAM_SIZE) 61 62/* Make linker section alignment comply with PMA granularity. */ 63#if defined(CONFIG_SOC_ANDES_V5_PMA_REGION_MIN_ALIGN_AND_SIZE) 64_region_min_align = CONFIG_SOC_ANDES_V5_PMA_REGION_MIN_ALIGN_AND_SIZE; 65#else 66_region_min_align = 4; 67#endif 68 69#if defined(CONFIG_SOC_ANDES_V5_PMA) 70/* 71 * Andes-V5 PMA needs power-of-2 alignment. 72 */ 73#define MPU_MIN_SIZE_ALIGN . = ALIGN(_region_min_align); 74#define MPU_ALIGN(region_size) \ 75 . = ALIGN(_region_min_align); \ 76 . = ALIGN( 1 << LOG2CEIL(region_size)) 77#else 78#define MPU_MIN_SIZE_ALIGN 79#define MPU_ALIGN(region_size) \ 80 . = ALIGN(_region_min_align) 81#endif 82 83MEMORY 84{ 85#ifdef CONFIG_XIP 86 ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE 87#endif 88 RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE 89 90 /* Data & Instruction Tightly Coupled Memory */ 91 LINKER_DT_REGION_FROM_NODE(ITCM, rw, DT_CHOSEN(zephyr_itcm)) 92 LINKER_DT_REGION_FROM_NODE(DTCM, rw, DT_CHOSEN(zephyr_dtcm)) 93 94 /* Used by and documented in include/linker/intlist.ld */ 95 IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K 96} 97 98ENTRY(CONFIG_KERNEL_ENTRY) 99 100SECTIONS 101 { 102 103#include <linker/rel-sections.ld> 104 105 /* 106 * The .plt and .iplt are here according to 107 * 'riscv32-zephyr-elf-ld --verbose', before text section. 108 */ 109 SECTION_PROLOGUE(.plt,,) 110 { 111 *(.plt) 112 } 113 114 SECTION_PROLOGUE(.iplt,,) 115 { 116 *(.iplt) 117 } 118 119 GROUP_START(ROMABLE_REGION) 120 __rom_region_start = ROM_BASE; 121 122 SECTION_PROLOGUE(_VECTOR_SECTION_NAME,,) 123 { 124 /* In XIP mode, the .init section must be at the start of ROM */ 125 . = ALIGN(4); 126 KEEP(*(.init.*)) 127 . = ALIGN(4); 128 KEEP(*(.vectors.*)) 129 } GROUP_LINK_IN(ROMABLE_REGION) 130 131 SECTION_PROLOGUE(rom_start,,) 132 { 133 . = ALIGN(16); 134/* Located in generated directory. This file is populated by calling 135 * zephyr_linker_sources(ROM_START ...). 136 */ 137#include <snippets-rom-start.ld> 138 } GROUP_LINK_IN(ROMABLE_REGION) 139 140 SECTION_PROLOGUE(_RESET_SECTION_NAME,,) 141 { 142 KEEP(*(.reset.*)) 143 } GROUP_LINK_IN(ROMABLE_REGION) 144 145 SECTION_PROLOGUE(_EXCEPTION_SECTION_NAME,,) 146 { 147 KEEP(*(".exception.entry.*")) 148 *(".exception.other.*") 149 } GROUP_LINK_IN(ROMABLE_REGION) 150 151 SECTION_PROLOGUE(_TEXT_SECTION_NAME,,) 152 { 153 . = ALIGN(4); 154 KEEP(*(.openocd_debug)) 155 KEEP(*(".openocd_debug.*")) 156 157 __text_region_start = .; 158 159 *(.text) 160 *(".text.*") 161 *(.gnu.linkonce.t.*) 162#include <linker/kobject-text.ld> 163#ifdef CONFIG_SOC_FLASH_RAMCODE_SECTION 164 . = ALIGN(0x1000); 165 _ram_code_start = .; 166 KEEP(*(.__ram_code)) 167 __ram_code_size = . - _ram_code_start; 168 ASSERT((__ram_code_size <= 0x1000), 169 "__ram_code_size <= 4k bytes"); 170#endif 171 } GROUP_LINK_IN(ROMABLE_REGION) 172 173 __text_region_end = .; 174 175 __rodata_region_start = .; 176#include <linker/common-rom.ld> 177#include <linker/thread-local-storage.ld> 178 179 SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) 180 { 181 . = ALIGN(4); 182 *(.srodata) 183 *(".srodata.*") 184 *(.rodata) 185 *(".rodata.*") 186 *(.gnu.linkonce.r.*) 187 *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) 188 189/* Located in generated directory. This file is populated by the 190 * zephyr_linker_sources() Cmake function. 191 */ 192#include <snippets-rodata.ld> 193#include <linker/kobject-rom.ld> 194 . = ALIGN(4); 195 } GROUP_LINK_IN(ROMABLE_REGION) 196 197#include <linker/cplusplus-rom.ld> 198 __rodata_region_end = .; 199 MPU_ALIGN(__rodata_region_end - __rom_region_start); 200 GROUP_END(ROMABLE_REGION) 201 202 GROUP_START(RAMABLE_REGION) 203 204#if defined(CONFIG_USERSPACE) 205#define APP_SHARED_ALIGN MPU_MIN_SIZE_ALIGN 206#define SMEM_PARTITION_ALIGN MPU_ALIGN 207 208#include <app_smem.ld> 209 210 _image_ram_start = _app_smem_start; 211 _app_smem_size = _app_smem_end - _app_smem_start; 212 _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); 213#endif /* CONFIG_USERSPACE */ 214 215 SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) 216 { 217 MPU_MIN_SIZE_ALIGN 218 /* 219 * For performance, BSS section is assumed to be 4 byte aligned and 220 * a multiple of 4 bytes 221 */ 222 . = ALIGN(4); 223 __bss_start = .; 224 _image_ram_start = .; 225 __kernel_ram_start = .; 226 *(.sbss) 227 *(".sbss.*") 228 *(.bss) 229 *(".bss.*") 230 COMMON_SYMBOLS 231 /* 232 * As memory is cleared in words only, it is simpler to ensure the BSS 233 * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes. 234 */ 235 __bss_end = ALIGN(4); 236 } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) 237 238#include <linker/common-noinit.ld> 239#include <linker/cplusplus-ram.ld> 240 241 __data_region_start = .; 242 243 SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,) 244 { 245 . = ALIGN(4); 246 /* _image_ram_start = .; */ 247 __data_start = .; 248 249 *(.data) 250 *(".data.*") 251 252#ifdef CONFIG_RISCV_GP 253 /* 254 * RISC-V architecture has 12-bit signed immediate offsets in the 255 * instructions. If we can put the most commonly accessed globals 256 * in a special 4K span of memory addressed by the GP register, then 257 * we can access those values in a single instruction, saving both 258 * codespace and runtime. 259 * 260 * Since these immediate offsets are signed, place gp 0x800 past the 261 * beginning of .sdata so that we can use both positive and negative 262 * offsets. 263 */ 264 . = ALIGN(8); 265 PROVIDE (__global_pointer$ = . + 0x800); 266#endif 267 268 *(.sdata .sdata.* .gnu.linkonce.s.*) 269 270/* Located in generated directory. This file is populated by the 271 * zephyr_linker_sources() Cmake function. 272 */ 273#include <snippets-rwdata.ld> 274 __data_end = .; 275 276 } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 277 __data_size = __data_end - __data_start; 278 __data_load_start = LOADADDR(_DATA_SECTION_NAME); 279 280 __data_region_load_start = LOADADDR(_DATA_SECTION_NAME); 281 282#include <linker/common-ram.ld> 283#include <linker/kobject-data.ld> 284 285/* Located in generated directory. This file is populated by the 286 * zephyr_linker_sources() Cmake function. 287 */ 288#include <snippets-ram-sections.ld> 289 290/* Located in generated directory. This file is populated by the 291 * zephyr_linker_sources() Cmake function. 292 */ 293#include <snippets-data-sections.ld> 294 295 __data_region_end = .; 296 297 MPU_MIN_SIZE_ALIGN 298 299 _image_ram_end = .; 300 _end = .; /* end of image */ 301 302 __kernel_ram_end = .; 303 __kernel_ram_size = __kernel_ram_end - __kernel_ram_start; 304 305#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) 306GROUP_START(ITCM) 307 308 SECTION_PROLOGUE(_ITCM_SECTION_NAME,,SUBALIGN(8)) 309 { 310 __itcm_start = .; 311 *(.itcm) 312 *(".itcm.*") 313 __itcm_end = .; 314 } GROUP_LINK_IN(ITCM AT> ROMABLE_REGION) 315 316 __itcm_size = __itcm_end - __itcm_start; 317 __itcm_rom_start = LOADADDR(_ITCM_SECTION_NAME); 318 319GROUP_END(ITCM) 320#endif 321 322#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) 323GROUP_START(DTCM) 324 325 SECTION_PROLOGUE(_DTCM_BSS_SECTION_NAME, (NOLOAD),SUBALIGN(8)) 326 { 327 __dtcm_start = .; 328 __dtcm_bss_start = .; 329 *(.dtcm_bss) 330 *(".dtcm_bss.*") 331 __dtcm_bss_end = .; 332 } GROUP_LINK_IN(DTCM) 333 334 SECTION_PROLOGUE(_DTCM_NOINIT_SECTION_NAME, (NOLOAD),SUBALIGN(8)) 335 { 336 __dtcm_noinit_start = .; 337 *(.dtcm_noinit) 338 *(".dtcm_noinit.*") 339 __dtcm_noinit_end = .; 340 } GROUP_LINK_IN(DTCM) 341 342 SECTION_PROLOGUE(_DTCM_DATA_SECTION_NAME,,SUBALIGN(8)) 343 { 344 __dtcm_data_start = .; 345 *(.dtcm_data) 346 *(".dtcm_data.*") 347 __dtcm_data_end = .; 348 } GROUP_LINK_IN(DTCM AT> ROMABLE_REGION) 349 350 __dtcm_end = .; 351 352 __dtcm_data_rom_start = LOADADDR(_DTCM_DATA_SECTION_NAME); 353 354GROUP_END(DTCM) 355#endif 356 357/* Located in generated directory. This file is populated by the 358 * zephyr_linker_sources() Cmake function. 359 */ 360#include <snippets-sections.ld> 361 362 GROUP_END(RAMABLE_REGION) 363 364#include <linker/debug-sections.ld> 365 366 /DISCARD/ : { *(.note.GNU-stack) } 367 368 SECTION_PROLOGUE(.riscv.attributes, 0,) 369 { 370 KEEP(*(.riscv.attributes)) 371 KEEP(*(.gnu.attributes)) 372 } 373 374/* Must be last in romable region */ 375SECTION_PROLOGUE(.last_section,(NOLOAD),) 376{ 377} GROUP_LINK_IN(ROMABLE_REGION) 378 379/* To provide the image size as a const expression, 380 * calculate this value here. */ 381__rom_region_end = LOADADDR(.last_section); 382__rom_region_size = __rom_region_end - __rom_region_start; 383 384} 385