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