| 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 | |
| 9 | |
| 10 | |
| 11 | . = ALIGN(SZ_8); \
|
| 12 | __start___kvm_ex_table = .; \
|
| 13 | *(__kvm_ex_table) \
|
| 14 | __stop___kvm_ex_table = .;
|
| 15 |
|
| 16 | |
| 17 | |
| 18 | . = ALIGN(PAGE_SIZE); \
|
| 19 | __hyp_event_ids_start = .; \
|
| 20 | *(HYP_SECTION_NAME(.event_ids)) \
|
| 21 | __hyp_event_ids_end = .;
|
| 22 | |
| 23 | |
| 24 | |
| 25 |
|
| 26 | |
| 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 | |
| 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 | |
| 47 | . = ALIGN(PAGE_SIZE); \
|
| 48 | HYP_SECTION_NAME(.data..percpu) : { \
|
| 49 | *(HYP_SECTION_NAME(.data..percpu)) \
|
| 50 | }
|
| 51 |
|
| 52 | |
| 53 | .hyp.reloc : ALIGN(4) { \
|
| 54 | __hyp_reloc_begin = .; \
|
| 55 | *(.hyp.reloc) \
|
| 56 | __hyp_reloc_end = .; \
|
| 57 | }
|
| 58 |
|
| 59 | |
| 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 | |
| 72 | |
| 73 | |
| 74 | |
| 75 | |
| 76 | |
| 77 | |
| 78 | |
| 79 | |
| 80 |
|
| 81 | |
| 82 | |
| 83 |
|
| 84 | |
| 85 | |
| 86 | |
| 87 | |
| 88 | |
| 89 | |
| 90 |
|
| 91 | |
| 92 |
|
| 93 | OUTPUT_ARCH(aarch64)
|
| 94 | ENTRY(_text)
|
| 95 |
|
| 96 | jiffies = jiffies_64;
|
| 97 |
|
| 98 | |
| 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 | |
| 110 | . = ALIGN(SZ_4K); \
|
| 111 | __idmap_text_start = .; \
|
| 112 | *(.idmap.text) \
|
| 113 | __idmap_text_end = .;
|
| 114 |
|
| 115 | |
| 116 | |
| 117 | ALIGN_FUNCTION(); \
|
| 118 | __hibernate_exit_text_start = .; \
|
| 119 | *(.hibernate_exit.text) \
|
| 120 | __hibernate_exit_text_end = .;
|
| 121 | |
| 122 | |
| 123 | |
| 124 |
|
| 125 | |
| 126 | |
| 127 | ALIGN_FUNCTION(); \
|
| 128 | __relocate_new_kernel_start = .; \
|
| 129 | *(.kexec_relocate.text) \
|
| 130 | __relocate_new_kernel_end = .;
|
| 131 | |
| 132 | |
| 133 | |
| 134 |
|
| 135 | |
| 136 | |
| 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 | |
| 144 | |
| 145 | |
| 146 |
|
| 147 | |
| 148 | |
| 149 | .eh_frame : { \
|
| 150 | __pi___eh_frame_start = .; \
|
| 151 | *(.eh_frame) \
|
| 152 | __pi___eh_frame_end = .; \
|
| 153 | }
|
| 154 | |
| 155 | |
| 156 | |
| 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 | */
|
| 165 | PECOFF_FILE_ALIGNMENT = 0x200;
|
| 166 |
|
| 167 | |
| 168 | |
| 169 | .pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); }
|
| 170 | |
| 171 | |
| 172 | |
| 173 |
|
| 174 | SECTIONS
|
| 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 | |
| 239 | tramp_pg_dir = .;
|
| 240 | . += PAGE_SIZE;
|
| 241 | |
| 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 | |
| 323 | .data.hyp_events : {
|
| 324 | __hyp_events_start = .;
|
| 325 | *(SORT(_hyp_events.*))
|
| 326 | __hyp_events_end = .;
|
| 327 | }
|
| 328 | |
| 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 | */
|
| 400 | ASSERT(__hyp_idmap_text_end - __hyp_idmap_text_start <= PAGE_SIZE,
|
| 401 | "HYP init code too big")
|
| 402 | ASSERT(__idmap_text_end - (__idmap_text_start & ~(SZ_4K - 1)) <= SZ_4K,
|
| 403 | "ID map text too big or misaligned")
|
| 404 | |
| 405 | ASSERT(__hibernate_exit_text_end - __hibernate_exit_text_start <= SZ_4K,
|
| 406 | "Hibernate exit text is bigger than 4 KiB")
|
| 407 | ASSERT(__hibernate_exit_text_start == swsusp_arch_suspend_exit,
|
| 408 | "Hibernate exit text does not start with swsusp_arch_suspend_exit")
|
| 409 | |
| 410 | |
| 411 | ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) <= 3*PAGE_SIZE,
|
| 412 | "Entry trampoline text too big")
|
| 413 | |
| 414 | |
| 415 | ASSERT(__hyp_bss_start == __bss_start, "HYP and Host BSS are misaligned")
|
| 416 | |
| 417 | /*
|
| 418 | * If padding is applied before .head.text, virt<->phys conversions will fail.
|
| 419 | */
|
| 420 | ASSERT(_text == KIMAGE_VADDR, "HEAD is misaligned")
|
| 421 |
|
| 422 | ASSERT(swapper_pg_dir - reserved_pg_dir == RESERVED_SWAPPER_OFFSET,
|
| 423 | "RESERVED_SWAPPER_OFFSET is wrong!")
|
| 424 |
|
| 425 | |
| 426 | ASSERT(swapper_pg_dir - tramp_pg_dir == TRAMP_SWAPPER_OFFSET,
|
| 427 | "TRAMP_SWAPPER_OFFSET is wrong!")
|
| 428 | |
| 429 |
|
| 430 | |
| 431 | /* kexec relocation code should fit into one KEXEC_CONTROL_PAGE_SIZE */
|
| 432 | ASSERT(__relocate_new_kernel_end - __relocate_new_kernel_start <= SZ_4K,
|
| 433 | "kexec relocation code is bigger than 4 KiB")
|
| 434 | ASSERT(KEXEC_CONTROL_PAGE_SIZE >= SZ_4K, "KEXEC_CONTROL_PAGE_SIZE is broken")
|
| 435 | ASSERT(__relocate_new_kernel_start == arm64_relocate_new_kernel,
|
| 436 | "kexec control page does not start with arm64_relocate_new_kernel")
|
| 437 | |