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