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