projects/linux·blob master · refs

437 lines · 10.3 KiB

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#include <asm/hyp_image.h>
9#ifdef CONFIG_KVM
10#define HYPERVISOR_EXTABLE \
11 . = ALIGN(SZ_8); \
12 __start___kvm_ex_table = .; \
13 *(__kvm_ex_table) \
14 __stop___kvm_ex_table = .;
15
16#ifdef CONFIG_NVHE_EL2_TRACING
17#define HYPERVISOR_EVENT_IDS \
18 . = ALIGN(PAGE_SIZE); \
19 __hyp_event_ids_start = .; \
20 *(HYP_SECTION_NAME(.event_ids)) \
21 __hyp_event_ids_end = .;
22#else
23#define HYPERVISOR_EVENT_IDS
24#endif
25
26#define HYPERVISOR_RODATA_SECTIONS \
27 HYP_SECTION_NAME(.rodata) : { \
28 . = ALIGN(PAGE_SIZE); \
29 __hyp_rodata_start = .; \
30 *(HYP_SECTION_NAME(.data..ro_after_init)) \
31 *(HYP_SECTION_NAME(.rodata)) \
32 HYPERVISOR_EVENT_IDS \
33 . = ALIGN(PAGE_SIZE); \
34 __hyp_rodata_end = .; \
35 }
36
37#define HYPERVISOR_DATA_SECTION \
38 HYP_SECTION_NAME(.data) : { \
39 . = ALIGN(PAGE_SIZE); \
40 __hyp_data_start = .; \
41 *(HYP_SECTION_NAME(.data)) \
42 . = ALIGN(PAGE_SIZE); \
43 __hyp_data_end = .; \
44 }
45
46#define HYPERVISOR_PERCPU_SECTION \
47 . = ALIGN(PAGE_SIZE); \
48 HYP_SECTION_NAME(.data..percpu) : { \
49 *(HYP_SECTION_NAME(.data..percpu)) \
50 }
51
52#define HYPERVISOR_RELOC_SECTION \
53 .hyp.reloc : ALIGN(4) { \
54 __hyp_reloc_begin = .; \
55 *(.hyp.reloc) \
56 __hyp_reloc_end = .; \
57 }
58
59#define BSS_FIRST_SECTIONS \
60 __hyp_bss_start = .; \
61 *(HYP_SECTION_NAME(.bss)) \
62 . = ALIGN(PAGE_SIZE); \
63 __hyp_bss_end = .;
64
65/*
66 * We require that __hyp_bss_start and __bss_start are aligned, and enforce it
67 * with an assertion. But the BSS_SECTION macro places an empty .sbss section
68 * between them, which can in some cases cause the linker to misalign them. To
69 * work around the issue, force a page alignment for __bss_start.
70 */
71#define SBSS_ALIGN PAGE_SIZE
72#else /* CONFIG_KVM */
73#define HYPERVISOR_EXTABLE
74#define HYPERVISOR_RODATA_SECTIONS
75#define HYPERVISOR_DATA_SECTION
76#define HYPERVISOR_PERCPU_SECTION
77#define HYPERVISOR_RELOC_SECTION
78#define SBSS_ALIGN 0
79#endif
80
81#define RO_EXCEPTION_TABLE_ALIGN 4
82#define RUNTIME_DISCARD_EXIT
83
84#include <asm-generic/vmlinux.lds.h>
85#include <asm/cache.h>
86#include <asm/kernel-pgtable.h>
87#include <asm/kexec.h>
88#include <asm/memory.h>
89#include <asm/page.h>
90
91#include "image.h"
92
93OUTPUT_ARCH(aarch64)
94ENTRY(_text)
95
96jiffies = jiffies_64;
97
98#define HYPERVISOR_TEXT \
99 . = ALIGN(PAGE_SIZE); \
100 __hyp_idmap_text_start = .; \
101 *(.hyp.idmap.text) \
102 __hyp_idmap_text_end = .; \
103 __hyp_text_start = .; \
104 *(.hyp.text) \
105 HYPERVISOR_EXTABLE \
106 . = ALIGN(PAGE_SIZE); \
107 __hyp_text_end = .;
108
109#define IDMAP_TEXT \
110 . = ALIGN(SZ_4K); \
111 __idmap_text_start = .; \
112 *(.idmap.text) \
113 __idmap_text_end = .;
114
115#ifdef CONFIG_HIBERNATION
116#define HIBERNATE_TEXT \
117 ALIGN_FUNCTION(); \
118 __hibernate_exit_text_start = .; \
119 *(.hibernate_exit.text) \
120 __hibernate_exit_text_end = .;
121#else
122#define HIBERNATE_TEXT
123#endif
124
125#ifdef CONFIG_KEXEC_CORE
126#define KEXEC_TEXT \
127 ALIGN_FUNCTION(); \
128 __relocate_new_kernel_start = .; \
129 *(.kexec_relocate.text) \
130 __relocate_new_kernel_end = .;
131#else
132#define KEXEC_TEXT
133#endif
134
135#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
136#define TRAMP_TEXT \
137 . = ALIGN(PAGE_SIZE); \
138 __entry_tramp_text_start = .; \
139 *(.entry.tramp.text) \
140 . = ALIGN(PAGE_SIZE); \
141 __entry_tramp_text_end = .; \
142 *(.entry.tramp.rodata)
143#else
144#define TRAMP_TEXT
145#endif
146
147#ifdef CONFIG_UNWIND_TABLES
148#define UNWIND_DATA_SECTIONS \
149 .eh_frame : { \
150 __pi___eh_frame_start = .; \
151 *(.eh_frame) \
152 __pi___eh_frame_end = .; \
153 }
154#else
155#define UNWIND_DATA_SECTIONS
156#endif
157
158/*
159 * The size of the PE/COFF section that covers the kernel image, which
160 * runs from _stext to _edata, must be a round multiple of the PE/COFF
161 * FileAlignment, which we set to its minimum value of 0x200. '_stext'
162 * itself is 4 KB aligned, so padding out _edata to a 0x200 aligned
163 * boundary should be sufficient.
164 */
165PECOFF_FILE_ALIGNMENT = 0x200;
166
167#ifdef CONFIG_EFI
168#define PECOFF_EDATA_PADDING \
169 .pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); }
170#else
171#define PECOFF_EDATA_PADDING
172#endif
173
174SECTIONS
175{
176 /*
177 * XXX: The linker does not define how output sections are
178 * assigned to input sections when there are multiple statements
179 * matching the same input section name. There is no documented
180 * order of matching.
181 */
182 DISCARDS
183 /DISCARD/ : {
184 *(.interp .dynamic)
185 *(.dynsym .dynstr .hash .gnu.hash)
186 *(.ARM.attributes)
187 }
188
189 . = KIMAGE_VADDR;
190
191 .head.text : {
192 _text = .;
193 HEAD_TEXT
194 }
195 .text : ALIGN(SEGMENT_ALIGN) { /* Real text segment */
196 _stext = .; /* Text and read-only data */
197 IRQENTRY_TEXT
198 SOFTIRQENTRY_TEXT
199 ENTRY_TEXT
200 TEXT_TEXT
201 SCHED_TEXT
202 LOCK_TEXT
203 KPROBES_TEXT
204 HYPERVISOR_TEXT
205 STATIC_CALL_TEXT
206 *(.gnu.warning)
207 }
208
209 . = ALIGN(SEGMENT_ALIGN);
210 _etext = .; /* End of text section */
211
212 /* everything from this point to __init_begin will be marked RO NX */
213 RO_DATA(PAGE_SIZE)
214
215 HYPERVISOR_RODATA_SECTIONS
216
217 .got : { *(.got) }
218 /*
219 * Make sure that the .got.plt is either completely empty or it
220 * contains only the lazy dispatch entries.
221 */
222 .got.plt : { *(.got.plt) }
223 ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0x18,
224 "Unexpected GOT/PLT entries detected!")
225
226 /* code sections that are never executed via the kernel mapping */
227 .rodata.text : {
228 TRAMP_TEXT
229 HIBERNATE_TEXT
230 KEXEC_TEXT
231 IDMAP_TEXT
232 . = ALIGN(PAGE_SIZE);
233 }
234
235 idmap_pg_dir = .;
236 . += PAGE_SIZE;
237
238#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
239 tramp_pg_dir = .;
240 . += PAGE_SIZE;
241#endif
242
243 reserved_pg_dir = .;
244 . += PAGE_SIZE;
245
246 swapper_pg_dir = .;
247 . += PAGE_SIZE;
248
249 . = ALIGN(SEGMENT_ALIGN);
250 __init_begin = .;
251 __inittext_begin = .;
252
253 INIT_TEXT_SECTION(8)
254
255 __exittext_begin = .;
256 .exit.text : {
257 EXIT_TEXT
258 }
259 __exittext_end = .;
260
261 . = ALIGN(4);
262 .altinstructions : {
263 __alt_instructions = .;
264 *(.altinstructions)
265 __alt_instructions_end = .;
266 }
267
268 UNWIND_DATA_SECTIONS
269
270 . = ALIGN(SEGMENT_ALIGN);
271 __inittext_end = .;
272 __initdata_begin = .;
273
274 __pi_init_idmap_pg_dir = .;
275 . += INIT_IDMAP_DIR_SIZE;
276 __pi_init_idmap_pg_end = .;
277
278 .init.data : {
279 INIT_DATA
280 INIT_SETUP(16)
281 INIT_CALLS
282 CON_INITCALL
283 INIT_RAM_FS
284 *(.init.altinstructions .init.bss) /* from the EFI stub */
285 }
286 .exit.data : {
287 EXIT_DATA
288 }
289
290 RUNTIME_CONST_VARIABLES
291
292 PERCPU_SECTION(L1_CACHE_BYTES)
293 HYPERVISOR_PERCPU_SECTION
294
295 HYPERVISOR_RELOC_SECTION
296
297 .rela.dyn : ALIGN(8) {
298 __pi_rela_start = .;
299 *(.rela .rela*)
300 __pi_rela_end = .;
301 }
302
303 .relr.dyn : ALIGN(8) {
304 __pi_relr_start = .;
305 *(.relr.dyn)
306 __pi_relr_end = .;
307 }
308
309 . = ALIGN(SEGMENT_ALIGN);
310 __initdata_end = .;
311 __init_end = .;
312
313 .data.rel.ro : { *(.data.rel.ro) }
314 ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!")
315
316 _data = .;
317 _sdata = .;
318 RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
319
320 HYPERVISOR_DATA_SECTION
321
322#ifdef CONFIG_NVHE_EL2_TRACING
323 .data.hyp_events : {
324 __hyp_events_start = .;
325 *(SORT(_hyp_events.*))
326 __hyp_events_end = .;
327 }
328#endif
329 /*
330 * Data written with the MMU off but read with the MMU on requires
331 * cache lines to be invalidated, discarding up to a Cache Writeback
332 * Granule (CWG) of data from the cache. Keep the section that
333 * requires this type of maintenance to be in its own Cache Writeback
334 * Granule (CWG) area so the cache maintenance operations don't
335 * interfere with adjacent data.
336 */
337 .mmuoff.data.write : ALIGN(SZ_2K) {
338 __mmuoff_data_start = .;
339 *(.mmuoff.data.write)
340 }
341 . = ALIGN(SZ_2K);
342 .mmuoff.data.read : {
343 *(.mmuoff.data.read)
344 __mmuoff_data_end = .;
345 }
346
347 PECOFF_EDATA_PADDING
348 __pecoff_data_rawsize = ABSOLUTE(. - __initdata_begin);
349 _edata = .;
350
351 /* start of zero-init region */
352 BSS_SECTION(SBSS_ALIGN, 0, PAGE_SIZE)
353 __pi___bss_start = __bss_start;
354
355 /* page table BSS starts here - preceding data/BSS is omitted from the linear map */
356 .pgtbl : ALIGN(PAGE_SIZE) {
357 *(.bss..pgtbl)
358 }
359 ASSERT(ADDR(.pgtbl) == __bss_stop, ".pgtbl must follow BSS")
360
361 . = ALIGN(PAGE_SIZE);
362 __pi_init_pg_dir = .;
363 . += INIT_DIR_SIZE;
364 __pi_init_pg_end = .;
365 /* end of zero-init region */
366
367 . += SZ_4K; /* stack for the early C runtime */
368 early_init_stack = .;
369
370 . = ALIGN(SEGMENT_ALIGN);
371 __pecoff_data_size = ABSOLUTE(. - __initdata_begin);
372 _end = .;
373 __pi__end = .;
374
375 STABS_DEBUG
376 DWARF_DEBUG
377 PROPELLER_DATA
378 MODINFO
379 ELF_DETAILS
380
381 HEAD_SYMBOLS
382
383 /*
384 * Sections that should stay zero sized, which is safer to
385 * explicitly check instead of blindly discarding.
386 */
387 .plt : {
388 *(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
389 }
390 ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
391}
392
393#include "image-vars.h"
394
395/*
396 * The HYP init code and ID map text can't be longer than a page each. The
397 * former is page-aligned, but the latter may not be with 16K or 64K pages, so
398 * it should also not cross a page boundary.
399 */
400ASSERT(__hyp_idmap_text_end - __hyp_idmap_text_start <= PAGE_SIZE,
401 "HYP init code too big")
402ASSERT(__idmap_text_end - (__idmap_text_start & ~(SZ_4K - 1)) <= SZ_4K,
403 "ID map text too big or misaligned")
404#ifdef CONFIG_HIBERNATION
405ASSERT(__hibernate_exit_text_end - __hibernate_exit_text_start <= SZ_4K,
406 "Hibernate exit text is bigger than 4 KiB")
407ASSERT(__hibernate_exit_text_start == swsusp_arch_suspend_exit,
408 "Hibernate exit text does not start with swsusp_arch_suspend_exit")
409#endif
410#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
411ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) <= 3*PAGE_SIZE,
412 "Entry trampoline text too big")
413#endif
414#ifdef CONFIG_KVM
415ASSERT(__hyp_bss_start == __bss_start, "HYP and Host BSS are misaligned")
416#endif
417/*
418 * If padding is applied before .head.text, virt<->phys conversions will fail.
419 */
420ASSERT(_text == KIMAGE_VADDR, "HEAD is misaligned")
421
422ASSERT(swapper_pg_dir - reserved_pg_dir == RESERVED_SWAPPER_OFFSET,
423 "RESERVED_SWAPPER_OFFSET is wrong!")
424
425#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
426ASSERT(swapper_pg_dir - tramp_pg_dir == TRAMP_SWAPPER_OFFSET,
427 "TRAMP_SWAPPER_OFFSET is wrong!")
428#endif
429
430#ifdef CONFIG_KEXEC_CORE
431/* kexec relocation code should fit into one KEXEC_CONTROL_PAGE_SIZE */
432ASSERT(__relocate_new_kernel_end - __relocate_new_kernel_start <= SZ_4K,
433 "kexec relocation code is bigger than 4 KiB")
434ASSERT(KEXEC_CONTROL_PAGE_SIZE >= SZ_4K, "KEXEC_CONTROL_PAGE_SIZE is broken")
435ASSERT(__relocate_new_kernel_start == arm64_relocate_new_kernel,
436 "kexec control page does not start with arm64_relocate_new_kernel")
437#endif