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