xref: /openbmc/linux/arch/arm64/kernel/vmlinux.lds.S (revision 9ac17575)
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * ld script to make ARM Linux kernel
4 * taken from the i386 version by Russell King
5 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
6 */
7
8#define RO_EXCEPTION_TABLE_ALIGN	8
9
10#include <asm-generic/vmlinux.lds.h>
11#include <asm/cache.h>
12#include <asm/kernel-pgtable.h>
13#include <asm/thread_info.h>
14#include <asm/memory.h>
15#include <asm/page.h>
16#include <asm/pgtable.h>
17
18#include "image.h"
19
20OUTPUT_ARCH(aarch64)
21ENTRY(_text)
22
23jiffies = jiffies_64;
24
25#define HYPERVISOR_TEXT					\
26	/*						\
27	 * Align to 4 KB so that			\
28	 * a) the HYP vector table is at its minimum	\
29	 *    alignment of 2048 bytes			\
30	 * b) the HYP init code will not cross a page	\
31	 *    boundary if its size does not exceed	\
32	 *    4 KB (see related ASSERT() below)		\
33	 */						\
34	. = ALIGN(SZ_4K);				\
35	__hyp_idmap_text_start = .;			\
36	*(.hyp.idmap.text)				\
37	__hyp_idmap_text_end = .;			\
38	__hyp_text_start = .;				\
39	*(.hyp.text)					\
40	__hyp_text_end = .;
41
42#define IDMAP_TEXT					\
43	. = ALIGN(SZ_4K);				\
44	__idmap_text_start = .;				\
45	*(.idmap.text)					\
46	__idmap_text_end = .;
47
48#ifdef CONFIG_HIBERNATION
49#define HIBERNATE_TEXT					\
50	. = ALIGN(SZ_4K);				\
51	__hibernate_exit_text_start = .;		\
52	*(.hibernate_exit.text)				\
53	__hibernate_exit_text_end = .;
54#else
55#define HIBERNATE_TEXT
56#endif
57
58#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
59#define TRAMP_TEXT					\
60	. = ALIGN(PAGE_SIZE);				\
61	__entry_tramp_text_start = .;			\
62	*(.entry.tramp.text)				\
63	. = ALIGN(PAGE_SIZE);				\
64	__entry_tramp_text_end = .;
65#else
66#define TRAMP_TEXT
67#endif
68
69/*
70 * The size of the PE/COFF section that covers the kernel image, which
71 * runs from _stext to _edata, must be a round multiple of the PE/COFF
72 * FileAlignment, which we set to its minimum value of 0x200. '_stext'
73 * itself is 4 KB aligned, so padding out _edata to a 0x200 aligned
74 * boundary should be sufficient.
75 */
76PECOFF_FILE_ALIGNMENT = 0x200;
77
78#ifdef CONFIG_EFI
79#define PECOFF_EDATA_PADDING	\
80	.pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); }
81#else
82#define PECOFF_EDATA_PADDING
83#endif
84
85SECTIONS
86{
87	/*
88	 * XXX: The linker does not define how output sections are
89	 * assigned to input sections when there are multiple statements
90	 * matching the same input section name.  There is no documented
91	 * order of matching.
92	 */
93	/DISCARD/ : {
94		EXIT_CALL
95		*(.discard)
96		*(.discard.*)
97		*(.interp .dynamic)
98		*(.dynsym .dynstr .hash .gnu.hash)
99		*(.eh_frame)
100	}
101
102	. = KIMAGE_VADDR + TEXT_OFFSET;
103
104	.head.text : {
105		_text = .;
106		HEAD_TEXT
107	}
108	.text : {			/* Real text segment		*/
109		_stext = .;		/* Text and read-only data	*/
110			IRQENTRY_TEXT
111			SOFTIRQENTRY_TEXT
112			ENTRY_TEXT
113			TEXT_TEXT
114			SCHED_TEXT
115			CPUIDLE_TEXT
116			LOCK_TEXT
117			KPROBES_TEXT
118			HYPERVISOR_TEXT
119			IDMAP_TEXT
120			HIBERNATE_TEXT
121			TRAMP_TEXT
122			*(.fixup)
123			*(.gnu.warning)
124		. = ALIGN(16);
125		*(.got)			/* Global offset table		*/
126	}
127
128	. = ALIGN(SEGMENT_ALIGN);
129	_etext = .;			/* End of text section */
130
131	/* everything from this point to __init_begin will be marked RO NX */
132	RO_DATA(PAGE_SIZE)
133
134	idmap_pg_dir = .;
135	. += IDMAP_DIR_SIZE;
136	idmap_pg_end = .;
137
138#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
139	tramp_pg_dir = .;
140	. += PAGE_SIZE;
141#endif
142
143#ifdef CONFIG_ARM64_SW_TTBR0_PAN
144	reserved_ttbr0 = .;
145	. += RESERVED_TTBR0_SIZE;
146#endif
147	swapper_pg_dir = .;
148	. += PAGE_SIZE;
149	swapper_pg_end = .;
150
151	. = ALIGN(SEGMENT_ALIGN);
152	__init_begin = .;
153	__inittext_begin = .;
154
155	INIT_TEXT_SECTION(8)
156
157	__exittext_begin = .;
158	.exit.text : {
159		EXIT_TEXT
160	}
161	__exittext_end = .;
162
163	. = ALIGN(4);
164	.altinstructions : {
165		__alt_instructions = .;
166		*(.altinstructions)
167		__alt_instructions_end = .;
168	}
169	.altinstr_replacement : {
170		*(.altinstr_replacement)
171	}
172
173	. = ALIGN(SEGMENT_ALIGN);
174	__inittext_end = .;
175	__initdata_begin = .;
176
177	.init.data : {
178		INIT_DATA
179		INIT_SETUP(16)
180		INIT_CALLS
181		CON_INITCALL
182		INIT_RAM_FS
183		*(.init.rodata.* .init.bss)	/* from the EFI stub */
184	}
185	.exit.data : {
186		EXIT_DATA
187	}
188
189	PERCPU_SECTION(L1_CACHE_BYTES)
190
191	.rela.dyn : ALIGN(8) {
192		*(.rela .rela*)
193	}
194
195	__rela_offset	= ABSOLUTE(ADDR(.rela.dyn) - KIMAGE_VADDR);
196	__rela_size	= SIZEOF(.rela.dyn);
197
198#ifdef CONFIG_RELR
199	.relr.dyn : ALIGN(8) {
200		*(.relr.dyn)
201	}
202
203	__relr_offset	= ABSOLUTE(ADDR(.relr.dyn) - KIMAGE_VADDR);
204	__relr_size	= SIZEOF(.relr.dyn);
205#endif
206
207	. = ALIGN(SEGMENT_ALIGN);
208	__initdata_end = .;
209	__init_end = .;
210
211	_data = .;
212	_sdata = .;
213	RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
214
215	/*
216	 * Data written with the MMU off but read with the MMU on requires
217	 * cache lines to be invalidated, discarding up to a Cache Writeback
218	 * Granule (CWG) of data from the cache. Keep the section that
219	 * requires this type of maintenance to be in its own Cache Writeback
220	 * Granule (CWG) area so the cache maintenance operations don't
221	 * interfere with adjacent data.
222	 */
223	.mmuoff.data.write : ALIGN(SZ_2K) {
224		__mmuoff_data_start = .;
225		*(.mmuoff.data.write)
226	}
227	. = ALIGN(SZ_2K);
228	.mmuoff.data.read : {
229		*(.mmuoff.data.read)
230		__mmuoff_data_end = .;
231	}
232
233	PECOFF_EDATA_PADDING
234	__pecoff_data_rawsize = ABSOLUTE(. - __initdata_begin);
235	_edata = .;
236
237	BSS_SECTION(0, 0, 0)
238
239	. = ALIGN(PAGE_SIZE);
240	init_pg_dir = .;
241	. += INIT_DIR_SIZE;
242	init_pg_end = .;
243
244	. = ALIGN(SEGMENT_ALIGN);
245	__pecoff_data_size = ABSOLUTE(. - __initdata_begin);
246	_end = .;
247
248	STABS_DEBUG
249
250	HEAD_SYMBOLS
251}
252
253#include "image-vars.h"
254
255/*
256 * The HYP init code and ID map text can't be longer than a page each,
257 * and should not cross a page boundary.
258 */
259ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & ~(SZ_4K - 1)) <= SZ_4K,
260	"HYP init code too big or misaligned")
261ASSERT(__idmap_text_end - (__idmap_text_start & ~(SZ_4K - 1)) <= SZ_4K,
262	"ID map text too big or misaligned")
263#ifdef CONFIG_HIBERNATION
264ASSERT(__hibernate_exit_text_end - (__hibernate_exit_text_start & ~(SZ_4K - 1))
265	<= SZ_4K, "Hibernate exit text too big or misaligned")
266#endif
267#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
268ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) == PAGE_SIZE,
269	"Entry trampoline text too big")
270#endif
271/*
272 * If padding is applied before .head.text, virt<->phys conversions will fail.
273 */
274ASSERT(_text == (KIMAGE_VADDR + TEXT_OFFSET), "HEAD is misaligned")
275