linux/arch/arm/kernel/vmlinux.lds.S
<<
>>
Prefs
   1/* ld script to make ARM Linux kernel
   2 * taken from the i386 version by Russell King
   3 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
   4 */
   5
   6#include <asm-generic/vmlinux.lds.h>
   7#include <asm/thread_info.h>
   8#include <asm/memory.h>
   9#include <asm/page.h>
  10        
  11#define PROC_INFO                                                       \
  12        VMLINUX_SYMBOL(__proc_info_begin) = .;                          \
  13        *(.proc.info.init)                                              \
  14        VMLINUX_SYMBOL(__proc_info_end) = .;
  15
  16#ifdef CONFIG_HOTPLUG_CPU
  17#define ARM_CPU_DISCARD(x)
  18#define ARM_CPU_KEEP(x)         x
  19#else
  20#define ARM_CPU_DISCARD(x)      x
  21#define ARM_CPU_KEEP(x)
  22#endif
  23
  24#if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \
  25        defined(CONFIG_GENERIC_BUG)
  26#define ARM_EXIT_KEEP(x)        x
  27#define ARM_EXIT_DISCARD(x)
  28#else
  29#define ARM_EXIT_KEEP(x)
  30#define ARM_EXIT_DISCARD(x)     x
  31#endif
  32
  33OUTPUT_ARCH(arm)
  34ENTRY(stext)
  35
  36#ifndef __ARMEB__
  37jiffies = jiffies_64;
  38#else
  39jiffies = jiffies_64 + 4;
  40#endif
  41
  42SECTIONS
  43{
  44        /*
  45         * XXX: The linker does not define how output sections are
  46         * assigned to input sections when there are multiple statements
  47         * matching the same input section name.  There is no documented
  48         * order of matching.
  49         *
  50         * unwind exit sections must be discarded before the rest of the
  51         * unwind sections get included.
  52         */
  53        /DISCARD/ : {
  54                *(.ARM.exidx.exit.text)
  55                *(.ARM.extab.exit.text)
  56                ARM_CPU_DISCARD(*(.ARM.exidx.cpuexit.text))
  57                ARM_CPU_DISCARD(*(.ARM.extab.cpuexit.text))
  58                ARM_EXIT_DISCARD(EXIT_TEXT)
  59                ARM_EXIT_DISCARD(EXIT_DATA)
  60                EXIT_CALL
  61#ifndef CONFIG_HOTPLUG
  62                *(.ARM.exidx.devexit.text)
  63                *(.ARM.extab.devexit.text)
  64#endif
  65#ifndef CONFIG_MMU
  66                *(.fixup)
  67                *(__ex_table)
  68#endif
  69#ifndef CONFIG_SMP_ON_UP
  70                *(.alt.smp.init)
  71#endif
  72                *(.discard)
  73                *(.discard.*)
  74        }
  75
  76#ifdef CONFIG_XIP_KERNEL
  77        . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
  78#else
  79        . = PAGE_OFFSET + TEXT_OFFSET;
  80#endif
  81        .head.text : {
  82                _text = .;
  83                HEAD_TEXT
  84        }
  85        .text : {                       /* Real text segment            */
  86                _stext = .;             /* Text and read-only data      */
  87                        __exception_text_start = .;
  88                        *(.exception.text)
  89                        __exception_text_end = .;
  90                        IRQENTRY_TEXT
  91                        TEXT_TEXT
  92                        SCHED_TEXT
  93                        LOCK_TEXT
  94                        KPROBES_TEXT
  95#ifdef CONFIG_MMU
  96                        *(.fixup)
  97#endif
  98                        *(.gnu.warning)
  99                        *(.glue_7)
 100                        *(.glue_7t)
 101                . = ALIGN(4);
 102                *(.got)                 /* Global offset table          */
 103                        ARM_CPU_KEEP(PROC_INFO)
 104        }
 105
 106        RO_DATA(PAGE_SIZE)
 107
 108#ifdef CONFIG_ARM_UNWIND
 109        /*
 110         * Stack unwinding tables
 111         */
 112        . = ALIGN(8);
 113        .ARM.unwind_idx : {
 114                __start_unwind_idx = .;
 115                *(.ARM.exidx*)
 116                __stop_unwind_idx = .;
 117        }
 118        .ARM.unwind_tab : {
 119                __start_unwind_tab = .;
 120                *(.ARM.extab*)
 121                __stop_unwind_tab = .;
 122        }
 123#endif
 124
 125        _etext = .;                     /* End of text and rodata section */
 126
 127#ifndef CONFIG_XIP_KERNEL
 128        . = ALIGN(PAGE_SIZE);
 129        __init_begin = .;
 130#endif
 131
 132        INIT_TEXT_SECTION(8)
 133        .exit.text : {
 134                ARM_EXIT_KEEP(EXIT_TEXT)
 135        }
 136        .init.proc.info : {
 137                ARM_CPU_DISCARD(PROC_INFO)
 138        }
 139        .init.arch.info : {
 140                __arch_info_begin = .;
 141                *(.arch.info.init)
 142                __arch_info_end = .;
 143        }
 144        .init.tagtable : {
 145                __tagtable_begin = .;
 146                *(.taglist.init)
 147                __tagtable_end = .;
 148        }
 149#ifdef CONFIG_SMP_ON_UP
 150        .init.smpalt : {
 151                __smpalt_begin = .;
 152                *(.alt.smp.init)
 153                __smpalt_end = .;
 154        }
 155#endif
 156        .init.pv_table : {
 157                __pv_table_begin = .;
 158                *(.pv_table)
 159                __pv_table_end = .;
 160        }
 161        .init.data : {
 162#ifndef CONFIG_XIP_KERNEL
 163                INIT_DATA
 164#endif
 165                INIT_SETUP(16)
 166                INIT_CALLS
 167                CON_INITCALL
 168                SECURITY_INITCALL
 169                INIT_RAM_FS
 170        }
 171#ifndef CONFIG_XIP_KERNEL
 172        .exit.data : {
 173                ARM_EXIT_KEEP(EXIT_DATA)
 174        }
 175#endif
 176
 177        PERCPU_SECTION(32)
 178
 179#ifdef CONFIG_XIP_KERNEL
 180        __data_loc = ALIGN(4);          /* location in binary */
 181        . = PAGE_OFFSET + TEXT_OFFSET;
 182#else
 183        __init_end = .;
 184        . = ALIGN(THREAD_SIZE);
 185        __data_loc = .;
 186#endif
 187
 188        .data : AT(__data_loc) {
 189                _data = .;              /* address in memory */
 190                _sdata = .;
 191
 192                /*
 193                 * first, the init task union, aligned
 194                 * to an 8192 byte boundary.
 195                 */
 196                INIT_TASK_DATA(THREAD_SIZE)
 197
 198#ifdef CONFIG_XIP_KERNEL
 199                . = ALIGN(PAGE_SIZE);
 200                __init_begin = .;
 201                INIT_DATA
 202                ARM_EXIT_KEEP(EXIT_DATA)
 203                . = ALIGN(PAGE_SIZE);
 204                __init_end = .;
 205#endif
 206
 207                NOSAVE_DATA
 208                CACHELINE_ALIGNED_DATA(32)
 209                READ_MOSTLY_DATA(32)
 210
 211                /*
 212                 * The exception fixup table (might need resorting at runtime)
 213                 */
 214                . = ALIGN(32);
 215                __start___ex_table = .;
 216#ifdef CONFIG_MMU
 217                *(__ex_table)
 218#endif
 219                __stop___ex_table = .;
 220
 221                /*
 222                 * and the usual data section
 223                 */
 224                DATA_DATA
 225                CONSTRUCTORS
 226
 227                _edata = .;
 228        }
 229        _edata_loc = __data_loc + SIZEOF(.data);
 230
 231#ifdef CONFIG_HAVE_TCM
 232        /*
 233         * We align everything to a page boundary so we can
 234         * free it after init has commenced and TCM contents have
 235         * been copied to its destination.
 236         */
 237        .tcm_start : {
 238                . = ALIGN(PAGE_SIZE);
 239                __tcm_start = .;
 240                __itcm_start = .;
 241        }
 242
 243        /*
 244         * Link these to the ITCM RAM
 245         * Put VMA to the TCM address and LMA to the common RAM
 246         * and we'll upload the contents from RAM to TCM and free
 247         * the used RAM after that.
 248         */
 249        .text_itcm ITCM_OFFSET : AT(__itcm_start)
 250        {
 251                __sitcm_text = .;
 252                *(.tcm.text)
 253                *(.tcm.rodata)
 254                . = ALIGN(4);
 255                __eitcm_text = .;
 256        }
 257
 258        /*
 259         * Reset the dot pointer, this is needed to create the
 260         * relative __dtcm_start below (to be used as extern in code).
 261         */
 262        . = ADDR(.tcm_start) + SIZEOF(.tcm_start) + SIZEOF(.text_itcm);
 263
 264        .dtcm_start : {
 265                __dtcm_start = .;
 266        }
 267
 268        /* TODO: add remainder of ITCM as well, that can be used for data! */
 269        .data_dtcm DTCM_OFFSET : AT(__dtcm_start)
 270        {
 271                . = ALIGN(4);
 272                __sdtcm_data = .;
 273                *(.tcm.data)
 274                . = ALIGN(4);
 275                __edtcm_data = .;
 276        }
 277
 278        /* Reset the dot pointer or the linker gets confused */
 279        . = ADDR(.dtcm_start) + SIZEOF(.data_dtcm);
 280
 281        /* End marker for freeing TCM copy in linked object */
 282        .tcm_end : AT(ADDR(.dtcm_start) + SIZEOF(.data_dtcm)){
 283                . = ALIGN(PAGE_SIZE);
 284                __tcm_end = .;
 285        }
 286#endif
 287
 288        NOTES
 289
 290        BSS_SECTION(0, 0, 0)
 291        _end = .;
 292
 293        STABS_DEBUG
 294        .comment 0 : { *(.comment) }
 295}
 296
 297/*
 298 * These must never be empty
 299 * If you have to comment these two assert statements out, your
 300 * binutils is too old (for other reasons as well)
 301 */
 302ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
 303ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
 304