Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: 8513/1: xip: Move XIP linking to a separate file

When building an XIP kernel, the linker script needs to be much different
than a conventional kernel's script. Over time, it's been difficult to
maintain both XIP and non-XIP layouts in one linker script. Therefore,
this patch separates the two procedures into two completely different
files.

The new linker script is essentially a straight copy of the current script
with all the non-CONFIG_XIP_KERNEL portions removed.

Additionally, all CONFIG_XIP_KERNEL portions have been removed from the
existing linker script...never to return again.

It should be noted that this does not fix any current XIP issues, but
rather is the first move in fixing them properly with subsequent patches.

Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Chris Brandt and committed by
Russell King
538bf469 8b6f2499

+332 -27
+322
arch/arm/kernel/vmlinux-xip.lds.S
··· 1 + /* ld script to make ARM Linux kernel 2 + * taken from the i386 version by Russell King 3 + * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> 4 + */ 5 + 6 + #include <asm-generic/vmlinux.lds.h> 7 + #include <asm/cache.h> 8 + #include <asm/thread_info.h> 9 + #include <asm/memory.h> 10 + #include <asm/page.h> 11 + #ifdef CONFIG_DEBUG_RODATA 12 + #include <asm/pgtable.h> 13 + #endif 14 + 15 + #define PROC_INFO \ 16 + . = ALIGN(4); \ 17 + VMLINUX_SYMBOL(__proc_info_begin) = .; \ 18 + *(.proc.info.init) \ 19 + VMLINUX_SYMBOL(__proc_info_end) = .; 20 + 21 + #define IDMAP_TEXT \ 22 + ALIGN_FUNCTION(); \ 23 + VMLINUX_SYMBOL(__idmap_text_start) = .; \ 24 + *(.idmap.text) \ 25 + VMLINUX_SYMBOL(__idmap_text_end) = .; \ 26 + . = ALIGN(PAGE_SIZE); \ 27 + VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \ 28 + *(.hyp.idmap.text) \ 29 + VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; 30 + 31 + #ifdef CONFIG_HOTPLUG_CPU 32 + #define ARM_CPU_DISCARD(x) 33 + #define ARM_CPU_KEEP(x) x 34 + #else 35 + #define ARM_CPU_DISCARD(x) x 36 + #define ARM_CPU_KEEP(x) 37 + #endif 38 + 39 + #if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \ 40 + defined(CONFIG_GENERIC_BUG) 41 + #define ARM_EXIT_KEEP(x) x 42 + #define ARM_EXIT_DISCARD(x) 43 + #else 44 + #define ARM_EXIT_KEEP(x) 45 + #define ARM_EXIT_DISCARD(x) x 46 + #endif 47 + 48 + OUTPUT_ARCH(arm) 49 + ENTRY(stext) 50 + 51 + #ifndef __ARMEB__ 52 + jiffies = jiffies_64; 53 + #else 54 + jiffies = jiffies_64 + 4; 55 + #endif 56 + 57 + SECTIONS 58 + { 59 + /* 60 + * XXX: The linker does not define how output sections are 61 + * assigned to input sections when there are multiple statements 62 + * matching the same input section name. There is no documented 63 + * order of matching. 64 + * 65 + * unwind exit sections must be discarded before the rest of the 66 + * unwind sections get included. 67 + */ 68 + /DISCARD/ : { 69 + *(.ARM.exidx.exit.text) 70 + *(.ARM.extab.exit.text) 71 + ARM_CPU_DISCARD(*(.ARM.exidx.cpuexit.text)) 72 + ARM_CPU_DISCARD(*(.ARM.extab.cpuexit.text)) 73 + ARM_EXIT_DISCARD(EXIT_TEXT) 74 + ARM_EXIT_DISCARD(EXIT_DATA) 75 + EXIT_CALL 76 + #ifndef CONFIG_MMU 77 + *(.text.fixup) 78 + *(__ex_table) 79 + #endif 80 + #ifndef CONFIG_SMP_ON_UP 81 + *(.alt.smp.init) 82 + #endif 83 + *(.discard) 84 + *(.discard.*) 85 + } 86 + 87 + . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); 88 + 89 + .head.text : { 90 + _text = .; 91 + HEAD_TEXT 92 + } 93 + 94 + #ifdef CONFIG_DEBUG_RODATA 95 + . = ALIGN(1<<SECTION_SHIFT); 96 + #endif 97 + 98 + .text : { /* Real text segment */ 99 + _stext = .; /* Text and read-only data */ 100 + IDMAP_TEXT 101 + __exception_text_start = .; 102 + *(.exception.text) 103 + __exception_text_end = .; 104 + IRQENTRY_TEXT 105 + TEXT_TEXT 106 + SCHED_TEXT 107 + LOCK_TEXT 108 + KPROBES_TEXT 109 + *(.gnu.warning) 110 + *(.glue_7) 111 + *(.glue_7t) 112 + . = ALIGN(4); 113 + *(.got) /* Global offset table */ 114 + ARM_CPU_KEEP(PROC_INFO) 115 + } 116 + 117 + #ifdef CONFIG_DEBUG_RODATA 118 + . = ALIGN(1<<SECTION_SHIFT); 119 + #endif 120 + RO_DATA(PAGE_SIZE) 121 + 122 + . = ALIGN(4); 123 + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { 124 + __start___ex_table = .; 125 + #ifdef CONFIG_MMU 126 + *(__ex_table) 127 + #endif 128 + __stop___ex_table = .; 129 + } 130 + 131 + #ifdef CONFIG_ARM_UNWIND 132 + /* 133 + * Stack unwinding tables 134 + */ 135 + . = ALIGN(8); 136 + .ARM.unwind_idx : { 137 + __start_unwind_idx = .; 138 + *(.ARM.exidx*) 139 + __stop_unwind_idx = .; 140 + } 141 + .ARM.unwind_tab : { 142 + __start_unwind_tab = .; 143 + *(.ARM.extab*) 144 + __stop_unwind_tab = .; 145 + } 146 + #endif 147 + 148 + NOTES 149 + 150 + _etext = .; /* End of text and rodata section */ 151 + 152 + /* 153 + * The vectors and stubs are relocatable code, and the 154 + * only thing that matters is their relative offsets 155 + */ 156 + __vectors_start = .; 157 + .vectors 0 : AT(__vectors_start) { 158 + *(.vectors) 159 + } 160 + . = __vectors_start + SIZEOF(.vectors); 161 + __vectors_end = .; 162 + 163 + __stubs_start = .; 164 + .stubs 0x1000 : AT(__stubs_start) { 165 + *(.stubs) 166 + } 167 + . = __stubs_start + SIZEOF(.stubs); 168 + __stubs_end = .; 169 + 170 + INIT_TEXT_SECTION(8) 171 + .exit.text : { 172 + ARM_EXIT_KEEP(EXIT_TEXT) 173 + } 174 + .init.proc.info : { 175 + ARM_CPU_DISCARD(PROC_INFO) 176 + } 177 + .init.arch.info : { 178 + __arch_info_begin = .; 179 + *(.arch.info.init) 180 + __arch_info_end = .; 181 + } 182 + .init.tagtable : { 183 + __tagtable_begin = .; 184 + *(.taglist.init) 185 + __tagtable_end = .; 186 + } 187 + #ifdef CONFIG_SMP_ON_UP 188 + .init.smpalt : { 189 + __smpalt_begin = .; 190 + *(.alt.smp.init) 191 + __smpalt_end = .; 192 + } 193 + #endif 194 + .init.pv_table : { 195 + __pv_table_begin = .; 196 + *(.pv_table) 197 + __pv_table_end = .; 198 + } 199 + .init.data : { 200 + INIT_SETUP(16) 201 + INIT_CALLS 202 + CON_INITCALL 203 + SECURITY_INITCALL 204 + INIT_RAM_FS 205 + } 206 + 207 + #ifdef CONFIG_SMP 208 + PERCPU_SECTION(L1_CACHE_BYTES) 209 + #endif 210 + 211 + __data_loc = ALIGN(4); /* location in binary */ 212 + . = PAGE_OFFSET + TEXT_OFFSET; 213 + 214 + .data : AT(__data_loc) { 215 + _data = .; /* address in memory */ 216 + _sdata = .; 217 + 218 + /* 219 + * first, the init task union, aligned 220 + * to an 8192 byte boundary. 221 + */ 222 + INIT_TASK_DATA(THREAD_SIZE) 223 + 224 + . = ALIGN(PAGE_SIZE); 225 + __init_begin = .; 226 + INIT_DATA 227 + ARM_EXIT_KEEP(EXIT_DATA) 228 + . = ALIGN(PAGE_SIZE); 229 + __init_end = .; 230 + 231 + NOSAVE_DATA 232 + CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) 233 + READ_MOSTLY_DATA(L1_CACHE_BYTES) 234 + 235 + /* 236 + * and the usual data section 237 + */ 238 + DATA_DATA 239 + CONSTRUCTORS 240 + 241 + _edata = .; 242 + } 243 + _edata_loc = __data_loc + SIZEOF(.data); 244 + 245 + #ifdef CONFIG_HAVE_TCM 246 + /* 247 + * We align everything to a page boundary so we can 248 + * free it after init has commenced and TCM contents have 249 + * been copied to its destination. 250 + */ 251 + .tcm_start : { 252 + . = ALIGN(PAGE_SIZE); 253 + __tcm_start = .; 254 + __itcm_start = .; 255 + } 256 + 257 + /* 258 + * Link these to the ITCM RAM 259 + * Put VMA to the TCM address and LMA to the common RAM 260 + * and we'll upload the contents from RAM to TCM and free 261 + * the used RAM after that. 262 + */ 263 + .text_itcm ITCM_OFFSET : AT(__itcm_start) 264 + { 265 + __sitcm_text = .; 266 + *(.tcm.text) 267 + *(.tcm.rodata) 268 + . = ALIGN(4); 269 + __eitcm_text = .; 270 + } 271 + 272 + /* 273 + * Reset the dot pointer, this is needed to create the 274 + * relative __dtcm_start below (to be used as extern in code). 275 + */ 276 + . = ADDR(.tcm_start) + SIZEOF(.tcm_start) + SIZEOF(.text_itcm); 277 + 278 + .dtcm_start : { 279 + __dtcm_start = .; 280 + } 281 + 282 + /* TODO: add remainder of ITCM as well, that can be used for data! */ 283 + .data_dtcm DTCM_OFFSET : AT(__dtcm_start) 284 + { 285 + . = ALIGN(4); 286 + __sdtcm_data = .; 287 + *(.tcm.data) 288 + . = ALIGN(4); 289 + __edtcm_data = .; 290 + } 291 + 292 + /* Reset the dot pointer or the linker gets confused */ 293 + . = ADDR(.dtcm_start) + SIZEOF(.data_dtcm); 294 + 295 + /* End marker for freeing TCM copy in linked object */ 296 + .tcm_end : AT(ADDR(.dtcm_start) + SIZEOF(.data_dtcm)){ 297 + . = ALIGN(PAGE_SIZE); 298 + __tcm_end = .; 299 + } 300 + #endif 301 + 302 + BSS_SECTION(0, 0, 0) 303 + _end = .; 304 + 305 + STABS_DEBUG 306 + } 307 + 308 + /* 309 + * These must never be empty 310 + * If you have to comment these two assert statements out, your 311 + * binutils is too old (for other reasons as well) 312 + */ 313 + ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support") 314 + ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined") 315 + 316 + /* 317 + * The HYP init code can't be more than a page long, 318 + * and should not cross a page boundary. 319 + * The above comment applies as well. 320 + */ 321 + ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE, 322 + "HYP init code too big or misaligned")
+10 -27
arch/arm/kernel/vmlinux.lds.S
··· 3 3 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> 4 4 */ 5 5 6 + #ifdef CONFIG_XIP_KERNEL 7 + #include "vmlinux-xip.lds.S" 8 + #else 9 + 6 10 #include <asm-generic/vmlinux.lds.h> 7 11 #include <asm/cache.h> 8 12 #include <asm/thread_info.h> ··· 88 84 *(.discard.*) 89 85 } 90 86 91 - #ifdef CONFIG_XIP_KERNEL 92 - . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); 93 - #else 94 87 . = PAGE_OFFSET + TEXT_OFFSET; 95 - #endif 96 88 .head.text : { 97 89 _text = .; 98 90 HEAD_TEXT ··· 152 152 153 153 _etext = .; /* End of text and rodata section */ 154 154 155 - #ifndef CONFIG_XIP_KERNEL 156 - # ifdef CONFIG_DEBUG_RODATA 155 + #ifdef CONFIG_DEBUG_RODATA 157 156 . = ALIGN(1<<SECTION_SHIFT); 158 - # else 157 + #else 159 158 . = ALIGN(PAGE_SIZE); 160 - # endif 161 - __init_begin = .; 162 159 #endif 160 + __init_begin = .; 161 + 163 162 /* 164 163 * The vectors and stubs are relocatable code, and the 165 164 * only thing that matters is their relative offsets ··· 207 208 __pv_table_end = .; 208 209 } 209 210 .init.data : { 210 - #ifndef CONFIG_XIP_KERNEL 211 211 INIT_DATA 212 - #endif 213 212 INIT_SETUP(16) 214 213 INIT_CALLS 215 214 CON_INITCALL 216 215 SECURITY_INITCALL 217 216 INIT_RAM_FS 218 217 } 219 - #ifndef CONFIG_XIP_KERNEL 220 218 .exit.data : { 221 219 ARM_EXIT_KEEP(EXIT_DATA) 222 220 } 223 - #endif 224 221 225 222 #ifdef CONFIG_SMP 226 223 PERCPU_SECTION(L1_CACHE_BYTES) 227 224 #endif 228 225 229 - #ifdef CONFIG_XIP_KERNEL 230 - __data_loc = ALIGN(4); /* location in binary */ 231 - . = PAGE_OFFSET + TEXT_OFFSET; 232 - #else 233 226 #ifdef CONFIG_DEBUG_RODATA 234 227 . = ALIGN(1<<SECTION_SHIFT); 235 228 #else ··· 229 238 #endif 230 239 __init_end = .; 231 240 __data_loc = .; 232 - #endif 233 241 234 242 .data : AT(__data_loc) { 235 243 _data = .; /* address in memory */ ··· 239 249 * to an 8192 byte boundary. 240 250 */ 241 251 INIT_TASK_DATA(THREAD_SIZE) 242 - 243 - #ifdef CONFIG_XIP_KERNEL 244 - . = ALIGN(PAGE_SIZE); 245 - __init_begin = .; 246 - INIT_DATA 247 - ARM_EXIT_KEEP(EXIT_DATA) 248 - . = ALIGN(PAGE_SIZE); 249 - __init_end = .; 250 - #endif 251 252 252 253 NOSAVE_DATA 253 254 CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) ··· 332 351 */ 333 352 ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE, 334 353 "HYP init code too big or misaligned") 354 + 355 + #endif /* CONFIG_XIP_KERNEL */