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