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