vmlinux.lds.S 6.15 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0 */
2 3 4 5 6 7
/*
 * ld script to make ARM Linux kernel
 * taken from the i386 version by Russell King
 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
 */

8 9
#define RO_EXCEPTION_TABLE_ALIGN	8

10
#include <asm-generic/vmlinux.lds.h>
11
#include <asm/cache.h>
12
#include <asm/kernel-pgtable.h>
13 14 15
#include <asm/thread_info.h>
#include <asm/memory.h>
#include <asm/page.h>
16
#include <asm/pgtable.h>
17

18 19
#include "image.h"

20 21 22
/* .exit.text needed in case of alternative patching */
#define ARM_EXIT_KEEP(x)	x
#define ARM_EXIT_DISCARD(x)
23 24

OUTPUT_ARCH(aarch64)
25
ENTRY(_text)
26 27 28

jiffies = jiffies_64;

29 30
#define HYPERVISOR_TEXT					\
	/*						\
31 32 33 34 35 36
	 * Align to 4 KB so that			\
	 * a) the HYP vector table is at its minimum	\
	 *    alignment of 2048 bytes			\
	 * b) the HYP init code will not cross a page	\
	 *    boundary if its size does not exceed	\
	 *    4 KB (see related ASSERT() below)		\
37
	 */						\
38
	. = ALIGN(SZ_4K);				\
39
	__hyp_idmap_text_start = .;			\
40
	*(.hyp.idmap.text)				\
41 42
	__hyp_idmap_text_end = .;			\
	__hyp_text_start = .;				\
43
	*(.hyp.text)					\
44
	__hyp_text_end = .;
45

46 47
#define IDMAP_TEXT					\
	. = ALIGN(SZ_4K);				\
48
	__idmap_text_start = .;				\
49
	*(.idmap.text)					\
50
	__idmap_text_end = .;
51

52 53 54
#ifdef CONFIG_HIBERNATION
#define HIBERNATE_TEXT					\
	. = ALIGN(SZ_4K);				\
55
	__hibernate_exit_text_start = .;		\
56
	*(.hibernate_exit.text)				\
57
	__hibernate_exit_text_end = .;
58 59 60 61
#else
#define HIBERNATE_TEXT
#endif

62 63 64
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
#define TRAMP_TEXT					\
	. = ALIGN(PAGE_SIZE);				\
65
	__entry_tramp_text_start = .;			\
66 67
	*(.entry.tramp.text)				\
	. = ALIGN(PAGE_SIZE);				\
68
	__entry_tramp_text_end = .;
69 70 71 72
#else
#define TRAMP_TEXT
#endif

73 74
/*
 * The size of the PE/COFF section that covers the kernel image, which
75 76
 * runs from _stext to _edata, must be a round multiple of the PE/COFF
 * FileAlignment, which we set to its minimum value of 0x200. '_stext'
77 78 79 80 81 82 83 84 85 86 87 88
 * itself is 4 KB aligned, so padding out _edata to a 0x200 aligned
 * boundary should be sufficient.
 */
PECOFF_FILE_ALIGNMENT = 0x200;

#ifdef CONFIG_EFI
#define PECOFF_EDATA_PADDING	\
	.pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); }
#else
#define PECOFF_EDATA_PADDING
#endif

