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#ifndef KERNELOFFSET 34#define KERNELOFFSET 0xd0003000 35#endif 36 37/* Note: In the following macros, it would be nice to specify only the 38 vector name and section kind and construct "sym" and "section" using 39 CPP concatenation, but that does not work reliably. Concatenating a 40 string with "." produces an invalid token. CPP will not print a 41 warning because it thinks this is an assembly file, but it leaves 42 them as multiple tokens and there may or may not be whitespace 43 between them. */ 44 45/* Macro for a relocation entry */ 46 47#define RELOCATE_ENTRY(sym, section) \ 48 LONG(sym ## _start); \ 49 LONG(sym ## _end); \ 50 LONG(LOADADDR(section)) 51 52/* Macro to define a section for a vector. 53 * 54 * Use of the MIN function catches the types of errors illustrated in 55 * the following example: 56 * 57 * Assume the section .DoubleExceptionVector.literal is completely 58 * full. Then a programmer adds code to .DoubleExceptionVector.text 59 * that produces another literal. The final literal position will 60 * overlay onto the first word of the adjacent code section 61 * .DoubleExceptionVector.text. (In practice, the literals will 62 * overwrite the code, and the first few instructions will be 63 * garbage.) 64 */ 65 66#define SECTION_VECTOR(sym, section, addr, max_prevsec_size, prevsec) \ 67 section addr : AT((MIN(LOADADDR(prevsec) + max_prevsec_size, \ 68 LOADADDR(prevsec) + SIZEOF(prevsec)) + 3) & ~ 3) \ 69 { \ 70 . = ALIGN(4); \ 71 sym ## _start = ABSOLUTE(.); \ 72 *(section) \ 73 sym ## _end = ABSOLUTE(.); \ 74 } 75 76/* 77 * Mapping of input sections to output sections when linking. 78 */ 79 80SECTIONS 81{ 82 . = KERNELOFFSET; 83 /* .text section */ 84 85 _text = .; 86 _stext = .; 87 88 .text : 89 { 90 /* The HEAD_TEXT section must be the first section! */ 91 HEAD_TEXT 92 TEXT_TEXT 93 VMLINUX_SYMBOL(__sched_text_start) = .; 94 *(.sched.literal .sched.text) 95 VMLINUX_SYMBOL(__sched_text_end) = .; 96 VMLINUX_SYMBOL(__lock_text_start) = .; 97 *(.spinlock.literal .spinlock.text) 98 VMLINUX_SYMBOL(__lock_text_end) = .; 99 100 } 101 _etext = .; 102 PROVIDE (etext = .); 103 104 . = ALIGN(16); 105 106 RODATA 107 108 /* Relocation table */ 109 110 .fixup : { *(.fixup) } 111 112 EXCEPTION_TABLE(16) 113 /* Data section */ 114 115 _sdata = .; 116 RW_DATA_SECTION(XCHAL_ICACHE_LINESIZE, PAGE_SIZE, THREAD_SIZE) 117 _edata = .; 118 119 /* Initialization code and data: */ 120 121 . = ALIGN(PAGE_SIZE); 122 __init_begin = .; 123 INIT_TEXT_SECTION(PAGE_SIZE) 124 125 .init.data : 126 { 127 INIT_DATA 128 . = ALIGN(0x4); 129 __tagtable_begin = .; 130 *(.taglist) 131 __tagtable_end = .; 132 133 . = ALIGN(16); 134 __boot_reloc_table_start = ABSOLUTE(.); 135 136 RELOCATE_ENTRY(_WindowVectors_text, 137 .WindowVectors.text); 138#if XCHAL_EXCM_LEVEL >= 2 139 RELOCATE_ENTRY(_Level2InterruptVector_text, 140 .Level2InterruptVector.text); 141#endif 142#if XCHAL_EXCM_LEVEL >= 3 143 RELOCATE_ENTRY(_Level3InterruptVector_text, 144 .Level3InterruptVector.text); 145#endif 146#if XCHAL_EXCM_LEVEL >= 4 147 RELOCATE_ENTRY(_Level4InterruptVector_text, 148 .Level4InterruptVector.text); 149#endif 150#if XCHAL_EXCM_LEVEL >= 5 151 RELOCATE_ENTRY(_Level5InterruptVector_text, 152 .Level5InterruptVector.text); 153#endif 154#if XCHAL_EXCM_LEVEL >= 6 155 RELOCATE_ENTRY(_Level6InterruptVector_text, 156 .Level6InterruptVector.text); 157#endif 158 RELOCATE_ENTRY(_KernelExceptionVector_text, 159 .KernelExceptionVector.text); 160 RELOCATE_ENTRY(_UserExceptionVector_text, 161 .UserExceptionVector.text); 162 RELOCATE_ENTRY(_DoubleExceptionVector_literal, 163 .DoubleExceptionVector.literal); 164 RELOCATE_ENTRY(_DoubleExceptionVector_text, 165 .DoubleExceptionVector.text); 166 RELOCATE_ENTRY(_DebugInterruptVector_text, 167 .DebugInterruptVector.text); 168#if defined(CONFIG_SMP) 169 RELOCATE_ENTRY(_SecondaryResetVector_text, 170 .SecondaryResetVector.text); 171#endif 172 173 174 __boot_reloc_table_end = ABSOLUTE(.) ; 175 176 INIT_SETUP(XCHAL_ICACHE_LINESIZE) 177 INIT_CALLS 178 CON_INITCALL 179 SECURITY_INITCALL 180 INIT_RAM_FS 181 } 182 183 PERCPU_SECTION(XCHAL_ICACHE_LINESIZE) 184 185 /* We need this dummy segment here */ 186 187 . = ALIGN(4); 188 .dummy : { LONG(0) } 189 190 /* The vectors are relocated to the real position at startup time */ 191 192 SECTION_VECTOR (_WindowVectors_text, 193 .WindowVectors.text, 194 WINDOW_VECTORS_VADDR, 4, 195 .dummy) 196 SECTION_VECTOR (_DebugInterruptVector_literal, 197 .DebugInterruptVector.literal, 198 DEBUG_VECTOR_VADDR - 4, 199 SIZEOF(.WindowVectors.text), 200 .WindowVectors.text) 201 SECTION_VECTOR (_DebugInterruptVector_text, 202 .DebugInterruptVector.text, 203 DEBUG_VECTOR_VADDR, 204 4, 205 .DebugInterruptVector.literal) 206#undef LAST 207#define LAST .DebugInterruptVector.text 208#if XCHAL_EXCM_LEVEL >= 2 209 SECTION_VECTOR (_Level2InterruptVector_text, 210 .Level2InterruptVector.text, 211 INTLEVEL2_VECTOR_VADDR, 212 SIZEOF(LAST), LAST) 213# undef LAST 214# define LAST .Level2InterruptVector.text 215#endif 216#if XCHAL_EXCM_LEVEL >= 3 217 SECTION_VECTOR (_Level3InterruptVector_text, 218 .Level3InterruptVector.text, 219 INTLEVEL3_VECTOR_VADDR, 220 SIZEOF(LAST), LAST) 221# undef LAST 222# define LAST .Level3InterruptVector.text 223#endif 224#if XCHAL_EXCM_LEVEL >= 4 225 SECTION_VECTOR (_Level4InterruptVector_text, 226 .Level4InterruptVector.text, 227 INTLEVEL4_VECTOR_VADDR, 228 SIZEOF(LAST), LAST) 229# undef LAST 230# define LAST .Level4InterruptVector.text 231#endif 232#if XCHAL_EXCM_LEVEL >= 5 233 SECTION_VECTOR (_Level5InterruptVector_text, 234 .Level5InterruptVector.text, 235 INTLEVEL5_VECTOR_VADDR, 236 SIZEOF(LAST), LAST) 237# undef LAST 238# define LAST .Level5InterruptVector.text 239#endif 240#if XCHAL_EXCM_LEVEL >= 6 241 SECTION_VECTOR (_Level6InterruptVector_text, 242 .Level6InterruptVector.text, 243 INTLEVEL6_VECTOR_VADDR, 244 SIZEOF(LAST), LAST) 245# undef LAST 246# define LAST .Level6InterruptVector.text 247#endif 248 SECTION_VECTOR (_KernelExceptionVector_literal, 249 .KernelExceptionVector.literal, 250 KERNEL_VECTOR_VADDR - 4, 251 SIZEOF(LAST), LAST) 252#undef LAST 253 SECTION_VECTOR (_KernelExceptionVector_text, 254 .KernelExceptionVector.text, 255 KERNEL_VECTOR_VADDR, 256 4, 257 .KernelExceptionVector.literal) 258 SECTION_VECTOR (_UserExceptionVector_literal, 259 .UserExceptionVector.literal, 260 USER_VECTOR_VADDR - 4, 261 SIZEOF(.KernelExceptionVector.text), 262 .KernelExceptionVector.text) 263 SECTION_VECTOR (_UserExceptionVector_text, 264 .UserExceptionVector.text, 265 USER_VECTOR_VADDR, 266 4, 267 .UserExceptionVector.literal) 268 SECTION_VECTOR (_DoubleExceptionVector_literal, 269 .DoubleExceptionVector.literal, 270 DOUBLEEXC_VECTOR_VADDR - 48, 271 SIZEOF(.UserExceptionVector.text), 272 .UserExceptionVector.text) 273 SECTION_VECTOR (_DoubleExceptionVector_text, 274 .DoubleExceptionVector.text, 275 DOUBLEEXC_VECTOR_VADDR, 276 48, 277 .DoubleExceptionVector.literal) 278 279 . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; 280 281#if defined(CONFIG_SMP) 282 283 SECTION_VECTOR (_SecondaryResetVector_text, 284 .SecondaryResetVector.text, 285 RESET_VECTOR1_VADDR, 286 SIZEOF(.DoubleExceptionVector.text), 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 /DISCARD/ : { *(.exit.literal) } 337} 338