diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-05-08 19:20:34 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-05-08 20:18:10 -0400 |
commit | 5b11f1cee5797b38d16b94d8745b12b6727a8373 (patch) | |
tree | 01d9ce7df1629c1ec17815c33ad3ce8b5bed3094 /arch/x86/boot | |
parent | b40d68d5b5b799caaf99d2e073e62962e6d917ce (diff) |
x86, boot: straighten out ranges to copy/zero in compressed/head*.S
Both on 32 and 64 bits, we copy all the way up to the end of bss,
except that on 64 bits there is a hack to avoid copying on top of the
page tables. There is no point in copying bss at all, especially
since we are just about to zero it all anyway.
To clean up and unify the handling, we now do:
- copy from startup_32 to _bss.
- zero from _bss to _ebss.
- the _ebss symbol is aligned to an 8-byte boundary.
- the page tables are moved to a separate section.
Use _bss as the copy endpoint since _edata may be misaligned.
[ Impact: cleanup, trivial performance improvement ]
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/boot')
-rw-r--r-- | arch/x86/boot/compressed/head_32.S | 8 | ||||
-rw-r--r-- | arch/x86/boot/compressed/head_64.S | 18 | ||||
-rw-r--r-- | arch/x86/boot/compressed/vmlinux.lds.S | 19 |
3 files changed, 29 insertions, 16 deletions
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 7bd7766ffabf..59425e157df3 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S | |||
@@ -93,9 +93,9 @@ ENTRY(startup_32) | |||
93 | * where decompression in place becomes safe. | 93 | * where decompression in place becomes safe. |
94 | */ | 94 | */ |
95 | pushl %esi | 95 | pushl %esi |
96 | leal _ebss(%ebp), %esi | 96 | leal _bss(%ebp), %esi |
97 | leal _ebss(%ebx), %edi | 97 | leal _bss(%ebx), %edi |
98 | movl $(_ebss - startup_32), %ecx | 98 | movl $(_bss - startup_32), %ecx |
99 | std | 99 | std |
100 | rep movsb | 100 | rep movsb |
101 | cld | 101 | cld |
@@ -125,7 +125,7 @@ relocated: | |||
125 | * Clear BSS | 125 | * Clear BSS |
126 | */ | 126 | */ |
127 | xorl %eax, %eax | 127 | xorl %eax, %eax |
128 | leal _edata(%ebx), %edi | 128 | leal _bss(%ebx), %edi |
129 | leal _ebss(%ebx), %ecx | 129 | leal _ebss(%ebx), %ecx |
130 | subl %edi, %ecx | 130 | subl %edi, %ecx |
131 | cld | 131 | cld |
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 26c3def43ace..5bc9052615b6 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S | |||
@@ -253,9 +253,9 @@ ENTRY(startup_64) | |||
253 | * Copy the compressed kernel to the end of our buffer | 253 | * Copy the compressed kernel to the end of our buffer |
254 | * where decompression in place becomes safe. | 254 | * where decompression in place becomes safe. |
255 | */ | 255 | */ |
256 | leaq _end_before_pgt(%rip), %r8 | 256 | leaq _bss(%rip), %r8 |
257 | leaq _end_before_pgt(%rbx), %r9 | 257 | leaq _bss(%rbx), %r9 |
258 | movq $_end_before_pgt /* - $startup_32 */, %rcx | 258 | movq $_bss /* - $startup_32 */, %rcx |
259 | 1: subq $8, %r8 | 259 | 1: subq $8, %r8 |
260 | subq $8, %r9 | 260 | subq $8, %r9 |
261 | movq 0(%r8), %rax | 261 | movq 0(%r8), %rax |
@@ -276,8 +276,8 @@ relocated: | |||
276 | * Clear BSS | 276 | * Clear BSS |
277 | */ | 277 | */ |
278 | xorq %rax, %rax | 278 | xorq %rax, %rax |
279 | leaq _edata(%rbx), %rdi | 279 | leaq _bss(%rbx), %rdi |
280 | leaq _end_before_pgt(%rbx), %rcx | 280 | leaq _ebss(%rbx), %rcx |
281 | subq %rdi, %rcx | 281 | subq %rdi, %rcx |
282 | cld | 282 | cld |
283 | rep stosb | 283 | rep stosb |
@@ -329,3 +329,11 @@ boot_heap: | |||
329 | boot_stack: | 329 | boot_stack: |
330 | .fill BOOT_STACK_SIZE, 1, 0 | 330 | .fill BOOT_STACK_SIZE, 1, 0 |
331 | boot_stack_end: | 331 | boot_stack_end: |
332 | |||
333 | /* | ||
334 | * Space for page tables (not in .bss so not zeroed) | ||
335 | */ | ||
336 | .section ".pgtable","a",@nobits | ||
337 | .balign 4096 | ||
338 | pgtable: | ||
339 | .fill 6*4096, 1, 0 | ||
diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S index dbe515e13fef..cc353e1b3ffd 100644 --- a/arch/x86/boot/compressed/vmlinux.lds.S +++ b/arch/x86/boot/compressed/vmlinux.lds.S | |||
@@ -2,6 +2,8 @@ OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT) | |||
2 | 2 | ||
3 | #undef i386 | 3 | #undef i386 |
4 | 4 | ||
5 | #include <asm/page_types.h> | ||
6 | |||
5 | #ifdef CONFIG_X86_64 | 7 | #ifdef CONFIG_X86_64 |
6 | OUTPUT_ARCH(i386:x86-64) | 8 | OUTPUT_ARCH(i386:x86-64) |
7 | ENTRY(startup_64) | 9 | ENTRY(startup_64) |
@@ -48,13 +50,16 @@ SECTIONS | |||
48 | *(.bss) | 50 | *(.bss) |
49 | *(.bss.*) | 51 | *(.bss.*) |
50 | *(COMMON) | 52 | *(COMMON) |
51 | #ifdef CONFIG_X86_64 | 53 | . = ALIGN(8); /* For convenience during zeroing */ |
52 | . = ALIGN(8); | ||
53 | _end_before_pgt = . ; | ||
54 | . = ALIGN(4096); | ||
55 | pgtable = . ; | ||
56 | . = . + 4096 * 6; | ||
57 | #endif | ||
58 | _ebss = .; | 54 | _ebss = .; |
59 | } | 55 | } |
56 | #ifdef CONFIG_X86_64 | ||
57 | . = ALIGN(PAGE_SIZE); | ||
58 | .pgtable : { | ||
59 | _pgtable = . ; | ||
60 | *(.pgtable) | ||
61 | _epgtable = . ; | ||
62 | } | ||
63 | #endif | ||
64 | _end = .; | ||
60 | } | 65 | } |