aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Brandt <chris.brandt@renesas.com>2016-02-03 09:58:10 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2016-02-11 10:33:39 -0500
commit538bf4694898b19e76f32d554cc16135cf37b51c (patch)
tree23bf4422d05f626d03d3c46ea5e98c4f7c571f2e
parent8b6f2499ac45d5a0ab2e4b6f9613ab3f60416be1 (diff)
ARM: 8513/1: xip: Move XIP linking to a separate file
When building an XIP kernel, the linker script needs to be much different than a conventional kernel's script. Over time, it's been difficult to maintain both XIP and non-XIP layouts in one linker script. Therefore, this patch separates the two procedures into two completely different files. The new linker script is essentially a straight copy of the current script with all the non-CONFIG_XIP_KERNEL portions removed. Additionally, all CONFIG_XIP_KERNEL portions have been removed from the existing linker script...never to return again. It should be noted that this does not fix any current XIP issues, but rather is the first move in fixing them properly with subsequent patches. Signed-off-by: Chris Brandt <chris.brandt@renesas.com> Acked-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/kernel/vmlinux-xip.lds.S322
-rw-r--r--arch/arm/kernel/vmlinux.lds.S37
2 files changed, 332 insertions, 27 deletions
diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S
new file mode 100644
index 000000000000..6f59ef290289
--- /dev/null
+++ b/arch/arm/kernel/vmlinux-xip.lds.S
@@ -0,0 +1,322 @@
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/cache.h>
8#include <asm/thread_info.h>
9#include <asm/memory.h>
10#include <asm/page.h>
11#ifdef CONFIG_DEBUG_RODATA
12#include <asm/pgtable.h>
13#endif
14
15#define PROC_INFO \
16 . = ALIGN(4); \
17 VMLINUX_SYMBOL(__proc_info_begin) = .; \
18 *(.proc.info.init) \
19 VMLINUX_SYMBOL(__proc_info_end) = .;
20
21#define IDMAP_TEXT \
22 ALIGN_FUNCTION(); \
23 VMLINUX_SYMBOL(__idmap_text_start) = .; \
24 *(.idmap.text) \
25 VMLINUX_SYMBOL(__idmap_text_end) = .; \
26 . = ALIGN(PAGE_SIZE); \
27 VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \
28 *(.hyp.idmap.text) \
29 VMLINUX_SYMBOL(__hyp_idmap_text_end) = .;
30
31#ifdef CONFIG_HOTPLUG_CPU
32#define ARM_CPU_DISCARD(x)
33#define ARM_CPU_KEEP(x) x
34#else
35#define ARM_CPU_DISCARD(x) x
36#define ARM_CPU_KEEP(x)
37#endif
38
39#if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \
40 defined(CONFIG_GENERIC_BUG)
41#define ARM_EXIT_KEEP(x) x
42#define ARM_EXIT_DISCARD(x)
43#else
44#define ARM_EXIT_KEEP(x)
45#define ARM_EXIT_DISCARD(x) x
46#endif
47
48OUTPUT_ARCH(arm)
49ENTRY(stext)
50
51#ifndef __ARMEB__
52jiffies = jiffies_64;
53#else
54jiffies = jiffies_64 + 4;
55#endif
56
57SECTIONS
58{
59 /*
60 * XXX: The linker does not define how output sections are
61 * assigned to input sections when there are multiple statements
62 * matching the same input section name. There is no documented
63 * order of matching.
64 *
65 * unwind exit sections must be discarded before the rest of the
66 * unwind sections get included.
67 */
68 /DISCARD/ : {
69 *(.ARM.exidx.exit.text)
70 *(.ARM.extab.exit.text)
71 ARM_CPU_DISCARD(*(.ARM.exidx.cpuexit.text))
72 ARM_CPU_DISCARD(*(.ARM.extab.cpuexit.text))
73 ARM_EXIT_DISCARD(EXIT_TEXT)
74 ARM_EXIT_DISCARD(EXIT_DATA)
75 EXIT_CALL
76#ifndef CONFIG_MMU
77 *(.text.fixup)
78 *(__ex_table)
79#endif
80#ifndef CONFIG_SMP_ON_UP
81 *(.alt.smp.init)
82#endif
83 *(.discard)
84 *(.discard.*)
85 }
86
87 . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
88
89 .head.text : {
90 _text = .;
91 HEAD_TEXT
92 }
93
94#ifdef CONFIG_DEBUG_RODATA
95 . = ALIGN(1<<SECTION_SHIFT);
96#endif
97
98 .text : { /* Real text segment */
99 _stext = .; /* Text and read-only data */
100 IDMAP_TEXT
101 __exception_text_start = .;
102 *(.exception.text)
103 __exception_text_end = .;
104 IRQENTRY_TEXT
105 TEXT_TEXT
106 SCHED_TEXT
107 LOCK_TEXT
108 KPROBES_TEXT
109 *(.gnu.warning)
110 *(.glue_7)
111 *(.glue_7t)
112 . = ALIGN(4);
113 *(.got) /* Global offset table */
114 ARM_CPU_KEEP(PROC_INFO)
115 }
116
117#ifdef CONFIG_DEBUG_RODATA
118 . = ALIGN(1<<SECTION_SHIFT);
119#endif
120 RO_DATA(PAGE_SIZE)
121
122 . = ALIGN(4);
123 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
124 __start___ex_table = .;
125#ifdef CONFIG_MMU
126 *(__ex_table)
127#endif
128 __stop___ex_table = .;
129 }
130
131#ifdef CONFIG_ARM_UNWIND
132 /*
133 * Stack unwinding tables
134 */
135 . = ALIGN(8);
136 .ARM.unwind_idx : {
137 __start_unwind_idx = .;
138 *(.ARM.exidx*)
139 __stop_unwind_idx = .;
140 }
141 .ARM.unwind_tab : {
142 __start_unwind_tab = .;
143 *(.ARM.extab*)
144 __stop_unwind_tab = .;
145 }
146#endif
147
148 NOTES
149
150 _etext = .; /* End of text and rodata section */
151
152 /*
153 * The vectors and stubs are relocatable code, and the
154 * only thing that matters is their relative offsets
155 */
156 __vectors_start = .;
157 .vectors 0 : AT(__vectors_start) {
158 *(.vectors)
159 }
160 . = __vectors_start + SIZEOF(.vectors);
161 __vectors_end = .;
162
163 __stubs_start = .;
164 .stubs 0x1000 : AT(__stubs_start) {
165 *(.stubs)
166 }
167 . = __stubs_start + SIZEOF(.stubs);
168 __stubs_end = .;
169
170 INIT_TEXT_SECTION(8)
171 .exit.text : {
172 ARM_EXIT_KEEP(EXIT_TEXT)
173 }
174 .init.proc.info : {
175 ARM_CPU_DISCARD(PROC_INFO)
176 }
177 .init.arch.info : {
178 __arch_info_begin = .;
179 *(.arch.info.init)
180 __arch_info_end = .;
181 }
182 .init.tagtable : {
183 __tagtable_begin = .;
184 *(.taglist.init)
185 __tagtable_end = .;
186 }
187#ifdef CONFIG_SMP_ON_UP
188 .init.smpalt : {
189 __smpalt_begin = .;
190 *(.alt.smp.init)
191 __smpalt_end = .;
192 }
193#endif
194 .init.pv_table : {
195 __pv_table_begin = .;
196 *(.pv_table)
197 __pv_table_end = .;
198 }
199 .init.data : {
200 INIT_SETUP(16)
201 INIT_CALLS
202 CON_INITCALL
203 SECURITY_INITCALL
204 INIT_RAM_FS
205 }
206
207#ifdef CONFIG_SMP
208 PERCPU_SECTION(L1_CACHE_BYTES)
209#endif
210
211 __data_loc = ALIGN(4); /* location in binary */
212 . = PAGE_OFFSET + TEXT_OFFSET;
213
214 .data : AT(__data_loc) {
215 _data = .; /* address in memory */
216 _sdata = .;
217
218 /*
219 * first, the init task union, aligned
220 * to an 8192 byte boundary.
221 */
222 INIT_TASK_DATA(THREAD_SIZE)
223
224 . = ALIGN(PAGE_SIZE);
225 __init_begin = .;
226 INIT_DATA
227 ARM_EXIT_KEEP(EXIT_DATA)
228 . = ALIGN(PAGE_SIZE);
229 __init_end = .;
230
231 NOSAVE_DATA
232 CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
233 READ_MOSTLY_DATA(L1_CACHE_BYTES)
234
235 /*
236 * and the usual data section
237 */
238 DATA_DATA
239 CONSTRUCTORS
240
241 _edata = .;
242 }
243 _edata_loc = __data_loc + SIZEOF(.data);
244
245#ifdef CONFIG_HAVE_TCM
246 /*
247 * We align everything to a page boundary so we can
248 * free it after init has commenced and TCM contents have
249 * been copied to its destination.
250 */
251 .tcm_start : {
252 . = ALIGN(PAGE_SIZE);
253 __tcm_start = .;
254 __itcm_start = .;
255 }
256
257 /*
258 * Link these to the ITCM RAM
259 * Put VMA to the TCM address and LMA to the common RAM
260 * and we'll upload the contents from RAM to TCM and free
261 * the used RAM after that.
262 */
263 .text_itcm ITCM_OFFSET : AT(__itcm_start)
264 {
265 __sitcm_text = .;
266 *(.tcm.text)
267 *(.tcm.rodata)
268 . = ALIGN(4);
269 __eitcm_text = .;
270 }
271
272 /*
273 * Reset the dot pointer, this is needed to create the
274 * relative __dtcm_start below (to be used as extern in code).
275 */
276 . = ADDR(.tcm_start) + SIZEOF(.tcm_start) + SIZEOF(.text_itcm);
277
278 .dtcm_start : {
279 __dtcm_start = .;
280 }
281
282 /* TODO: add remainder of ITCM as well, that can be used for data! */
283 .data_dtcm DTCM_OFFSET : AT(__dtcm_start)
284 {
285 . = ALIGN(4);
286 __sdtcm_data = .;
287 *(.tcm.data)
288 . = ALIGN(4);
289 __edtcm_data = .;
290 }
291
292 /* Reset the dot pointer or the linker gets confused */
293 . = ADDR(.dtcm_start) + SIZEOF(.data_dtcm);
294
295 /* End marker for freeing TCM copy in linked object */
296 .tcm_end : AT(ADDR(.dtcm_start) + SIZEOF(.data_dtcm)){
297 . = ALIGN(PAGE_SIZE);
298 __tcm_end = .;
299 }
300#endif
301
302 BSS_SECTION(0, 0, 0)
303 _end = .;
304
305 STABS_DEBUG
306}
307
308/*
309 * These must never be empty
310 * If you have to comment these two assert statements out, your
311 * binutils is too old (for other reasons as well)
312 */
313ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
314ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
315
316/*
317 * The HYP init code can't be more than a page long,
318 * and should not cross a page boundary.
319 * The above comment applies as well.
320 */
321ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE,
322 "HYP init code too big or misaligned")
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index a6e395c53a48..cdc84693091b 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -3,6 +3,10 @@
3 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> 3 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
4 */ 4 */
5 5
6#ifdef CONFIG_XIP_KERNEL
7#include "vmlinux-xip.lds.S"
8#else
9
6#include <asm-generic/vmlinux.lds.h> 10#include <asm-generic/vmlinux.lds.h>
7#include <asm/cache.h> 11#include <asm/cache.h>
8#include <asm/thread_info.h> 12#include <asm/thread_info.h>
@@ -84,11 +88,7 @@ SECTIONS
84 *(.discard.*) 88 *(.discard.*)
85 } 89 }
86 90
87#ifdef CONFIG_XIP_KERNEL
88 . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
89#else
90 . = PAGE_OFFSET + TEXT_OFFSET; 91 . = PAGE_OFFSET + TEXT_OFFSET;
91#endif
92 .head.text : { 92 .head.text : {
93 _text = .; 93 _text = .;
94 HEAD_TEXT 94 HEAD_TEXT
@@ -152,14 +152,13 @@ SECTIONS
152 152
153 _etext = .; /* End of text and rodata section */ 153 _etext = .; /* End of text and rodata section */
154 154
155#ifndef CONFIG_XIP_KERNEL 155#ifdef CONFIG_DEBUG_RODATA
156# ifdef CONFIG_DEBUG_RODATA
157 . = ALIGN(1<<SECTION_SHIFT); 156 . = ALIGN(1<<SECTION_SHIFT);
158# else 157#else
159 . = ALIGN(PAGE_SIZE); 158 . = ALIGN(PAGE_SIZE);
160# endif
161 __init_begin = .;
162#endif 159#endif
160 __init_begin = .;
161
163 /* 162 /*
164 * The vectors and stubs are relocatable code, and the 163 * The vectors and stubs are relocatable code, and the
165 * only thing that matters is their relative offsets 164 * only thing that matters is their relative offsets
@@ -208,29 +207,21 @@ SECTIONS
208 __pv_table_end = .; 207 __pv_table_end = .;
209 } 208 }
210 .init.data : { 209 .init.data : {
211#ifndef CONFIG_XIP_KERNEL
212 INIT_DATA 210 INIT_DATA
213#endif
214 INIT_SETUP(16) 211 INIT_SETUP(16)
215 INIT_CALLS 212 INIT_CALLS
216 CON_INITCALL 213 CON_INITCALL
217 SECURITY_INITCALL 214 SECURITY_INITCALL
218 INIT_RAM_FS 215 INIT_RAM_FS
219 } 216 }
220#ifndef CONFIG_XIP_KERNEL
221 .exit.data : { 217 .exit.data : {
222 ARM_EXIT_KEEP(EXIT_DATA) 218 ARM_EXIT_KEEP(EXIT_DATA)
223 } 219 }
224#endif
225 220
226#ifdef CONFIG_SMP 221#ifdef CONFIG_SMP
227 PERCPU_SECTION(L1_CACHE_BYTES) 222 PERCPU_SECTION(L1_CACHE_BYTES)
228#endif 223#endif
229 224
230#ifdef CONFIG_XIP_KERNEL
231 __data_loc = ALIGN(4); /* location in binary */
232 . = PAGE_OFFSET + TEXT_OFFSET;
233#else
234#ifdef CONFIG_DEBUG_RODATA 225#ifdef CONFIG_DEBUG_RODATA
235 . = ALIGN(1<<SECTION_SHIFT); 226 . = ALIGN(1<<SECTION_SHIFT);
236#else 227#else
@@ -238,7 +229,6 @@ SECTIONS
238#endif 229#endif
239 __init_end = .; 230 __init_end = .;
240 __data_loc = .; 231 __data_loc = .;
241#endif
242 232
243 .data : AT(__data_loc) { 233 .data : AT(__data_loc) {
244 _data = .; /* address in memory */ 234 _data = .; /* address in memory */
@@ -250,15 +240,6 @@ SECTIONS
250 */ 240 */
251 INIT_TASK_DATA(THREAD_SIZE) 241 INIT_TASK_DATA(THREAD_SIZE)
252 242
253#ifdef CONFIG_XIP_KERNEL
254 . = ALIGN(PAGE_SIZE);
255 __init_begin = .;
256 INIT_DATA
257 ARM_EXIT_KEEP(EXIT_DATA)
258 . = ALIGN(PAGE_SIZE);
259 __init_end = .;
260#endif
261
262 NOSAVE_DATA 243 NOSAVE_DATA
263 CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) 244 CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
264 READ_MOSTLY_DATA(L1_CACHE_BYTES) 245 READ_MOSTLY_DATA(L1_CACHE_BYTES)
@@ -351,3 +332,5 @@ ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
351 */ 332 */
352ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE, 333ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE,
353 "HYP init code too big or misaligned") 334 "HYP init code too big or misaligned")
335
336#endif /* CONFIG_XIP_KERNEL */