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