1/* SPDX-License-Identifier: GPL-2.0 */ 2/* ld script to make ARM Linux kernel 3 * taken from the i386 version by Russell King 4 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> 5 */ 6 7#ifdef CONFIG_XIP_KERNEL 8#include "vmlinux-xip.lds.S" 9#else 10 11#include <asm-generic/vmlinux.lds.h> 12#include <asm/cache.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 "vmlinux.lds.h" 19 20OUTPUT_ARCH(arm) 21ENTRY(stext) 22 23#ifndef __ARMEB__ 24jiffies = jiffies_64; 25#else 26jiffies = jiffies_64 + 4; 27#endif 28 29SECTIONS 30{ 31 /* 32 * XXX: The linker does not define how output sections are 33 * assigned to input sections when there are multiple statements 34 * matching the same input section name. There is no documented 35 * order of matching. 36 * 37 * unwind exit sections must be discarded before the rest of the 38 * unwind sections get included. 39 */ 40 /DISCARD/ : { 41 ARM_DISCARD 42#ifndef CONFIG_SMP_ON_UP 43 *(.alt.smp.init) 44#endif 45 } 46 47 . = PAGE_OFFSET + TEXT_OFFSET; 48 .head.text : { 49 _text = .; 50 HEAD_TEXT 51 } 52 53#ifdef CONFIG_STRICT_KERNEL_RWX 54 . = ALIGN(1<<SECTION_SHIFT); 55#endif 56 57 .text : { /* Real text segment */ 58 _stext = .; /* Text and read-only data */ 59 ARM_TEXT 60 } 61 62#ifdef CONFIG_DEBUG_ALIGN_RODATA 63 . = ALIGN(1<<SECTION_SHIFT); 64#endif 65 _etext = .; /* End of text section */ 66 67 RO_DATA(PAGE_SIZE) 68 69 . = ALIGN(4); 70 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { 71 __start___ex_table = .; 72 ARM_MMU_KEEP(*(__ex_table)) 73 __stop___ex_table = .; 74 } 75 76#ifdef CONFIG_ARM_UNWIND 77 ARM_UNWIND_SECTIONS 78#endif 79 80 NOTES 81 82#ifdef CONFIG_STRICT_KERNEL_RWX 83 . = ALIGN(1<<SECTION_SHIFT); 84#else 85 . = ALIGN(PAGE_SIZE); 86#endif 87 __init_begin = .; 88 89 ARM_VECTORS 90 INIT_TEXT_SECTION(8) 91 .exit.text : { 92 ARM_EXIT_KEEP(EXIT_TEXT) 93 } 94 .init.proc.info : { 95 ARM_CPU_DISCARD(PROC_INFO) 96 } 97 .init.arch.info : { 98 __arch_info_begin = .; 99 *(.arch.info.init) 100 __arch_info_end = .; 101 } 102 .init.tagtable : { 103 __tagtable_begin = .; 104 *(.taglist.init) 105 __tagtable_end = .; 106 } 107#ifdef CONFIG_SMP_ON_UP 108 .init.smpalt : { 109 __smpalt_begin = .; 110 *(.alt.smp.init) 111 __smpalt_end = .; 112 } 113#endif 114 .init.pv_table : { 115 __pv_table_begin = .; 116 *(.pv_table) 117 __pv_table_end = .; 118 } 119 120 INIT_DATA_SECTION(16) 121 122 .exit.data : { 123 ARM_EXIT_KEEP(EXIT_DATA) 124 } 125 126#ifdef CONFIG_SMP 127 PERCPU_SECTION(L1_CACHE_BYTES) 128#endif 129 130#ifdef CONFIG_HAVE_TCM 131 ARM_TCM 132#endif 133 134#ifdef CONFIG_STRICT_KERNEL_RWX 135 . = ALIGN(1<<SECTION_SHIFT); 136#else 137 . = ALIGN(THREAD_SIZE); 138#endif 139 __init_end = .; 140 141 _sdata = .; 142 RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) 143 _edata = .; 144 145 BSS_SECTION(0, 0, 0) 146 _end = .; 147 148 STABS_DEBUG 149} 150 151#ifdef CONFIG_STRICT_KERNEL_RWX 152/* 153 * Without CONFIG_DEBUG_ALIGN_RODATA, __start_rodata_section_aligned will 154 * be the first section-aligned location after __start_rodata. Otherwise, 155 * it will be equal to __start_rodata. 156 */ 157__start_rodata_section_aligned = ALIGN(__start_rodata, 1 << SECTION_SHIFT); 158#endif 159 160/* 161 * These must never be empty 162 * If you have to comment these two assert statements out, your 163 * binutils is too old (for other reasons as well) 164 */ 165ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support") 166ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined") 167 168/* 169 * The HYP init code can't be more than a page long, 170 * and should not cross a page boundary. 171 * The above comment applies as well. 172 */ 173ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE, 174 "HYP init code too big or misaligned") 175 176#endif /* CONFIG_XIP_KERNEL */ 177