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