blob: f76e75548670e97eeac9112a8e48b53e37f9cc91 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* 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>
Russell King4f7a1812005-05-05 13:11:00 +01007#include <asm/thread_info.h>
Nicolas Pitre37d07b72005-10-29 21:44:56 +01008#include <asm/memory.h>
Linus Walleijf6430a92009-06-24 23:38:56 +01009#include <asm/page.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010
Russell King5085f3f2010-10-01 15:37:05 +010011#define PROC_INFO \
12 VMLINUX_SYMBOL(__proc_info_begin) = .; \
13 *(.proc.info.init) \
14 VMLINUX_SYMBOL(__proc_info_end) = .;
15
Will Deacon89038262011-09-30 11:43:29 +010016#define IDMAP_TEXT \
17 ALIGN_FUNCTION(); \
18 VMLINUX_SYMBOL(__idmap_text_start) = .; \
19 *(.idmap.text) \
20 VMLINUX_SYMBOL(__idmap_text_end) = .;
21
Russell King5085f3f2010-10-01 15:37:05 +010022#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
Simon Glass87e040b2011-08-16 23:44:26 +010030#if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \
31 defined(CONFIG_GENERIC_BUG)
Russell Kinga9ad21f2011-02-21 10:13:36 +000032#define ARM_EXIT_KEEP(x) x
Russell King6760b102011-09-20 23:35:15 +010033#define ARM_EXIT_DISCARD(x)
Russell Kinga9ad21f2011-02-21 10:13:36 +000034#else
35#define ARM_EXIT_KEEP(x)
Russell King6760b102011-09-20 23:35:15 +010036#define ARM_EXIT_DISCARD(x) x
Russell Kinga9ad21f2011-02-21 10:13:36 +000037#endif
38
Linus Torvalds1da177e2005-04-16 15:20:36 -070039OUTPUT_ARCH(arm)
40ENTRY(stext)
Nicolas Pitre37d07b72005-10-29 21:44:56 +010041
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#ifndef __ARMEB__
43jiffies = jiffies_64;
44#else
45jiffies = jiffies_64 + 4;
46#endif
Nicolas Pitre37d07b72005-10-29 21:44:56 +010047
Linus Torvalds1da177e2005-04-16 15:20:36 -070048SECTIONS
49{
Russell King39df8882011-05-26 11:25:33 +010050 /*
Russell King6760b102011-09-20 23:35:15 +010051 * 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 *
Russell King39df8882011-05-26 11:25:33 +010056 * 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))
Russell King6760b102011-09-20 23:35:15 +010064 ARM_EXIT_DISCARD(EXIT_TEXT)
65 ARM_EXIT_DISCARD(EXIT_DATA)
66 EXIT_CALL
Russell King39df8882011-05-26 11:25:33 +010067#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
Russell King6760b102011-09-20 23:35:15 +010078 *(.discard)
79 *(.discard.*)
Russell King39df8882011-05-26 11:25:33 +010080 }
81
Russell King9d4f13e2006-01-03 17:28:33 +000082#ifdef CONFIG_XIP_KERNEL
83 . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
84#else
85 . = PAGE_OFFSET + TEXT_OFFSET;
86#endif
Russell King1604d792011-07-05 22:56:41 +010087 .head.text : {
Russell Kinge2f81842011-07-06 10:53:22 +010088 _text = .;
Russell King1604d792011-07-05 22:56:41 +010089 HEAD_TEXT
90 }
Russell King3835d692011-07-06 10:39:34 +010091 .text : { /* Real text segment */
Russell Kinge2f81842011-07-06 10:53:22 +010092 _stext = .; /* Text and read-only data */
Russell King3835d692011-07-06 10:39:34 +010093 __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
Will Deacon89038262011-09-30 11:43:29 +0100101 IDMAP_TEXT
Russell King3835d692011-07-06 10:39:34 +0100102#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
Russell King1604d792011-07-05 22:56:41 +0100139 INIT_TEXT_SECTION(8)
140 .exit.text : {
141 ARM_EXIT_KEEP(EXIT_TEXT)
142 }
143 .init.proc.info : {
Russell King5085f3f2010-10-01 15:37:05 +0100144 ARM_CPU_DISCARD(PROC_INFO)
Russell King1604d792011-07-05 22:56:41 +0100145 }
146 .init.arch.info : {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147 __arch_info_begin = .;
Russell King1604d792011-07-05 22:56:41 +0100148 *(.arch.info.init)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 __arch_info_end = .;
Russell King1604d792011-07-05 22:56:41 +0100150 }
151 .init.tagtable : {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 __tagtable_begin = .;
Russell King1604d792011-07-05 22:56:41 +0100153 *(.taglist.init)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 __tagtable_end = .;
Russell King1604d792011-07-05 22:56:41 +0100155 }
Russell Kingf00ec482010-09-04 10:47:48 +0100156#ifdef CONFIG_SMP_ON_UP
Russell King1604d792011-07-05 22:56:41 +0100157 .init.smpalt : {
Russell Kingf00ec482010-09-04 10:47:48 +0100158 __smpalt_begin = .;
Russell King1604d792011-07-05 22:56:41 +0100159 *(.alt.smp.init)
Russell Kingf00ec482010-09-04 10:47:48 +0100160 __smpalt_end = .;
Russell King1604d792011-07-05 22:56:41 +0100161 }
Russell Kingf00ec482010-09-04 10:47:48 +0100162#endif
Russell King1604d792011-07-05 22:56:41 +0100163 .init.pv_table : {
Russell Kingdc21af92011-01-04 19:09:43 +0000164 __pv_table_begin = .;
Russell King1604d792011-07-05 22:56:41 +0100165 *(.pv_table)
Russell Kingdc21af92011-01-04 19:09:43 +0000166 __pv_table_end = .;
Russell King1604d792011-07-05 22:56:41 +0100167 }
168 .init.data : {
169#ifndef CONFIG_XIP_KERNEL
170 INIT_DATA
171#endif
Nelson Elhage78d75302009-10-02 16:32:47 -0400172 INIT_SETUP(16)
Nelson Elhage78d75302009-10-02 16:32:47 -0400173 INIT_CALLS
174 CON_INITCALL
175 SECURITY_INITCALL
176 INIT_RAM_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 }
Russell King1604d792011-07-05 22:56:41 +0100178#ifndef CONFIG_XIP_KERNEL
179 .exit.data : {
180 ARM_EXIT_KEEP(EXIT_DATA)
181 }
182#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183
Tejun Heo0415b00d12011-03-24 18:50:09 +0100184 PERCPU_SECTION(32)
Nelson Elhage78d75302009-10-02 16:32:47 -0400185
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186#ifdef CONFIG_XIP_KERNEL
187 __data_loc = ALIGN(4); /* location in binary */
Russell King9d4f13e2006-01-03 17:28:33 +0000188 . = PAGE_OFFSET + TEXT_OFFSET;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189#else
Russell King3835d692011-07-06 10:39:34 +0100190 __init_end = .;
Russell King4f7a1812005-05-05 13:11:00 +0100191 . = ALIGN(THREAD_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192 __data_loc = .;
193#endif
194
195 .data : AT(__data_loc) {
Russell King37efe642008-12-01 11:53:07 +0000196 _data = .; /* address in memory */
Catalin Marinas8c7e6572009-05-30 14:00:17 +0100197 _sdata = .;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198
199 /*
200 * first, the init task union, aligned
201 * to an 8192 byte boundary.
202 */
Nelson Elhage78d75302009-10-02 16:32:47 -0400203 INIT_TASK_DATA(THREAD_SIZE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204
205#ifdef CONFIG_XIP_KERNEL
Linus Walleijf6430a92009-06-24 23:38:56 +0100206 . = ALIGN(PAGE_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 __init_begin = .;
Sam Ravnborg01ba2bd2008-01-20 14:15:03 +0100208 INIT_DATA
Russell Kinga9ad21f2011-02-21 10:13:36 +0000209 ARM_EXIT_KEEP(EXIT_DATA)
Linus Walleijf6430a92009-06-24 23:38:56 +0100210 . = ALIGN(PAGE_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 __init_end = .;
212#endif
213
Nelson Elhage78d75302009-10-02 16:32:47 -0400214 NOSAVE_DATA
215 CACHELINE_ALIGNED_DATA(32)
Russell Kingdaf87412010-12-04 17:08:32 +0000216 READ_MOSTLY_DATA(32)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217
218 /*
Nicolas Pitre13b1f642005-10-13 22:04:37 +0100219 * The exception fixup table (might need resorting at runtime)
220 */
221 . = ALIGN(32);
222 __start___ex_table = .;
Russell King9641c7c2006-06-21 20:38:17 +0100223#ifdef CONFIG_MMU
Nicolas Pitre13b1f642005-10-13 22:04:37 +0100224 *(__ex_table)
Russell King9641c7c2006-06-21 20:38:17 +0100225#endif
Nicolas Pitre13b1f642005-10-13 22:04:37 +0100226 __stop___ex_table = .;
227
228 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 * and the usual data section
230 */
Sam Ravnborgca967252007-05-17 13:38:44 +0200231 DATA_DATA
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 CONSTRUCTORS
233
234 _edata = .;
235 }
Nicolas Pitree98ff7f2007-02-22 16:18:09 +0100236 _edata_loc = __data_loc + SIZEOF(.data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237
Linus Walleijbc581772009-09-15 17:30:37 +0100238#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
Pawel Molldc810ef2011-02-16 18:54:01 +0100295 NOTES
296
Nelson Elhage78d75302009-10-02 16:32:47 -0400297 BSS_SECTION(0, 0, 0)
298 _end = .;
299
300 STABS_DEBUG
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 .comment 0 : { *(.comment) }
302}
303
Russell King728f5c02005-11-17 16:43:14 +0000304/*
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 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
310ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")