1/* 2 * Copyright (c) 2013-2014 Wind River Systems, Inc. 3 * Copyright (c) 2016-2017 Jean-Paul Etienne <fractalclone@gmail.com> 4 * Copyright (c) 2018 Foundries.io Ltd 5 * Copyright (c) 2024 sensry.io 6 * 7 * This file is based on: 8 * 9 * - include/arch/arm/cortex_m/scripts/linker.ld 10 * - include/arch/riscv/common/linker.ld 11 * - include/arch/riscv/pulpino/linker.ld 12 * 13 * SPDX-License-Identifier: Apache-2.0 14 */ 15 16#include <zephyr/devicetree.h> 17 18#include <zephyr/linker/sections.h> 19#include <zephyr/linker/linker-defs.h> 20#include <zephyr/linker/linker-tool.h> 21 22#define MPU_ALIGN(region_size) . = ALIGN(4) 23 24/* 25 * Extra efforts would need to be taken to ensure the IRQ handlers are within 26 * jumping distance of the vector table in non-XIP builds, so avoid them. 27 */ 28#define ROMABLE_REGION ROM 29#define RAMABLE_REGION RAM 30 31## ROM AREA ## 32#define ROM_BASE 0x1C010100 33#define ROM_SIZE 0x5Fa00 34 35## RAM AREA ## 36#define RAM_BASE 0x1C070000 37#define RAM_SIZE 0x200000 38 39MEMORY 40 { 41 L2_START (rx) : ORIGIN = 0x1c010000, LENGTH = 0x00000080 42 L2_VALIDITY (rx) : ORIGIN = 0x1c010080, LENGTH = 0x00000080 43 44 ROM (rx) : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE /* 392kb */ 45 RAM (rwx) : ORIGIN = RAM_BASE, LENGTH = RAM_SIZE /* 2097kb */ 46 47 L2_PRIV_CH0 : ORIGIN = 0x1c004100, LENGTH = 0x2000 /* uDMA access */ 48 49 /* 50 * Special section, not included in the final binary, used 51 * to generate interrupt tables. See include/linker/intlist.ld. 52 */ 53 IDT_LIST : ORIGIN = 0xFFFFF7FF, LENGTH = 2K 54 } 55 56ENTRY(CONFIG_KERNEL_ENTRY) 57 58SECTIONS 59 { 60 61 .pre_start MAX(0x1c010000,ALIGN(0x80)) : 62 { 63 KEEP(*(.pre_start)) 64 } > L2_START 65 66 .validity_marker MAX(0x1c010080,ALIGN(0x80)) : 67 { 68 KEEP(*(.validity_marker)) 69 } > L2_VALIDITY 70 71 /* uninitialized space for uDMA access */ 72 .udma_access (NOLOAD): { 73 . = ALIGN(4); 74 _udma_space_start = .; 75 *(.udma_access) 76 _udma_space_end = .; 77 } > L2_PRIV_CH0 78 79 #include <zephyr/linker/rel-sections.ld> 80 81 #ifdef CONFIG_LLEXT 82 #include <zephyr/linker/llext-sections.ld> 83 #endif 84 85 SECTION_PROLOGUE(.plt,,) 86 { 87 *(.plt) 88 } 89 90 91 SECTION_PROLOGUE(.iplt,,) 92 { 93 *(.iplt) 94 } 95 96 97 GROUP_START(ROM) 98 __rom_region_start = ROM_BASE; 99 100 SECTION_PROLOGUE(_TEXT_SECTION_NAME,,) 101 { 102 103 /* Located in generated directory. This file is populated by calling 104 * zephyr_linker_sources(ROM_START ...). This typically contains the vector 105 * table and debug information. 106 */ 107 #include <snippets-rom-start.ld> 108 109 __text_region_start = .; 110 111 *(.text .text.*) 112 *(.gnu.linkonce.t.*) 113 *(.eh_frame) 114 115 } GROUP_LINK_IN(ROM) 116 117 __text_region_end = .; 118 119 120 __rodata_region_start = .; 121 122 #include <zephyr/linker/common-rom.ld> 123 #include <zephyr/linker/thread-local-storage.ld> 124 125 SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) 126 { 127 . = ALIGN(4); 128 *(.srodata) 129 *(".srodata.*") 130 *(.rodata) 131 *(.rodata.*) 132 *(.gnu.linkonce.r.*) 133 134 /* Located in generated directory. This file is populated by the 135 * zephyr_linker_sources() Cmake function. 136 */ 137 #include <snippets-rodata.ld> 138 139 } GROUP_LINK_IN(ROMABLE_REGION) 140 141 #include <zephyr/linker/cplusplus-rom.ld> 142 143 __rodata_region_end = .; 144 145 __rom_region_end = .; 146 GROUP_END(ROM) 147 148 GROUP_START(RAM) 149 150 SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,) 151 { 152 . = ALIGN(4); 153 _image_ram_start = .; 154 __data_region_start = .; 155 __data_start = .; 156 157 *(.data) 158 *(.data.*) 159 *(.gnu.linkonce.s.*) 160 161 /* https://groups.google.com/a/groups.riscv.org/d/msg/sw-dev/60IdaZj27dY/TKT3hbNlAgAJ */ 162 *(.sdata .sdata.* .gnu.linkonce.s.*) 163 *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) 164 165 /* Located in generated directory. This file is populated by the 166 * zephyr_linker_sources() Cmake function. 167 */ 168 #include <snippets-rwdata.ld> 169 170 __data_end = .; 171 172 } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) 173 __data_size = __data_end - __data_start; 174 175 176 __data_load_start = LOADADDR(_DATA_SECTION_NAME); 177 178 #include <zephyr/linker/common-ram.ld> 179 #include <zephyr/linker/cplusplus-ram.ld> 180 181 /* Located in generated directory. This file is populated by the 182 * zephyr_linker_sources() Cmake function. 183 */ 184 #include <snippets-data-sections.ld> 185 186 __data_region_end = .; 187 __data_region_load_start = LOADADDR(_DATA_SECTION_NAME); 188 189 SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) 190 { 191 /* 192 * For performance, BSS section is assumed to be 4 byte aligned and 193 * a multiple of 4 bytes, so it can be cleared in words. 194 */ 195 . = ALIGN(4); 196 __bss_start = .; 197 198 *(.bss .bss.*) 199 *(.sbss .sbss.*) 200 COMMON_SYMBOLS 201 202 /* Ensure 4 byte alignment for the entire section. */ 203 . = ALIGN(4); 204 __bss_end = .; 205 } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) 206 207 SECTION_PROLOGUE(_NOINIT_SECTION_NAME,(NOLOAD),) 208 { 209 /* 210 * This section is used for non-initialized objects that 211 * will not be cleared during the boot process. 212 */ 213 *(.noinit .noinit.*) 214 215 /* Located in generated directory. This file is populated by the 216 * zephyr_linker_sources() Cmake function. 217 */ 218 #include <snippets-noinit.ld> 219 220 } GROUP_LINK_IN(RAMABLE_REGION) 221 222 /* Located in generated directory. This file is populated by the 223 * zephyr_linker_sources() Cmake function. 224 */ 225 #include <snippets-ram-sections.ld> 226 227 /* Located in generated directory. This file is populated by the 228 * zephyr_linker_sources() Cmake function. 229 */ 230 #include <snippets-sections.ld> 231 232 #include <zephyr/linker/ram-end.ld> 233 234 GROUP_END(RAMABLE_REGION) 235 236 #ifdef CONFIG_GEN_ISR_TABLES 237 /* Bogus section, post-processed during the build to initialize interrupts. */ 238 #include <zephyr/linker/intlist.ld> 239 #endif 240 241 #include <zephyr/linker/debug-sections.ld> 242 243 SECTION_PROLOGUE(.riscv.attributes, 0,) 244 { 245 KEEP(*(.riscv.attributes)) 246 KEEP(*(.gnu.attributes)) 247 } 248 249 /* 250 * Pulpino toolchains emit these sections; we don't care about them, 251 * but need to avoid build system warnings about orphaned sections. 252 */ 253 SECTION_PROLOGUE(.Pulp_Chip.Info,,) 254 { 255 *(.Pulp_Chip.*) 256 } 257 258 } 259