1/* Excerpts written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */ 2/* Modified for i386/x86-64 Xen by Keir Fraser */ 3/* Modified for ARM Xen by Ian Campbell */ 4 5#include <xen/cache.h> 6#include <xen/lib.h> 7#include <xen/xen.lds.h> 8#include <asm/page.h> 9 10ENTRY(start) 11 12#if defined(__arm__) 13#define FORMAT arm 14#elif defined(__aarch64__) 15#define FORMAT aarch64 16#endif 17 18OUTPUT_ARCH(FORMAT) 19 20PHDRS 21{ 22 text PT_LOAD ; 23#if defined(BUILD_ID) 24 note PT_NOTE ; 25#endif 26} 27SECTIONS 28{ 29 . = XEN_VIRT_START; 30 _start = .; 31 .text : { 32 _stext = .; /* Text section */ 33 _idmap_start = .; 34 *(.text.header) 35 *(.text.idmap) 36 *(.rodata.idmap) 37 *(.data.idmap) 38 _idmap_end = .; 39 40 *(.text.cold) 41 *(.text.unlikely .text.*_unlikely .text.unlikely.*) 42 43 *(.text) 44#ifdef CONFIG_CC_SPLIT_SECTIONS 45 *(.text.*) 46#endif 47 48 *(.gnu.warning) 49 _etext = .; /* End of text section */ 50 } :text = 0x9090 51 52 . = ALIGN(PAGE_SIZE); 53 .rodata : { 54 _srodata = .; /* Read-only data */ 55 56 BUGFRAMES 57 58 *(.rodata) 59 *(.rodata.*) 60 VPCI_ARRAY 61 *(.data.rel.ro) 62 *(.data.rel.ro.*) 63 64 . = ALIGN(4); 65 __proc_info_start = .; 66 *(.proc.info) 67 __proc_info_end = .; 68 } :text 69 70#if defined(BUILD_ID) 71 . = ALIGN(4); 72 .note.gnu.build-id : { 73 __note_gnu_build_id_start = .; 74 *(.note.gnu.build-id) 75 __note_gnu_build_id_end = .; 76 } :note :text 77#endif 78 _erodata = .; /* End of read-only data */ 79 80 . = ALIGN(PAGE_SIZE); 81 .data.ro_after_init : { 82 __ro_after_init_start = .; 83 *(.data.ro_after_init) 84 . = ALIGN(PAGE_SIZE); 85 __ro_after_init_end = .; 86 } : text 87 88 .data.read_mostly : { 89 *(.data.read_mostly) 90 } :text 91 92 . = ALIGN(SMP_CACHE_BYTES); 93 .data : { /* Data */ 94 *(.data.page_aligned) 95 . = ALIGN(8); 96 __start_schedulers_array = .; 97 *(.data.schedulers) 98 __end_schedulers_array = .; 99 100 HYPFS_PARAM 101 102 *(.data .data.*) 103 CONSTRUCTORS 104 } :text 105 106 . = ALIGN(8); 107 .arch.info : { 108 _splatform = .; 109 *(.arch.info) 110 _eplatform = .; 111 } :text 112 113 DT_DEV_INFO 114 115#ifdef CONFIG_ACPI 116 ACPI_DEV_INFO 117#endif 118 119 . = ALIGN(8); 120 .teemediator.info : { 121 _steemediator = .; 122 *(.teemediator.info) 123 _eteemediator = .; 124 } :text 125 126 . = ALIGN(PAGE_SIZE); /* Init code and data */ 127 __init_begin = .; 128 .init.text : { 129 _sinittext = .; 130 *(.init.text) 131 _einittext = .; 132 . = ALIGN(PAGE_SIZE); /* Avoid mapping alt insns executable */ 133 *(.altinstr_replacement) 134 } :text 135 . = ALIGN(PAGE_SIZE); 136 __init_data_begin = .; 137 .init.data : { 138 *(.init.rodata) 139 *(.init.rodata.*) 140 141 . = ALIGN(POINTER_ALIGN); 142 __setup_start = .; 143 *(.init.setup) 144 __setup_end = .; 145 146 __initcall_start = .; 147 *(.initcallpresmp.init) 148 __presmp_initcall_end = .; 149 *(.initcall1.init) 150 __initcall_end = .; 151 152 . = ALIGN(4); 153 __alt_instructions = .; 154 *(.altinstructions) 155 __alt_instructions_end = .; 156 157 LOCK_PROFILE_DATA 158 159 *(.init.data) 160 *(.init.data.rel) 161 *(.init.data.rel.*) 162 163 . = ALIGN(8); 164 __ctors_start = .; 165 *(.ctors) 166 *(.init_array) 167 *(SORT(.init_array.*)) 168 __ctors_end = .; 169 } :text 170 __init_end_efi = .; 171 . = ALIGN(STACK_SIZE); 172 __init_end = .; 173 174 .bss : { /* BSS */ 175 __bss_start = .; 176 *(.bss.stack_aligned) 177 *(.bss.page_aligned) 178 PERCPU_BSS 179 *(.bss .bss.*) 180 . = ALIGN(POINTER_ALIGN); 181 __bss_end = .; 182 } :text 183 . = ALIGN(PAGE_SIZE); 184 _end = . ; 185 186 /* Section for the device tree blob (if any). */ 187 .dtb : { *(.dtb) } :text 188 189 DWARF2_DEBUG_SECTIONS 190 191 DISCARD_SECTIONS 192 193 STABS_DEBUG_SECTIONS 194 195 ELF_DETAILS_SECTIONS 196} 197 198PROVIDE(cpu_present_map = cpu_possible_map); 199 200/* 201 * The assembly code use _start and XEN_VIRT_START interchangeably to 202 * match the context. 203 */ 204ASSERT(_start == XEN_VIRT_START, "_start != XEN_VIRT_START") 205#ifdef CONFIG_MPU 206/* 207 * On MPU based platforms, the starting address is to be provided by user. 208 * One need to check that it is 4KB aligned. 209 */ 210ASSERT(IS_ALIGNED(_start, 4096), "starting address should be aligned to 4KB") 211#endif 212 213/* 214 * We require that Xen is loaded at a page boundary, so this ensures that any 215 * code running on the identity map cannot cross a section boundary. 216 */ 217ASSERT(IS_ALIGNED(_idmap_start, PAGE_SIZE), "_idmap_start should be page-aligned") 218ASSERT(_idmap_end - _idmap_start <= PAGE_SIZE, "Identity mapped code is larger than a page size") 219 220/* 221 * __init_[begin|end] MUST be at word size boundary otherwise we cannot 222 * write fault instructions in the space properly. 223 */ 224ASSERT(IS_ALIGNED(__init_begin, 4), "__init_begin is misaligned") 225ASSERT(IS_ALIGNED(__init_end, 4), "__init_end is misaligned") 226ASSERT(IS_ALIGNED(__bss_start, POINTER_ALIGN), "__bss_start is misaligned") 227ASSERT(IS_ALIGNED(__bss_end, POINTER_ALIGN), "__bss_end is misaligned") 228/* To simplify the logic in head.S, we want to _end to be page aligned */ 229ASSERT(IS_ALIGNED(_end, PAGE_SIZE), "_end is not page aligned") 230#ifdef CONFIG_MMU 231ASSERT((_end - _start) <= XEN_VIRT_SIZE, "Xen is too big") 232#endif 233