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