1#ifdef CONFIG_PPC64
2#define PROVIDE32(x)	PROVIDE(__unused__##x)
3#else
4#define PROVIDE32(x)	PROVIDE(x)
5#endif
6#include <asm/page.h>
7#include <asm-generic/vmlinux.lds.h>
8#include <asm/cache.h>
9
10ENTRY(_stext)
11
12PHDRS {
13	kernel PT_LOAD FLAGS(7); /* RWX */
14	notes PT_NOTE FLAGS(0);
15	dummy PT_NOTE FLAGS(0);
16
17	/* binutils < 2.18 has a bug that makes it misbehave when taking an
18	   ELF file with all segments at load address 0 as input.  This
19	   happens when running "strip" on vmlinux, because of the AT() magic
20	   in this linker script.  People using GCC >= 4.2 won't run into
21	   this problem, because the "build-id" support will put some data
22	   into the "notes" segment (at a non-zero load address).
23
24	   To work around this, we force some data into both the "dummy"
25	   segment and the kernel segment, so the dummy segment will get a
26	   non-zero load address.  It's not enough to always create the
27	   "notes" segment, since if nothing gets assigned to it, its load
28	   address will be zero.  */
29}
30
31#ifdef CONFIG_PPC64
32OUTPUT_ARCH(powerpc:common64)
33jiffies = jiffies_64;
34#else
35OUTPUT_ARCH(powerpc:common)
36jiffies = jiffies_64 + 4;
37#endif
38SECTIONS
39{
40	/* Sections to be discarded. */
41	/DISCARD/ : {
42	*(.exitcall.exit)
43	EXIT_DATA
44	}
45
46	. = KERNELBASE;
47
48/*
49 * Text, read only data and other permanent read-only sections
50 */
51
52	/* Text and gots */
53	.text : AT(ADDR(.text) - LOAD_OFFSET) {
54		ALIGN_FUNCTION();
55		HEAD_TEXT
56		_text = .;
57		/* careful! __ftr_alt_* sections need to be close to .text */
58		*(.text .fixup __ftr_alt_* .ref.text)
59		SCHED_TEXT
60		LOCK_TEXT
61		KPROBES_TEXT
62		IRQENTRY_TEXT
63
64#ifdef CONFIG_PPC32
65		*(.got1)
66		__got2_start = .;
67		*(.got2)
68		__got2_end = .;
69#endif /* CONFIG_PPC32 */
70
71	} :kernel
72
73	. = ALIGN(PAGE_SIZE);
74	_etext = .;
75	PROVIDE32 (etext = .);
76
77	/* Read-only data */
78	RODATA
79
80	/* Exception & bug tables */
81	__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
82		__start___ex_table = .;
83		*(__ex_table)
84		__stop___ex_table = .;
85	}
86
87	NOTES :kernel :notes
88
89	/* The dummy segment contents for the bug workaround mentioned above
90	   near PHDRS.  */
91	.dummy : AT(ADDR(.dummy) - LOAD_OFFSET) {
92		LONG(0)
93		LONG(0)
94		LONG(0)
95	} :kernel :dummy
96
97/*
98 * Init sections discarded at runtime
99 */
100	. = ALIGN(PAGE_SIZE);
101	__init_begin = .;
102
103	.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
104		_sinittext = .;
105		INIT_TEXT
106		_einittext = .;
107	} :kernel
108
109	/* .exit.text is discarded at runtime, not link time,
110	 * to deal with references from __bug_table
111	 */
112	.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
113		EXIT_TEXT
114	}
115
116	.init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
117		INIT_DATA
118		__vtop_table_begin = .;
119		*(.vtop_fixup);
120		__vtop_table_end = .;
121		__ptov_table_begin = .;
122		*(.ptov_fixup);
123		__ptov_table_end = .;
124#ifdef CONFIG_PPC_ISERIES
125		__dt_strings_start = .;
126		*(.dt_strings);
127		__dt_strings_end = .;
128#endif
129	}
130
131	. = ALIGN(16);
132	.init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
133		__setup_start = .;
134		*(.init.setup)
135		__setup_end = .;
136	}
137
138	.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
139		__initcall_start = .;
140		INITCALLS
141		__initcall_end = .;
142		}
143
144	.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
145		__con_initcall_start = .;
146		*(.con_initcall.init)
147		__con_initcall_end = .;
148	}
149
150	SECURITY_INIT
151
152	. = ALIGN(8);
153	__ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) {
154		__start___ftr_fixup = .;
155		*(__ftr_fixup)
156		__stop___ftr_fixup = .;
157	}
158	. = ALIGN(8);
159	__mmu_ftr_fixup : AT(ADDR(__mmu_ftr_fixup) - LOAD_OFFSET) {
160		__start___mmu_ftr_fixup = .;
161		*(__mmu_ftr_fixup)
162		__stop___mmu_ftr_fixup = .;
163	}
164	. = ALIGN(8);
165	__lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) {
166		__start___lwsync_fixup = .;
167		*(__lwsync_fixup)
168		__stop___lwsync_fixup = .;
169	}
170#ifdef CONFIG_PPC64
171	. = ALIGN(8);
172	__fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) {
173		__start___fw_ftr_fixup = .;
174		*(__fw_ftr_fixup)
175		__stop___fw_ftr_fixup = .;
176	}
177#endif
178#ifdef CONFIG_BLK_DEV_INITRD
179	. = ALIGN(PAGE_SIZE);
180	.init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
181		__initramfs_start = .;
182		*(.init.ramfs)
183		__initramfs_end = .;
184	}
185#endif
186	PERCPU(PAGE_SIZE)
187
188	. = ALIGN(8);
189	.machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) {
190		__machine_desc_start = . ;
191		*(.machine.desc)
192		__machine_desc_end = . ;
193	}
194#ifdef CONFIG_RELOCATABLE
195	. = ALIGN(8);
196	.dynsym : AT(ADDR(.dynsym) - LOAD_OFFSET) { *(.dynsym) }
197	.dynstr : AT(ADDR(.dynstr) - LOAD_OFFSET) { *(.dynstr) }
198	.dynamic : AT(ADDR(.dynamic) - LOAD_OFFSET)
199	{
200		__dynamic_start = .;
201		*(.dynamic)
202	}
203	.hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) }
204	.interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) }
205	.rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET)
206	{
207		__rela_dyn_start = .;
208		*(.rela*)
209	}
210#endif
211
212	/* freed after init ends here */
213	. = ALIGN(PAGE_SIZE);
214	__init_end = .;
215
216/*
217 * And now the various read/write data
218 */
219
220	. = ALIGN(PAGE_SIZE);
221	_sdata = .;
222
223#ifdef CONFIG_PPC32
224	.data : AT(ADDR(.data) - LOAD_OFFSET) {
225		DATA_DATA
226		*(.sdata)
227		*(.got.plt) *(.got)
228	}
229#else
230	.data : AT(ADDR(.data) - LOAD_OFFSET) {
231		DATA_DATA
232		*(.data.rel*)
233		*(.toc1)
234		*(.branch_lt)
235	}
236
237	.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
238		*(.opd)
239	}
240
241	.got : AT(ADDR(.got) - LOAD_OFFSET) {
242		__toc_start = .;
243		*(.got)
244		*(.toc)
245	}
246#endif
247
248	. = ALIGN(PAGE_SIZE);
249	_edata  =  .;
250	PROVIDE32 (edata = .);
251
252	/* The initial task and kernel stack */
253#ifdef CONFIG_PPC32
254	. = ALIGN(8192);
255#else
256	. = ALIGN(16384);
257#endif
258	.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
259		*(.data.init_task)
260	}
261
262	. = ALIGN(PAGE_SIZE);
263	.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
264		*(.data.page_aligned)
265	}
266
267	. = ALIGN(L1_CACHE_BYTES);
268	.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
269		*(.data.cacheline_aligned)
270	}
271
272	. = ALIGN(L1_CACHE_BYTES);
273	.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
274		*(.data.read_mostly)
275	}
276
277	. = ALIGN(PAGE_SIZE);
278	.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
279		__nosave_begin = .;
280		*(.data.nosave)
281		. = ALIGN(PAGE_SIZE);
282		__nosave_end = .;
283	}
284
285/*
286 * And finally the bss
287 */
288
289	.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
290		__bss_start = .;
291		*(.sbss) *(.scommon)
292		*(.dynbss)
293		*(.bss)
294		*(COMMON)
295		__bss_stop = .;
296	}
297
298	. = ALIGN(PAGE_SIZE);
299	_end = . ;
300	PROVIDE32 (end = .);
301}
302