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