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