aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/vmlinux_64.lds.S448
1 files changed, 243 insertions, 205 deletions
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
index c8742507b030..6d5a5b05eaa2 100644
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ b/arch/x86/kernel/vmlinux_64.lds.S
@@ -15,69 +15,79 @@ OUTPUT_ARCH(i386:x86-64)
15ENTRY(phys_startup_64) 15ENTRY(phys_startup_64)
16jiffies_64 = jiffies; 16jiffies_64 = jiffies;
17PHDRS { 17PHDRS {
18 text PT_LOAD FLAGS(5); /* R_E */ 18 text PT_LOAD FLAGS(5); /* R_E */
19 data PT_LOAD FLAGS(7); /* RWE */ 19 data PT_LOAD FLAGS(7); /* RWE */
20 user PT_LOAD FLAGS(7); /* RWE */ 20 user PT_LOAD FLAGS(7); /* RWE */
21 data.init PT_LOAD FLAGS(7); /* RWE */ 21 data.init PT_LOAD FLAGS(7); /* RWE */
22#ifdef CONFIG_SMP 22#ifdef CONFIG_SMP
23 percpu PT_LOAD FLAGS(7); /* RWE */ 23 percpu PT_LOAD FLAGS(7); /* RWE */
24#endif 24#endif
25 data.init2 PT_LOAD FLAGS(7); /* RWE */ 25 data.init2 PT_LOAD FLAGS(7); /* RWE */
26 note PT_NOTE FLAGS(0); /* ___ */ 26 note PT_NOTE FLAGS(0); /* ___ */
27} 27}
28SECTIONS 28SECTIONS
29{ 29{
30 . = __START_KERNEL; 30 . = __START_KERNEL;
31 phys_startup_64 = startup_64 - LOAD_OFFSET; 31 phys_startup_64 = startup_64 - LOAD_OFFSET;
32 .text : AT(ADDR(.text) - LOAD_OFFSET) { 32
33 _text = .; /* Text and read-only data */ 33 /* Text and read-only data */
34 /* First the code that has to be first for bootstrapping */ 34 .text : AT(ADDR(.text) - LOAD_OFFSET) {
35 *(.text.head) 35 _text = .;
36 _stext = .; 36 /* First the code that has to be first for bootstrapping */
37 /* Then the rest */ 37 *(.text.head)
38 TEXT_TEXT 38 _stext = .;
39 SCHED_TEXT 39 /* Then the rest */
40 LOCK_TEXT 40 TEXT_TEXT
41 KPROBES_TEXT 41 SCHED_TEXT
42 IRQENTRY_TEXT 42 LOCK_TEXT
43 *(.fixup) 43 KPROBES_TEXT
44 *(.gnu.warning) 44 IRQENTRY_TEXT
45 _etext = .; /* End of text section */ 45 *(.fixup)
46 } :text = 0x9090 46 *(.gnu.warning)
47 47 /* End of text section */
48 NOTES :text :note 48 _etext = .;
49 49 } :text = 0x9090
50 . = ALIGN(16); /* Exception table */ 50
51 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { 51 NOTES :text :note
52 __start___ex_table = .; 52
53 *(__ex_table) 53 /* Exception table */
54 __stop___ex_table = .; 54 . = ALIGN(16);
55 } :text = 0x9090 55 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
56 56 __start___ex_table = .;
57 RODATA 57 *(__ex_table)
58 58 __stop___ex_table = .;
59 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ 59 } :text = 0x9090
60 /* Data */
61 .data : AT(ADDR(.data) - LOAD_OFFSET) {
62 DATA_DATA
63 CONSTRUCTORS
64 _edata = .; /* End of data section */
65 } :data
66 60
61 RODATA
67 62
68 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { 63 /* Align data segment to page size boundary */
69 . = ALIGN(PAGE_SIZE); 64 . = ALIGN(PAGE_SIZE);
70 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); 65 /* Data */
71 *(.data.cacheline_aligned) 66 .data : AT(ADDR(.data) - LOAD_OFFSET) {
72 } 67 DATA_DATA
73 . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES); 68 CONSTRUCTORS
74 .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { 69 /* End of data section */
75 *(.data.read_mostly) 70 _edata = .;
76 } 71 } :data
72
73
74 .data.cacheline_aligned :
75 AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
76 . = ALIGN(PAGE_SIZE);
77 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
78 *(.data.cacheline_aligned)
79 }
80
81 . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES);
82 .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
83 *(.data.read_mostly)
84 }
77 85
78#define VSYSCALL_ADDR (-10*1024*1024) 86#define VSYSCALL_ADDR (-10*1024*1024)
79#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095)) 87#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + \
80#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095)) 88 SIZEOF(.data.read_mostly) + 4095) & ~(4095))
89#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + \
90 SIZEOF(.data.read_mostly) + 4095) & ~(4095))
81 91
82#define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR) 92#define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
83#define VLOAD(x) (ADDR(x) - VLOAD_OFFSET) 93#define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
@@ -85,37 +95,53 @@ SECTIONS
85#define VVIRT_OFFSET (VSYSCALL_ADDR - VSYSCALL_VIRT_ADDR) 95#define VVIRT_OFFSET (VSYSCALL_ADDR - VSYSCALL_VIRT_ADDR)
86#define VVIRT(x) (ADDR(x) - VVIRT_OFFSET) 96#define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
87 97
88 . = VSYSCALL_ADDR; 98 . = VSYSCALL_ADDR;
89 .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } :user 99 .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) {
90 __vsyscall_0 = VSYSCALL_VIRT_ADDR; 100 *(.vsyscall_0)
101 } :user
102
103 __vsyscall_0 = VSYSCALL_VIRT_ADDR;
104
105 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
106 .vsyscall_fn : AT(VLOAD(.vsyscall_fn)) {
107 *(.vsyscall_fn)
108 }
109
110 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
111 .vsyscall_gtod_data : AT(VLOAD(.vsyscall_gtod_data)) {
112 *(.vsyscall_gtod_data)
113 }
91 114
92 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); 115 vsyscall_gtod_data = VVIRT(.vsyscall_gtod_data);
93 .vsyscall_fn : AT(VLOAD(.vsyscall_fn)) { *(.vsyscall_fn) } 116 .vsyscall_clock : AT(VLOAD(.vsyscall_clock)) {
94 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); 117 *(.vsyscall_clock)
95 .vsyscall_gtod_data : AT(VLOAD(.vsyscall_gtod_data)) 118 }
96 { *(.vsyscall_gtod_data) } 119 vsyscall_clock = VVIRT(.vsyscall_clock);
97 vsyscall_gtod_data = VVIRT(.vsyscall_gtod_data);
98 .vsyscall_clock : AT(VLOAD(.vsyscall_clock))
99 { *(.vsyscall_clock) }
100 vsyscall_clock = VVIRT(.vsyscall_clock);
101 120
102 121
103 .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) 122 .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) {
104 { *(.vsyscall_1) } 123 *(.vsyscall_1)
105 .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) 124 }
106 { *(.vsyscall_2) } 125 .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) {
126 *(.vsyscall_2)
127 }
107 128
108 .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { *(.vgetcpu_mode) } 129 .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) {
109 vgetcpu_mode = VVIRT(.vgetcpu_mode); 130 *(.vgetcpu_mode)
131 }
132 vgetcpu_mode = VVIRT(.vgetcpu_mode);
110 133
111 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); 134 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
112 .jiffies : AT(VLOAD(.jiffies)) { *(.jiffies) } 135 .jiffies : AT(VLOAD(.jiffies)) {
113 jiffies = VVIRT(.jiffies); 136 *(.jiffies)
137 }
138 jiffies = VVIRT(.jiffies);
114 139
115 .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) 140 .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) {
116 { *(.vsyscall_3) } 141 *(.vsyscall_3)
142 }
117 143
118 . = VSYSCALL_VIRT_ADDR + PAGE_SIZE; 144 . = VSYSCALL_VIRT_ADDR + PAGE_SIZE;
119 145
120#undef VSYSCALL_ADDR 146#undef VSYSCALL_ADDR
121#undef VSYSCALL_PHYS_ADDR 147#undef VSYSCALL_PHYS_ADDR
@@ -125,156 +151,168 @@ SECTIONS
125#undef VVIRT_OFFSET 151#undef VVIRT_OFFSET
126#undef VVIRT 152#undef VVIRT
127 153
128 .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { 154 /* init_task */
129 . = ALIGN(THREAD_SIZE); /* init_task */ 155 .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
130 *(.data.init_task) 156 . = ALIGN(THREAD_SIZE);
131 }:data.init 157 *(.data.init_task)
158 } :data.init
132 159
133 .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { 160 .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
134 . = ALIGN(PAGE_SIZE); 161 . = ALIGN(PAGE_SIZE);
135 *(.data.page_aligned) 162 *(.data.page_aligned)
136 } 163 }
137 164
138 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { 165 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
139 /* might get freed after init */ 166 /* might get freed after init */
140 . = ALIGN(PAGE_SIZE); 167 . = ALIGN(PAGE_SIZE);
141 __smp_alt_begin = .; 168 __smp_alt_begin = .;
142 __smp_locks = .; 169 __smp_locks = .;
143 *(.smp_locks) 170 *(.smp_locks)
144 __smp_locks_end = .; 171 __smp_locks_end = .;
172 . = ALIGN(PAGE_SIZE);
173 __smp_alt_end = .;
174 }
175
176 /* Init code and data */
145 . = ALIGN(PAGE_SIZE); 177 . = ALIGN(PAGE_SIZE);
146 __smp_alt_end = .; 178 __init_begin = .; /* paired with __init_end */
147 } 179 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
148 180 _sinittext = .;
149 . = ALIGN(PAGE_SIZE); /* Init code and data */ 181 INIT_TEXT
150 __init_begin = .; /* paired with __init_end */ 182 _einittext = .;
151 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { 183 }
152 _sinittext = .; 184
153 INIT_TEXT 185 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
154 _einittext = .; 186 __initdata_begin = .;
155 } 187 INIT_DATA
156 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { 188 __initdata_end = .;
157 __initdata_begin = .; 189 }
158 INIT_DATA 190
159 __initdata_end = .; 191 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
160 } 192 . = ALIGN(16);
161 193 __setup_start = .;
162 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { 194 *(.init.setup)
163 . = ALIGN(16); 195 __setup_end = .;
164 __setup_start = .; 196 }
165 *(.init.setup) 197
166 __setup_end = .; 198 .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
167 } 199 __initcall_start = .;
168 .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { 200 INITCALLS
169 __initcall_start = .; 201 __initcall_end = .;
170 INITCALLS 202 }
171 __initcall_end = .; 203
172 } 204 .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
173 .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { 205 __con_initcall_start = .;
174 __con_initcall_start = .; 206 *(.con_initcall.init)
175 *(.con_initcall.init) 207 __con_initcall_end = .;
176 __con_initcall_end = .; 208 }
177 } 209
178 .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) { 210 .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
179 __x86_cpu_dev_start = .; 211 __x86_cpu_dev_start = .;
180 *(.x86_cpu_dev.init) 212 *(.x86_cpu_dev.init)
181 __x86_cpu_dev_end = .; 213 __x86_cpu_dev_end = .;
182 } 214 }
183 SECURITY_INIT 215
184 216 SECURITY_INIT
185 . = ALIGN(8); 217
186 .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
187 __parainstructions = .;
188 *(.parainstructions)
189 __parainstructions_end = .;
190 }
191
192 .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
193 . = ALIGN(8); 218 . = ALIGN(8);
194 __alt_instructions = .; 219 .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
195 *(.altinstructions) 220 __parainstructions = .;
196 __alt_instructions_end = .; 221 *(.parainstructions)
197 } 222 __parainstructions_end = .;
198 .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { 223 }
199 *(.altinstr_replacement) 224
200 } 225 .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
201 /* .exit.text is discard at runtime, not link time, to deal with references 226 . = ALIGN(8);
202 from .altinstructions and .eh_frame */ 227 __alt_instructions = .;
203 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { 228 *(.altinstructions)
204 EXIT_TEXT 229 __alt_instructions_end = .;
205 } 230 }
206 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { 231
207 EXIT_DATA 232 .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
208 } 233 *(.altinstr_replacement)
234 }
235
236 /*
237 * .exit.text is discard at runtime, not link time, to deal with
238 * references from .altinstructions and .eh_frame
239 */
240 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
241 EXIT_TEXT
242 }
243
244 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
245 EXIT_DATA
246 }
209 247
210#ifdef CONFIG_BLK_DEV_INITRD 248#ifdef CONFIG_BLK_DEV_INITRD
211 . = ALIGN(PAGE_SIZE); 249 . = ALIGN(PAGE_SIZE);
212 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { 250 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
213 __initramfs_start = .; 251 __initramfs_start = .;
214 *(.init.ramfs) 252 *(.init.ramfs)
215 __initramfs_end = .; 253 __initramfs_end = .;
216 } 254 }
217#endif 255#endif
218 256
219#ifdef CONFIG_SMP 257#ifdef CONFIG_SMP
220 /* 258 /*
221 * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the 259 * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
222 * output PHDR, so the next output section - __data_nosave - should 260 * output PHDR, so the next output section - __data_nosave - should
223 * start another section data.init2. Also, pda should be at the head of 261 * start another section data.init2. Also, pda should be at the head of
224 * percpu area. Preallocate it and define the percpu offset symbol 262 * percpu area. Preallocate it and define the percpu offset symbol
225 * so that it can be accessed as a percpu variable. 263 * so that it can be accessed as a percpu variable.
226 */ 264 */
227 . = ALIGN(PAGE_SIZE); 265 . = ALIGN(PAGE_SIZE);
228 PERCPU_VADDR(0, :percpu) 266 PERCPU_VADDR(0, :percpu)
229#else 267#else
230 PERCPU(PAGE_SIZE) 268 PERCPU(PAGE_SIZE)
231#endif 269#endif
232 270
233 . = ALIGN(PAGE_SIZE);
234 __init_end = .;
235
236 .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
237 . = ALIGN(PAGE_SIZE);
238 __nosave_begin = .;
239 *(.data.nosave)
240 . = ALIGN(PAGE_SIZE);
241 __nosave_end = .;
242 } :data.init2 /* use another section data.init2, see PERCPU_VADDR() above */
243
244 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
245 . = ALIGN(PAGE_SIZE); 271 . = ALIGN(PAGE_SIZE);
246 __bss_start = .; /* BSS */ 272 __init_end = .;
247 *(.bss.page_aligned) 273
248 *(.bss) 274 .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
249 __bss_stop = .; 275 . = ALIGN(PAGE_SIZE);
250 } 276 __nosave_begin = .;
277 *(.data.nosave)
278 . = ALIGN(PAGE_SIZE);
279 __nosave_end = .;
280 } :data.init2
281 /* use another section data.init2, see PERCPU_VADDR() above */
282
283 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
284 . = ALIGN(PAGE_SIZE);
285 __bss_start = .; /* BSS */
286 *(.bss.page_aligned)
287 *(.bss)
288 __bss_stop = .;
289 }
251 290
252 .brk : AT(ADDR(.brk) - LOAD_OFFSET) { 291 .brk : AT(ADDR(.brk) - LOAD_OFFSET) {
253 . = ALIGN(PAGE_SIZE); 292 . = ALIGN(PAGE_SIZE);
254 __brk_base = . ; 293 __brk_base = .;
255 . += 64 * 1024 ; /* 64k alignment slop space */ 294 . += 64 * 1024; /* 64k alignment slop space */
256 *(.brk_reservation) /* areas brk users have reserved */ 295 *(.brk_reservation) /* areas brk users have reserved */
257 __brk_limit = . ; 296 __brk_limit = .;
258 }
259
260 _end = . ;
261
262 /* Sections to be discarded */
263 /DISCARD/ : {
264 *(.exitcall.exit)
265 *(.eh_frame)
266 *(.discard)
267 } 297 }
268 298
269 STABS_DEBUG 299 _end = . ;
270 300
271 DWARF_DEBUG 301 /* Sections to be discarded */
302 /DISCARD/ : {
303 *(.exitcall.exit)
304 *(.eh_frame)
305 *(.discard)
306 }
307
308 STABS_DEBUG
309 DWARF_DEBUG
272} 310}
273 311
274 /* 312/*
275 * Per-cpu symbols which need to be offset from __per_cpu_load 313 * Per-cpu symbols which need to be offset from __per_cpu_load
276 * for the boot processor. 314 * for the boot processor.
277 */ 315 */
278#define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load 316#define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load
279INIT_PER_CPU(gdt_page); 317INIT_PER_CPU(gdt_page);
280INIT_PER_CPU(irq_stack_union); 318INIT_PER_CPU(irq_stack_union);