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