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