diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2010-08-02 18:34:44 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2010-08-02 18:34:44 -0400 |
commit | 22a57f5896df218356bae6203dfaf04bcfd6c88c (patch) | |
tree | e956ddcf7edf8457978d324a2e9c954b31be2206 /arch/x86/boot | |
parent | 70b0d22d581a5deef7b2876b0c3774635b8d846c (diff) |
x86, setup: Allow global variables and functions in the decompressor
In order for global variables and functions to work in the
decompressor, we need to fix up the GOT in assembly code.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
LKML-Reference: <4C57382E.8050501@zytor.com>
Diffstat (limited to 'arch/x86/boot')
-rw-r--r-- | arch/x86/boot/compressed/head_32.S | 13 | ||||
-rw-r--r-- | arch/x86/boot/compressed/head_64.S | 13 | ||||
-rw-r--r-- | arch/x86/boot/compressed/vmlinux.lds.S | 6 |
3 files changed, 32 insertions, 0 deletions
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index f543b70ffae2..67a655a39ce4 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S | |||
@@ -124,6 +124,19 @@ relocated: | |||
124 | rep stosl | 124 | rep stosl |
125 | 125 | ||
126 | /* | 126 | /* |
127 | * Adjust our own GOT | ||
128 | */ | ||
129 | leal _got(%ebx), %edx | ||
130 | leal _egot(%ebx), %ecx | ||
131 | 1: | ||
132 | cmpl %ecx, %edx | ||
133 | jae 2f | ||
134 | addl %ebx, (%edx) | ||
135 | addl $4, %edx | ||
136 | jmp 1b | ||
137 | 2: | ||
138 | |||
139 | /* | ||
127 | * Do the decompression, and jump to the new kernel.. | 140 | * Do the decompression, and jump to the new kernel.. |
128 | */ | 141 | */ |
129 | leal z_extract_offset_negative(%ebx), %ebp | 142 | leal z_extract_offset_negative(%ebx), %ebp |
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index faff0dc9c06a..52f85a196fa0 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S | |||
@@ -280,6 +280,19 @@ relocated: | |||
280 | rep stosq | 280 | rep stosq |
281 | 281 | ||
282 | /* | 282 | /* |
283 | * Adjust our own GOT | ||
284 | */ | ||
285 | leaq _got(%rip), %rdx | ||
286 | leaq _egot(%rip), %rcx | ||
287 | 1: | ||
288 | cmpq %rcx, %rdx | ||
289 | jae 2f | ||
290 | addq %rbx, (%rdx) | ||
291 | addq $8, %rdx | ||
292 | jmp 1b | ||
293 | 2: | ||
294 | |||
295 | /* | ||
283 | * Do the decompression, and jump to the new kernel.. | 296 | * Do the decompression, and jump to the new kernel.. |
284 | */ | 297 | */ |
285 | pushq %rsi /* Save the real mode argument */ | 298 | pushq %rsi /* Save the real mode argument */ |
diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S index 5ddabceee124..34d047c98284 100644 --- a/arch/x86/boot/compressed/vmlinux.lds.S +++ b/arch/x86/boot/compressed/vmlinux.lds.S | |||
@@ -41,6 +41,12 @@ SECTIONS | |||
41 | *(.rodata.*) | 41 | *(.rodata.*) |
42 | _erodata = . ; | 42 | _erodata = . ; |
43 | } | 43 | } |
44 | .got : { | ||
45 | _got = .; | ||
46 | KEEP(*(.got.plt)) | ||
47 | KEEP(*(.got)) | ||
48 | _egot = .; | ||
49 | } | ||
44 | .data : { | 50 | .data : { |
45 | _data = . ; | 51 | _data = . ; |
46 | *(.data) | 52 | *(.data) |