89 90 91 92 93 94 95 96 97 98 99 100 101 102
SECTIONS
{
	/*
	 * XXX: The linker does not define how output sections are
	 * assigned to input sections when there are multiple statements
	 * matching the same input section name.  There is no documented
	 * order of matching.
	 */
	/DISCARD/ : {
		ARM_EXIT_DISCARD(EXIT_TEXT)
		ARM_EXIT_DISCARD(EXIT_DATA)
		EXIT_CALL
		*(.discard)
		*(.discard.*)
103
		*(.interp .dynamic)
104 105
		*(.dynsym .dynstr .hash .gnu.hash)
		*(.eh_frame)
106 107
	}

108
	. = KIMAGE_VADDR + TEXT_OFFSET;
109 110 111 112 113 114 115 116

	.head.text : {
		_text = .;
		HEAD_TEXT
	}
	.text : {			/* Real text segment		*/
		_stext = .;		/* Text and read-only data	*/
			IRQENTRY_TEXT
117
			SOFTIRQENTRY_TEXT
118
			ENTRY_TEXT
119 120
			TEXT_TEXT
			SCHED_TEXT
121
			CPUIDLE_TEXT
122
			LOCK_TEXT
123
			KPROBES_TEXT
124
			HYPERVISOR_TEXT
125
			IDMAP_TEXT
126
			HIBERNATE_TEXT
127
			TRAMP_TEXT
128 129 130 131 132 133
			*(.fixup)
			*(.gnu.warning)
		. = ALIGN(16);
		*(.got)			/* Global offset table		*/
	}

134
	. = ALIGN(SEGMENT_ALIGN);
135 136
	_etext = .;			/* End of text section */

137 138
	/* everything from this point to __init_begin will be marked RO NX */
	RO_DATA(PAGE_SIZE)
139

140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
	idmap_pg_dir = .;
	. += IDMAP_DIR_SIZE;

#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
	tramp_pg_dir = .;
	. += PAGE_SIZE;
#endif

#ifdef CONFIG_ARM64_SW_TTBR0_PAN
	reserved_ttbr0 = .;
	. += RESERVED_TTBR0_SIZE;
#endif
	swapper_pg_dir = .;
	. += PAGE_SIZE;
	swapper_pg_end = .;

156
	. = ALIGN(SEGMENT_ALIGN);
157
	__init_begin = .;
158
	__inittext_begin = .;
159 160

	INIT_TEXT_SECTION(8)
161 162

	__exittext_begin = .;
163 164 165
	.exit.text : {
		ARM_EXIT_KEEP(EXIT_TEXT)
	}
166
	__exittext_end = .;
167

168 169 170 171 172 173 174 175 176 177 178 179 180 181
	. = ALIGN(4);
	.altinstructions : {
		__alt_instructions = .;
		*(.altinstructions)
		__alt_instructions_end = .;
	}
	.altinstr_replacement : {
		*(.altinstr_replacement)
	}

	. = ALIGN(PAGE_SIZE);
	__inittext_end = .;
	__initdata_begin = .;

182 183 184 185 186 187
	.init.data : {
		INIT_DATA
		INIT_SETUP(16)
		INIT_CALLS
		CON_INITCALL
		INIT_RAM_FS
188
		*(.init.rodata.* .init.bss)	/* from the EFI stub */
189 190 191 192 193
	}
	.exit.data : {
		ARM_EXIT_KEEP(EXIT_DATA)
	}

194
	PERCPU_SECTION(L1_CACHE_BYTES)
195

196
	.rela.dyn : ALIGN(8) {
197 198
		*(.rela .rela*)
	}
199

200 201
	__rela_offset	= ABSOLUTE(ADDR(.rela.dyn) - KIMAGE_VADDR);
	__rela_size	= SIZEOF(.rela.dyn);
202

203 204 205 206 207 208 209 210 211
#ifdef CONFIG_RELR
	.relr.dyn : ALIGN(8) {
		*(.relr.dyn)
	}

	__relr_offset	= ABSOLUTE(ADDR(.relr.dyn) - KIMAGE_VADDR);
	__relr_size	= SIZEOF(.relr.dyn);
#endif

212
	. = ALIGN(SEGMENT_ALIGN);
213
	__initdata_end = .;
214 215
	__init_end = .;

216 217
	_data = .;
	_sdata = .;
218
	RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237

	/*
	 * Data written with the MMU off but read with the MMU on requires
	 * cache lines to be invalidated, discarding up to a Cache Writeback
	 * Granule (CWG) of data from the cache. Keep the section that
	 * requires this type of maintenance to be in its own Cache Writeback
	 * Granule (CWG) area so the cache maintenance operations don't
	 * interfere with adjacent data.
	 */
	.mmuoff.data.write : ALIGN(SZ_2K) {
		__mmuoff_data_start = .;
		*(.mmuoff.data.write)
	}
	. = ALIGN(SZ_2K);
	.mmuoff.data.read : {
		*(.mmuoff.data.read)
		__mmuoff_data_end = .;
	}

238
	PECOFF_EDATA_PADDING
239
	__pecoff_data_rawsize = ABSOLUTE(. - __initdata_begin);
240
	_edata = .;
241 242

	BSS_SECTION(0, 0, 0)
243 244

	. = ALIGN(PAGE_SIZE);
245 246 247 248
	init_pg_dir = .;
	. += INIT_DIR_SIZE;
	init_pg_end = .;

249
	__pecoff_data_size = ABSOLUTE(. - __initdata_begin);
250 251 252
	_end = .;

	STABS_DEBUG
253 254

	HEAD_SYMBOLS
255
}
256

257 258
#include "image-vars.h"

259
/*
260
 * The HYP init code and ID map text can't be longer than a page each,
261
 * and should not cross a page boundary.
262
 */
263 264
ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & ~(SZ_4K - 1)) <= SZ_4K,
	"HYP init code too big or misaligned")
265 266
ASSERT(__idmap_text_end - (__idmap_text_start & ~(SZ_4K - 1)) <= SZ_4K,
	"ID map text too big or misaligned")
267 268 269 270
#ifdef CONFIG_HIBERNATION
ASSERT(__hibernate_exit_text_end - (__hibernate_exit_text_start & ~(SZ_4K - 1))
	<= SZ_4K, "Hibernate exit text too big or misaligned")
#endif
271 272 273 274
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) == PAGE_SIZE,
	"Entry trampoline text too big")
#endif
275 276 277
/*
 * If padding is applied before .head.text, virt<->phys conversions will fail.
 */
278
ASSERT(_text == (KIMAGE_VADDR + TEXT_OFFSET), "HEAD is misaligned")