1/* 2 * Copyright (c) 2020 Synopsys. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7/** 8 * @brief Common parts of the linker scripts for the ARCv2 targets for 9 * GNU and MWDT toolchains. 10 */ 11 12#include <zephyr/linker/sections.h> 13#include <zephyr/linker/linker-defs.h> 14#include <zephyr/linker/linker-tool.h> 15 16/* physical address of RAM */ 17#ifdef CONFIG_HARVARD 18 #define ROMABLE_REGION ICCM 19 #define RAMABLE_REGION DCCM 20 #define ROM_RAM_IN_SAME_REGION 0 21#else 22 #if defined(CONFIG_XIP) && (FLASH_SIZE != 0) 23 #define ROMABLE_REGION FLASH 24 #define RAMABLE_REGION SRAM 25 #define ROM_RAM_IN_SAME_REGION 0 26 #else 27 #define ROMABLE_REGION SRAM 28 #define RAMABLE_REGION SRAM 29 #define ROM_RAM_IN_SAME_REGION 1 30 #endif 31#endif 32 33#ifdef CONFIG_ARC_MPU_ENABLE 34 #if CONFIG_ARC_MPU_VER == 2 35 #define MPU_MIN_SIZE 2048 36 #elif (CONFIG_ARC_MPU_VER == 3) || (CONFIG_ARC_MPU_VER == 4) || \ 37 (CONFIG_ARC_MPU_VER == 6) || (CONFIG_ARC_MPU_VER == 8) 38 #define MPU_MIN_SIZE 32 39 #endif 40 #define MPU_MIN_SIZE_ALIGN . = ALIGN(MPU_MIN_SIZE); 41 #if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT) 42 #define MPU_ALIGN(region_size) \ 43 . = ALIGN(MPU_MIN_SIZE); \ 44 . = ALIGN( 1 << LOG2CEIL(region_size)) 45 #else 46 #define MPU_ALIGN(region_size) \ 47 . = ALIGN(MPU_MIN_SIZE) 48 #endif 49#else 50 #define MPU_MIN_SIZE_ALIGN 51 #define MPU_ALIGN(region_size) . = ALIGN(4) 52#endif 53 54OUTPUT_ARCH(arc) 55ENTRY(CONFIG_KERNEL_ENTRY) 56 57MEMORY { 58#ifdef FLASH_START 59 FLASH (rx) : ORIGIN = FLASH_START, LENGTH = FLASH_SIZE 60#endif 61#ifdef ICCM_START 62 ICCM (rwx) : ORIGIN = ICCM_START, LENGTH = ICCM_SIZE 63#endif 64#ifdef SRAM_START 65 SRAM (rwx) : ORIGIN = SRAM_START, LENGTH = SRAM_SIZE 66#endif 67#ifdef DCCM_START 68 DCCM (rw) : ORIGIN = DCCM_START, LENGTH = DCCM_SIZE 69#endif 70#ifdef XCCM_START 71 XCCM (rw) : ORIGIN = XCCM_START, LENGTH = XCCM_SIZE 72#endif 73#ifdef YCCM_START 74 YCCM (rw) : ORIGIN = YCCM_START, LENGTH = YCCM_SIZE 75#endif 76 /* Used by and documented in include/linker/intlist.ld */ 77 IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K 78} 79 80SECTIONS { 81 82#include <zephyr/linker/rel-sections.ld> 83 84#ifdef CONFIG_LLEXT 85#include <zephyr/linker/llext-sections.ld> 86#endif 87 88 GROUP_START(ROMABLE_REGION) 89 90 SECTION_PROLOGUE(_TEXT_SECTION_NAME,,ALIGN(1024)) { 91 __rom_region_start = .; 92 __text_region_start = .; 93 94/* Located in generated directory. This file is populated by the 95 * zephyr_linker_sources() Cmake function. 96 */ 97#include <snippets-rom-start.ld> 98 *(.text .text.*) 99 *(.gnu.linkonce.t.*) 100 101 . = ALIGN(4); 102#include <zephyr/linker/kobject-text.ld> 103 } GROUP_LINK_IN(ROMABLE_REGION) 104 105 __text_region_end = .; 106 __rodata_region_start = .; 107 108#include <zephyr/linker/common-rom.ld> 109/* Located in generated directory. This file is populated by calling 110 * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs. 111 */ 112#include <snippets-rom-sections.ld> 113#ifdef __MWDT_LINKER_CMD__ 114 SECTION_DATA_PROLOGUE(tdata,,) 115 { 116 *(.tls .tls.*); 117 } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 118 119 #ifdef CONFIG_XIP 120 /* The "primary copy" of tls should be only in flash on XIP systems */ 121 PROVIDE(_arcmwdt_tls_start = LOADADDR(tdata)); 122 #else 123 PROVIDE(_arcmwdt_tls_start = ADDR(tdata)); 124 #endif 125 126 PROVIDE(_arcmwdt_tls_size = SIZEOF(tdata)); 127 128/* TODO: add mwdt specific ROM C++ sections */ 129#else 130#include <zephyr/linker/thread-local-storage.ld> 131#include <zephyr/linker/cplusplus-rom.ld> 132#endif /* __MWDT_LINKER_CMD__ */ 133 134 SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) { 135 *(".rodata") 136 *(".rodata.*") 137 *(.gnu.linkonce.r.*) 138 139/* Located in generated directory. This file is populated by the 140 * zephyr_linker_sources() Cmake function. 141 */ 142#include <snippets-rodata.ld> 143#include <zephyr/linker/kobject-rom.ld> 144 145#if defined(CONFIG_CPP) && !defined(CONFIG_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__) 146 . = ALIGN(4); 147 _fctors = .; 148 KEEP(*(.ctors*)) 149 _ectors = .; 150#endif /* CONFIG_CPP && !CONFIG_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */ 151 152/* This extra MPU alignment of RAMABLE_REGION is only required if we put ROMABLE_REGION and 153 * RAMABLE_REGION into the same (continuous) memory - otherwise we can get beginning of the 154 * RAMABLE_REGION in the end of ROMABLE_REGION MPU aperture. 155 */ 156#if ROM_RAM_IN_SAME_REGION 157 MPU_ALIGN(ABSOLUTE(.) - __rom_region_start); 158#endif 159 } GROUP_LINK_IN(ROMABLE_REGION) 160 161 __rodata_region_end = .; 162 163 MPU_ALIGN(__rodata_region_end - __rom_region_start); 164 __rom_region_end = .; 165 __rom_region_size = __rom_region_end - __rom_region_start; 166 167 GROUP_END(ROMABLE_REGION) 168 169 GROUP_START(RAMABLE_REGION) 170 171 MPU_MIN_SIZE_ALIGN 172 173 _image_ram_start = .; 174 175#include <app_data_alignment.ld> 176 177/* Located in generated directory. This file is populated by the 178 * zephyr_linker_sources() Cmake function. 179 */ 180#include <snippets-ram-sections.ld> 181 182#if defined(CONFIG_USERSPACE) 183#define APP_SHARED_ALIGN MPU_MIN_SIZE_ALIGN 184#define SMEM_PARTITION_ALIGN MPU_ALIGN 185 186#include <app_smem.ld> 187 _app_smem_size = _app_smem_end - _app_smem_start; 188 _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); 189#endif /* CONFIG_USERSPACE */ 190 191 SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) { 192 MPU_MIN_SIZE_ALIGN 193 /* 194 * For performance, BSS section is assumed to be 4 byte aligned and 195 * a multiple of 4 bytes 196 */ 197 . = ALIGN(4); 198 __bss_start = .; 199 __kernel_ram_start = .; 200 *(".bss") 201 *(".bss.*") 202 *(COMMON) 203 *(".kernel_bss.*") 204 205 /* 206 * BSP clears this memory in words only and doesn't clear any 207 * potential left over bytes. 208 */ 209 __bss_end = ALIGN(4); 210 } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) 211 212#include <zephyr/linker/common-noinit.ld> 213 214 GROUP_START(DATA_REGION) 215 216 SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,) { 217 218/* when XIP, .text is in ROM, but vector table must be at start of .data */ 219 __data_region_start = .; 220 __data_start = .; 221 *(".data") 222 *(".data.*") 223 *(".kernel.*") 224 225/* Located in generated directory. This file is populated by the 226 * zephyr_linker_sources() Cmake function. 227 */ 228#include <snippets-rwdata.ld> 229 230 __data_end = .; 231 232 } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 233 234 __data_size = __data_end - __data_start; 235 __data_load_start = LOADADDR(_DATA_SECTION_NAME); 236 237 __data_region_load_start = LOADADDR(_DATA_SECTION_NAME); 238 239#include <zephyr/linker/common-ram.ld> 240#include <zephyr/linker/kobject-data.ld> 241 242#ifdef __MWDT_LINKER_CMD__ 243/* TODO: add mwdt specific RAM C++ sections */ 244#else 245#include <zephyr/linker/cplusplus-ram.ld> 246#endif /* __MWDT_LINKER_CMD__ */ 247 248/* Located in generated directory. This file is populated by the 249 * zephyr_linker_sources() Cmake function. 250 */ 251#include <snippets-data-sections.ld> 252 253 __data_region_end = .; 254 255 MPU_MIN_SIZE_ALIGN 256 /* Define linker symbols */ 257 258 __kernel_ram_end = .; 259 __kernel_ram_size = __kernel_ram_end - __kernel_ram_start; 260 261#ifdef __MWDT_LINKER_CMD__ 262/* mwdt requires _fstack, _estack which will be used in _stkchk. 263 * _stkchk is inserted by mwdt automatically, if _fstack, _estack is not 264 * set correctly, the brk_s instruction will be called 265 * here, we use a trick to deceive the compiler. 266 */ 267 _fstack = _image_ram_start; 268 _estack = .; 269#endif /* __MWDT_LINKER_CMD__ */ 270 271#ifdef CONFIG_ARC_XY_ENABLE 272 SECTION_PROLOGUE(xdata,,) 273 { 274 __xdata_start = .; 275 *(.Xdata*) 276 __xdata_end = .; 277 } GROUP_DATA_LINK_IN(XCCM, RAMABLE_REGION) 278 279 SECTION_PROLOGUE(ydata,,) 280 { 281 __ydata_start = .; 282 *(.Ydata*) 283 __ydata_end = .; 284 } GROUP_DATA_LINK_IN(YCCM, RAMABLE_REGION) 285#endif 286 287/* Located in generated directory. This file is populated by the 288 * zephyr_linker_sources() Cmake function. 289 */ 290#include <snippets-sections.ld> 291 292#include <zephyr/linker/ram-end.ld> 293 294 GROUP_END(RAMABLE_REGION) 295 296#include <zephyr/linker/debug-sections.ld> 297 298 SECTION_PROLOGUE(.arcextmap, 0,) { 299 *(.arcextmap) 300 *(.arcextmap.*) 301 *(.gnu.linkonce.arcextmap.*) 302 } 303 304 SECTION_PROLOGUE(.ARC.attributes, 0,) { 305 KEEP(*(.ARC.attributes)) 306 KEEP(*(.gnu.attributes)) 307 } 308 309#if !defined(CONFIG_XIP) 310 /* 311 * Zephyr uses _estack as a start of heap allocation area. 312 * Region [_estack .. sram_end] should be defined in MPU. 313 * Including _image_ram region which is [_image_ram_start .. _image_ram_end] 314 * we get [_image_ram_start .. sram_end] region to be defined in MPU. 315 */ 316 __arc_rw_sram_size = SRAM_START + SRAM_SIZE - _image_ram_start; 317#endif 318 319 /DISCARD/ : { 320#if defined(CONFIG_CPP) && !defined(CONFIG_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__) 321 *(.dtors*) 322 *(.fini*) 323 *(.eh_frame*) 324#endif /* CONFIG_CPP && !CONFIG_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */ 325 *(.note.GNU-stack) 326 *(.got.plt) 327 *(.igot.plt) 328 *(.got) 329 *(.igot) 330 } 331} 332