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