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		*(.text.head)
56		_text = .;
57		*(.text .fixup .text.init.refok .exit.text.refok __ftr_alt_*)
58		SCHED_TEXT
59		LOCK_TEXT
60		KPROBES_TEXT
61
62#ifdef CONFIG_PPC32
63		*(.got1)
64		__got2_start = .;
65		*(.got2)
66		__got2_end = .;
67#endif /* CONFIG_PPC32 */
68
69		. = ALIGN(PAGE_SIZE);
70		_etext = .;
71		PROVIDE32 (etext = .);
72	} :kernel
73
74	/* Read-only data */
75	RODATA
76
77	/* Exception & bug tables */
78	__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
79		__start___ex_table = .;
80		*(__ex_table)
81		__stop___ex_table = .;
82	}
83
84	NOTES :kernel :notes
85
86	/* The dummy segment contents for the bug workaround mentioned above
87	   near PHDRS.  */
88	.dummy : {
89		LONG(0xf177)
90	} :kernel :dummy
91
92/*
93 * Init sections discarded at runtime
94 */
95	. = ALIGN(PAGE_SIZE);
96	__init_begin = .;
97
98	.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
99		_sinittext = .;
100		INIT_TEXT
101		_einittext = .;
102	} :kernel
103
104	/* .exit.text is discarded at runtime, not link time,
105	 * to deal with references from __bug_table
106	 */
107	.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
108		EXIT_TEXT
109	}
110
111	.init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
112		INIT_DATA
113		__vtop_table_begin = .;
114		*(.vtop_fixup);
115		__vtop_table_end = .;
116		__ptov_table_begin = .;
117		*(.ptov_fixup);
118		__ptov_table_end = .;
119#ifdef CONFIG_PPC_ISERIES
120		__dt_strings_start = .;
121		*(.dt_strings);
122		__dt_strings_end = .;
123#endif
124	}
125
126	. = ALIGN(16);
127	.init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
128		__setup_start = .;
129		*(.init.setup)
130		__setup_end = .;
131	}
132
133	.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
134		__initcall_start = .;
135		INITCALLS
136		__initcall_end = .;
137		}
138
139	.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
140		__con_initcall_start = .;
141		*(.con_initcall.init)
142		__con_initcall_end = .;
143	}
144
145	SECURITY_INIT
146
147	. = ALIGN(8);
148	__ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) {
149		__start___ftr_fixup = .;
150		*(__ftr_fixup)
151		__stop___ftr_fixup = .;
152	}
153	. = ALIGN(8);
154	__lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) {
155		__start___lwsync_fixup = .;
156		*(__lwsync_fixup)
157		__stop___lwsync_fixup = .;
158	}
159#ifdef CONFIG_PPC64
160	. = ALIGN(8);
161	__fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) {
162		__start___fw_ftr_fixup = .;
163		*(__fw_ftr_fixup)
164		__stop___fw_ftr_fixup = .;
165	}
166#endif
167#ifdef CONFIG_BLK_DEV_INITRD
168	. = ALIGN(PAGE_SIZE);
169	.init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
170		__initramfs_start = .;
171		*(.init.ramfs)
172		__initramfs_end = .;
173	}
174#endif
175	. = ALIGN(PAGE_SIZE);
176	.data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
177		__per_cpu_start = .;
178		*(.data.percpu)
179		*(.data.percpu.shared_aligned)
180		__per_cpu_end = .;
181	}
182
183	. = ALIGN(8);
184	.machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) {
185		__machine_desc_start = . ;
186		*(.machine.desc)
187		__machine_desc_end = . ;
188	}
189
190	/* freed after init ends here */
191	. = ALIGN(PAGE_SIZE);
192	__init_end = .;
193
194/*
195 * And now the various read/write data
196 */
197
198	. = ALIGN(PAGE_SIZE);
199	_sdata = .;
200
201#ifdef CONFIG_PPC32
202	.data : AT(ADDR(.data) - LOAD_OFFSET) {
203		DATA_DATA
204		*(.sdata)
205		*(.got.plt) *(.got)
206	}
207#else
208	.data : AT(ADDR(.data) - LOAD_OFFSET) {
209		DATA_DATA
210		*(.data.rel*)
211		*(.toc1)
212		*(.branch_lt)
213	}
214
215	.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
216		*(.opd)
217	}
218
219	.got : AT(ADDR(.got) - LOAD_OFFSET) {
220		__toc_start = .;
221		*(.got)
222		*(.toc)
223	}
224#endif
225
226	. = ALIGN(PAGE_SIZE);
227	_edata  =  .;
228	PROVIDE32 (edata = .);
229
230	/* The initial task and kernel stack */
231#ifdef CONFIG_PPC32
232	. = ALIGN(8192);
233#else
234	. = ALIGN(16384);
235#endif
236	.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
237		*(.data.init_task)
238	}
239
240	. = ALIGN(PAGE_SIZE);
241	.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
242		*(.data.page_aligned)
243	}
244
245	.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
246		*(.data.cacheline_aligned)
247	}
248
249	. = ALIGN(L1_CACHE_BYTES);
250	.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
251		*(.data.read_mostly)
252	}
253
254	. = ALIGN(PAGE_SIZE);
255	.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
256		__nosave_begin = .;
257		*(.data.nosave)
258		. = ALIGN(PAGE_SIZE);
259		__nosave_end = .;
260	}
261
262/*
263 * And finally the bss
264 */
265
266	.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
267		__bss_start = .;
268		*(.sbss) *(.scommon)
269		*(.dynbss)
270		*(.bss)
271		*(COMMON)
272		__bss_stop = .;
273	}
274
275	. = ALIGN(PAGE_SIZE);
276	_end = . ;
277	PROVIDE32 (end = .);
278}
279