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