1/* 2 * arch/xtensa/kernel/vmlinux.lds.S 3 * 4 * Xtensa linker script 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 * 10 * Copyright (C) 2001 - 2008 Tensilica Inc. 11 * 12 * Chris Zankel <chris@zankel.net> 13 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca> 14 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> 15 */ 16 17#include <asm-generic/vmlinux.lds.h> 18#include <asm/page.h> 19#include <asm/thread_info.h> 20 21#include <asm/vectors.h> 22#include <variant/core.h> 23#include <platform/hardware.h> 24OUTPUT_ARCH(xtensa) 25ENTRY(_start) 26 27#ifdef __XTENSA_EB__ 28jiffies = jiffies_64 + 4; 29#else 30jiffies = jiffies_64; 31#endif 32 33/* Note: In the following macros, it would be nice to specify only the 34 vector name and section kind and construct "sym" and "section" using 35 CPP concatenation, but that does not work reliably. Concatenating a 36 string with "." produces an invalid token. CPP will not print a 37 warning because it thinks this is an assembly file, but it leaves 38 them as multiple tokens and there may or may not be whitespace 39 between them. */ 40 41/* Macro for a relocation entry */ 42 43#define RELOCATE_ENTRY(sym, section) \ 44 LONG(sym ## _start); \ 45 LONG(sym ## _end); \ 46 LONG(LOADADDR(section)) 47 48/* 49 * Macro to define a section for a vector. When CONFIG_VECTORS_OFFSET is 50 * defined code for every vector is located with other init data. At startup 51 * time head.S copies code for every vector to its final position according 52 * to description recorded in the corresponding RELOCATE_ENTRY. 53 */ 54 55#ifdef CONFIG_VECTORS_OFFSET 56#define SECTION_VECTOR(sym, section, addr, prevsec) \ 57 section addr : AT(((LOADADDR(prevsec) + SIZEOF(prevsec)) + 3) & ~ 3) \ 58 { \ 59 . = ALIGN(4); \ 60 sym ## _start = ABSOLUTE(.); \ 61 *(section) \ 62 sym ## _end = ABSOLUTE(.); \ 63 } 64#else 65#define SECTION_VECTOR(section, addr) \ 66 . = addr; \ 67 *(section) 68#endif 69 70/* 71 * Mapping of input sections to output sections when linking. 72 */ 73 74SECTIONS 75{ 76 . = KERNELOFFSET; 77 /* .text section */ 78 79 _text = .; 80 _stext = .; 81 82 .text : 83 { 84 /* The HEAD_TEXT section must be the first section! */ 85 HEAD_TEXT 86 87#ifndef CONFIG_VECTORS_OFFSET 88 . = ALIGN(PAGE_SIZE); 89 _vecbase = .; 90 91 SECTION_VECTOR (.WindowVectors.text, WINDOW_VECTORS_VADDR) 92#if XCHAL_EXCM_LEVEL >= 2 93 SECTION_VECTOR (.Level2InterruptVector.text, INTLEVEL2_VECTOR_VADDR) 94#endif 95#if XCHAL_EXCM_LEVEL >= 3 96 SECTION_VECTOR (.Level3InterruptVector.text, INTLEVEL3_VECTOR_VADDR) 97#endif 98#if XCHAL_EXCM_LEVEL >= 4 99 SECTION_VECTOR (.Level4InterruptVector.text, INTLEVEL4_VECTOR_VADDR) 100#endif 101#if XCHAL_EXCM_LEVEL >= 5 102 SECTION_VECTOR (.Level5InterruptVector.text, INTLEVEL5_VECTOR_VADDR) 103#endif 104#if XCHAL_EXCM_LEVEL >= 6 105 SECTION_VECTOR (.Level6InterruptVector.text, INTLEVEL6_VECTOR_VADDR) 106#endif 107 SECTION_VECTOR (.DebugInterruptVector.text, DEBUG_VECTOR_VADDR) 108 SECTION_VECTOR (.KernelExceptionVector.text, KERNEL_VECTOR_VADDR) 109 SECTION_VECTOR (.UserExceptionVector.text, USER_VECTOR_VADDR) 110 SECTION_VECTOR (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR) 111#endif 112 113 IRQENTRY_TEXT 114 SOFTIRQENTRY_TEXT 115 ENTRY_TEXT 116 TEXT_TEXT 117 SCHED_TEXT 118 CPUIDLE_TEXT 119 LOCK_TEXT 120 121 } 122 _etext = .; 123 PROVIDE (etext = .); 124 125 . = ALIGN(16); 126 127 RODATA 128 129 /* Relocation table */ 130 131 .fixup : { *(.fixup) } 132 133 EXCEPTION_TABLE(16) 134 /* Data section */ 135 136 _sdata = .; 137 RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE) 138 _edata = .; 139 140 /* Initialization code and data: */ 141 142 . = ALIGN(PAGE_SIZE); 143 __init_begin = .; 144 INIT_TEXT_SECTION(PAGE_SIZE) 145 146 .init.data : 147 { 148 INIT_DATA 149 . = ALIGN(0x4); 150 __tagtable_begin = .; 151 *(.taglist) 152 __tagtable_end = .; 153 154 . = ALIGN(16); 155 __boot_reloc_table_start = ABSOLUTE(.); 156 157#ifdef CONFIG_VECTORS_OFFSET 158 RELOCATE_ENTRY(_WindowVectors_text, 159 .WindowVectors.text); 160#if XCHAL_EXCM_LEVEL >= 2 161 RELOCATE_ENTRY(_Level2InterruptVector_text, 162 .Level2InterruptVector.text); 163#endif 164#if XCHAL_EXCM_LEVEL >= 3 165 RELOCATE_ENTRY(_Level3InterruptVector_text, 166 .Level3InterruptVector.text); 167#endif 168#if XCHAL_EXCM_LEVEL >= 4 169 RELOCATE_ENTRY(_Level4InterruptVector_text, 170 .Level4InterruptVector.text); 171#endif 172#if XCHAL_EXCM_LEVEL >= 5 173 RELOCATE_ENTRY(_Level5InterruptVector_text, 174 .Level5InterruptVector.text); 175#endif 176#if XCHAL_EXCM_LEVEL >= 6 177 RELOCATE_ENTRY(_Level6InterruptVector_text, 178 .Level6InterruptVector.text); 179#endif 180 RELOCATE_ENTRY(_KernelExceptionVector_text, 181 .KernelExceptionVector.text); 182 RELOCATE_ENTRY(_UserExceptionVector_text, 183 .UserExceptionVector.text); 184 RELOCATE_ENTRY(_DoubleExceptionVector_text, 185 .DoubleExceptionVector.text); 186 RELOCATE_ENTRY(_DebugInterruptVector_text, 187 .DebugInterruptVector.text); 188#endif 189#if defined(CONFIG_SMP) 190 RELOCATE_ENTRY(_SecondaryResetVector_text, 191 .SecondaryResetVector.text); 192#endif 193 194 195 __boot_reloc_table_end = ABSOLUTE(.) ; 196 197 INIT_SETUP(XCHAL_ICACHE_LINESIZE) 198 INIT_CALLS 199 CON_INITCALL 200 SECURITY_INITCALL 201 INIT_RAM_FS 202 } 203 204 PERCPU_SECTION(XCHAL_ICACHE_LINESIZE) 205 206 /* We need this dummy segment here */ 207 208 . = ALIGN(4); 209 .dummy : { LONG(0) } 210 211#ifdef CONFIG_VECTORS_OFFSET 212 /* The vectors are relocated to the real position at startup time */ 213 214 SECTION_VECTOR (_WindowVectors_text, 215 .WindowVectors.text, 216 WINDOW_VECTORS_VADDR, 217 .dummy) 218 SECTION_VECTOR (_DebugInterruptVector_text, 219 .DebugInterruptVector.text, 220 DEBUG_VECTOR_VADDR, 221 .WindowVectors.text) 222#undef LAST 223#define LAST .DebugInterruptVector.text 224#if XCHAL_EXCM_LEVEL >= 2 225 SECTION_VECTOR (_Level2InterruptVector_text, 226 .Level2InterruptVector.text, 227 INTLEVEL2_VECTOR_VADDR, 228 LAST) 229# undef LAST 230# define LAST .Level2InterruptVector.text 231#endif 232#if XCHAL_EXCM_LEVEL >= 3 233 SECTION_VECTOR (_Level3InterruptVector_text, 234 .Level3InterruptVector.text, 235 INTLEVEL3_VECTOR_VADDR, 236 LAST) 237# undef LAST 238# define LAST .Level3InterruptVector.text 239#endif 240#if XCHAL_EXCM_LEVEL >= 4 241 SECTION_VECTOR (_Level4InterruptVector_text, 242 .Level4InterruptVector.text, 243 INTLEVEL4_VECTOR_VADDR, 244 LAST) 245# undef LAST 246# define LAST .Level4InterruptVector.text 247#endif 248#if XCHAL_EXCM_LEVEL >= 5 249 SECTION_VECTOR (_Level5InterruptVector_text, 250 .Level5InterruptVector.text, 251 INTLEVEL5_VECTOR_VADDR, 252 LAST) 253# undef LAST 254# define LAST .Level5InterruptVector.text 255#endif 256#if XCHAL_EXCM_LEVEL >= 6 257 SECTION_VECTOR (_Level6InterruptVector_text, 258 .Level6InterruptVector.text, 259 INTLEVEL6_VECTOR_VADDR, 260 LAST) 261# undef LAST 262# define LAST .Level6InterruptVector.text 263#endif 264 SECTION_VECTOR (_KernelExceptionVector_text, 265 .KernelExceptionVector.text, 266 KERNEL_VECTOR_VADDR, 267 LAST) 268#undef LAST 269 SECTION_VECTOR (_UserExceptionVector_text, 270 .UserExceptionVector.text, 271 USER_VECTOR_VADDR, 272 .KernelExceptionVector.text) 273 SECTION_VECTOR (_DoubleExceptionVector_text, 274 .DoubleExceptionVector.text, 275 DOUBLEEXC_VECTOR_VADDR, 276 .UserExceptionVector.text) 277 278 . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; 279 280#endif 281#if defined(CONFIG_SMP) 282 283 SECTION_VECTOR (_SecondaryResetVector_text, 284 .SecondaryResetVector.text, 285 RESET_VECTOR1_VADDR, 286 .DoubleExceptionVector.text) 287 288 . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text); 289 290#endif 291 292 . = ALIGN(PAGE_SIZE); 293 294 __init_end = .; 295 296 BSS_SECTION(0, 8192, 0) 297 298 _end = .; 299 300 .xt.lit : { *(.xt.lit) } 301 .xt.prop : { *(.xt.prop) } 302 303 .debug 0 : { *(.debug) } 304 .line 0 : { *(.line) } 305 .debug_srcinfo 0 : { *(.debug_srcinfo) } 306 .debug_sfnames 0 : { *(.debug_sfnames) } 307 .debug_aranges 0 : { *(.debug_aranges) } 308 .debug_pubnames 0 : { *(.debug_pubnames) } 309 .debug_info 0 : { *(.debug_info) } 310 .debug_abbrev 0 : { *(.debug_abbrev) } 311 .debug_line 0 : { *(.debug_line) } 312 .debug_frame 0 : { *(.debug_frame) } 313 .debug_str 0 : { *(.debug_str) } 314 .debug_loc 0 : { *(.debug_loc) } 315 .debug_macinfo 0 : { *(.debug_macinfo) } 316 .debug_weaknames 0 : { *(.debug_weaknames) } 317 .debug_funcnames 0 : { *(.debug_funcnames) } 318 .debug_typenames 0 : { *(.debug_typenames) } 319 .debug_varnames 0 : { *(.debug_varnames) } 320 321 .xt.insn 0 : 322 { 323 *(.xt.insn) 324 *(.gnu.linkonce.x*) 325 } 326 327 .xt.lit 0 : 328 { 329 *(.xt.lit) 330 *(.gnu.linkonce.p*) 331 } 332 333 /* Sections to be discarded */ 334 DISCARDS 335} 336