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