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