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 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 NOTES 135 /* Data section */ 136 137 _sdata = .; 138 RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE) 139 _edata = .; 140 141 /* Initialization code and data: */ 142 143 . = ALIGN(PAGE_SIZE); 144 __init_begin = .; 145 INIT_TEXT_SECTION(PAGE_SIZE) 146 147 .init.data : 148 { 149 INIT_DATA 150 . = ALIGN(0x4); 151 __tagtable_begin = .; 152 *(.taglist) 153 __tagtable_end = .; 154 155 . = ALIGN(16); 156 __boot_reloc_table_start = ABSOLUTE(.); 157 158#ifdef CONFIG_VECTORS_OFFSET 159 RELOCATE_ENTRY(_WindowVectors_text, 160 .WindowVectors.text); 161#if XCHAL_EXCM_LEVEL >= 2 162 RELOCATE_ENTRY(_Level2InterruptVector_text, 163 .Level2InterruptVector.text); 164#endif 165#if XCHAL_EXCM_LEVEL >= 3 166 RELOCATE_ENTRY(_Level3InterruptVector_text, 167 .Level3InterruptVector.text); 168#endif 169#if XCHAL_EXCM_LEVEL >= 4 170 RELOCATE_ENTRY(_Level4InterruptVector_text, 171 .Level4InterruptVector.text); 172#endif 173#if XCHAL_EXCM_LEVEL >= 5 174 RELOCATE_ENTRY(_Level5InterruptVector_text, 175 .Level5InterruptVector.text); 176#endif 177#if XCHAL_EXCM_LEVEL >= 6 178 RELOCATE_ENTRY(_Level6InterruptVector_text, 179 .Level6InterruptVector.text); 180#endif 181 RELOCATE_ENTRY(_KernelExceptionVector_text, 182 .KernelExceptionVector.text); 183 RELOCATE_ENTRY(_UserExceptionVector_text, 184 .UserExceptionVector.text); 185 RELOCATE_ENTRY(_DoubleExceptionVector_text, 186 .DoubleExceptionVector.text); 187 RELOCATE_ENTRY(_DebugInterruptVector_text, 188 .DebugInterruptVector.text); 189#endif 190#if defined(CONFIG_SMP) 191 RELOCATE_ENTRY(_SecondaryResetVector_text, 192 .SecondaryResetVector.text); 193#endif 194 195 196 __boot_reloc_table_end = ABSOLUTE(.) ; 197 198 INIT_SETUP(XCHAL_ICACHE_LINESIZE) 199 INIT_CALLS 200 CON_INITCALL 201 SECURITY_INITCALL 202 INIT_RAM_FS 203 } 204 205 PERCPU_SECTION(XCHAL_ICACHE_LINESIZE) 206 207 /* We need this dummy segment here */ 208 209 . = ALIGN(4); 210 .dummy : { LONG(0) } 211 212#ifdef CONFIG_VECTORS_OFFSET 213 /* The vectors are relocated to the real position at startup time */ 214 215 SECTION_VECTOR (_WindowVectors_text, 216 .WindowVectors.text, 217 WINDOW_VECTORS_VADDR, 218 .dummy) 219 SECTION_VECTOR (_DebugInterruptVector_text, 220 .DebugInterruptVector.text, 221 DEBUG_VECTOR_VADDR, 222 .WindowVectors.text) 223#undef LAST 224#define LAST .DebugInterruptVector.text 225#if XCHAL_EXCM_LEVEL >= 2 226 SECTION_VECTOR (_Level2InterruptVector_text, 227 .Level2InterruptVector.text, 228 INTLEVEL2_VECTOR_VADDR, 229 LAST) 230# undef LAST 231# define LAST .Level2InterruptVector.text 232#endif 233#if XCHAL_EXCM_LEVEL >= 3 234 SECTION_VECTOR (_Level3InterruptVector_text, 235 .Level3InterruptVector.text, 236 INTLEVEL3_VECTOR_VADDR, 237 LAST) 238# undef LAST 239# define LAST .Level3InterruptVector.text 240#endif 241#if XCHAL_EXCM_LEVEL >= 4 242 SECTION_VECTOR (_Level4InterruptVector_text, 243 .Level4InterruptVector.text, 244 INTLEVEL4_VECTOR_VADDR, 245 LAST) 246# undef LAST 247# define LAST .Level4InterruptVector.text 248#endif 249#if XCHAL_EXCM_LEVEL >= 5 250 SECTION_VECTOR (_Level5InterruptVector_text, 251 .Level5InterruptVector.text, 252 INTLEVEL5_VECTOR_VADDR, 253 LAST) 254# undef LAST 255# define LAST .Level5InterruptVector.text 256#endif 257#if XCHAL_EXCM_LEVEL >= 6 258 SECTION_VECTOR (_Level6InterruptVector_text, 259 .Level6InterruptVector.text, 260 INTLEVEL6_VECTOR_VADDR, 261 LAST) 262# undef LAST 263# define LAST .Level6InterruptVector.text 264#endif 265 SECTION_VECTOR (_KernelExceptionVector_text, 266 .KernelExceptionVector.text, 267 KERNEL_VECTOR_VADDR, 268 LAST) 269#undef LAST 270 SECTION_VECTOR (_UserExceptionVector_text, 271 .UserExceptionVector.text, 272 USER_VECTOR_VADDR, 273 .KernelExceptionVector.text) 274 SECTION_VECTOR (_DoubleExceptionVector_text, 275 .DoubleExceptionVector.text, 276 DOUBLEEXC_VECTOR_VADDR, 277 .UserExceptionVector.text) 278 279 . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; 280 281#endif 282#if defined(CONFIG_SMP) 283 284 SECTION_VECTOR (_SecondaryResetVector_text, 285 .SecondaryResetVector.text, 286 RESET_VECTOR1_VADDR, 287 .DoubleExceptionVector.text) 288 289 . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text); 290 291#endif 292 293 . = ALIGN(PAGE_SIZE); 294 295 __init_end = .; 296 297 BSS_SECTION(0, 8192, 0) 298 299 _end = .; 300 301 .xt.lit : { *(.xt.lit) } 302 .xt.prop : { *(.xt.prop) } 303 304 .debug 0 : { *(.debug) } 305 .line 0 : { *(.line) } 306 .debug_srcinfo 0 : { *(.debug_srcinfo) } 307 .debug_sfnames 0 : { *(.debug_sfnames) } 308 .debug_aranges 0 : { *(.debug_aranges) } 309 .debug_pubnames 0 : { *(.debug_pubnames) } 310 .debug_info 0 : { *(.debug_info) } 311 .debug_abbrev 0 : { *(.debug_abbrev) } 312 .debug_line 0 : { *(.debug_line) } 313 .debug_frame 0 : { *(.debug_frame) } 314 .debug_str 0 : { *(.debug_str) } 315 .debug_loc 0 : { *(.debug_loc) } 316 .debug_macinfo 0 : { *(.debug_macinfo) } 317 .debug_weaknames 0 : { *(.debug_weaknames) } 318 .debug_funcnames 0 : { *(.debug_funcnames) } 319 .debug_typenames 0 : { *(.debug_typenames) } 320 .debug_varnames 0 : { *(.debug_varnames) } 321 322 .xt.insn 0 : 323 { 324 *(.xt.insn) 325 *(.gnu.linkonce.x*) 326 } 327 328 .xt.lit 0 : 329 { 330 *(.xt.lit) 331 *(.gnu.linkonce.p*) 332 } 333 334 /* Sections to be discarded */ 335 DISCARDS 336} 337