diff options
Diffstat (limited to 'arch/arm/boot')
-rw-r--r-- | arch/arm/boot/compressed/head.S | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 55a5bcb82ba0..53dd5da84f8a 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -187,15 +187,14 @@ not_angel: | |||
187 | bl cache_on | 187 | bl cache_on |
188 | 188 | ||
189 | restart: adr r0, LC0 | 189 | restart: adr r0, LC0 |
190 | ldmia r0, {r1, r2, r3, r5, r6, r9, r11, r12} | 190 | ldmia r0, {r1, r2, r3, r6, r9, r11, r12} |
191 | ldr sp, [r0, #32] | 191 | ldr sp, [r0, #28] |
192 | 192 | ||
193 | /* | 193 | /* |
194 | * We might be running at a different address. We need | 194 | * We might be running at a different address. We need |
195 | * to fix up various pointers. | 195 | * to fix up various pointers. |
196 | */ | 196 | */ |
197 | sub r0, r0, r1 @ calculate the delta offset | 197 | sub r0, r0, r1 @ calculate the delta offset |
198 | add r5, r5, r0 @ _start | ||
199 | add r6, r6, r0 @ _edata | 198 | add r6, r6, r0 @ _edata |
200 | 199 | ||
201 | #ifndef CONFIG_ZBOOT_ROM | 200 | #ifndef CONFIG_ZBOOT_ROM |
@@ -214,31 +213,39 @@ restart: adr r0, LC0 | |||
214 | /* | 213 | /* |
215 | * Check to see if we will overwrite ourselves. | 214 | * Check to see if we will overwrite ourselves. |
216 | * r4 = final kernel address | 215 | * r4 = final kernel address |
217 | * r5 = start of this image | ||
218 | * r9 = size of decompressed image | 216 | * r9 = size of decompressed image |
219 | * r10 = end of this image, including bss/stack/malloc space if non XIP | 217 | * r10 = end of this image, including bss/stack/malloc space if non XIP |
220 | * We basically want: | 218 | * We basically want: |
221 | * r4 >= r10 -> OK | 219 | * r4 >= r10 -> OK |
222 | * r4 + image length <= r5 -> OK | 220 | * r4 + image length <= current position (pc) -> OK |
223 | */ | 221 | */ |
224 | cmp r4, r10 | 222 | cmp r4, r10 |
225 | bhs wont_overwrite | 223 | bhs wont_overwrite |
226 | add r10, r4, r9 | 224 | add r10, r4, r9 |
227 | cmp r10, r5 | 225 | ARM( cmp r10, pc ) |
226 | THUMB( mov lr, pc ) | ||
227 | THUMB( cmp r10, lr ) | ||
228 | bls wont_overwrite | 228 | bls wont_overwrite |
229 | 229 | ||
230 | /* | 230 | /* |
231 | * Relocate ourselves past the end of the decompressed kernel. | 231 | * Relocate ourselves past the end of the decompressed kernel. |
232 | * r5 = start of this image | ||
233 | * r6 = _edata | 232 | * r6 = _edata |
234 | * r10 = end of the decompressed kernel | 233 | * r10 = end of the decompressed kernel |
235 | * Because we always copy ahead, we need to do it from the end and go | 234 | * Because we always copy ahead, we need to do it from the end and go |
236 | * backward in case the source and destination overlap. | 235 | * backward in case the source and destination overlap. |
237 | */ | 236 | */ |
238 | /* Round up to next 256-byte boundary. */ | 237 | /* |
239 | add r10, r10, #256 | 238 | * Bump to the next 256-byte boundary with the size of |
239 | * the relocation code added. This avoids overwriting | ||
240 | * ourself when the offset is small. | ||
241 | */ | ||
242 | add r10, r10, #((reloc_code_end - restart + 256) & ~255) | ||
240 | bic r10, r10, #255 | 243 | bic r10, r10, #255 |
241 | 244 | ||
245 | /* Get start of code we want to copy and align it down. */ | ||
246 | adr r5, restart | ||
247 | bic r5, r5, #31 | ||
248 | |||
242 | sub r9, r6, r5 @ size to copy | 249 | sub r9, r6, r5 @ size to copy |
243 | add r9, r9, #31 @ rounded up to a multiple | 250 | add r9, r9, #31 @ rounded up to a multiple |
244 | bic r9, r9, #31 @ ... of 32 bytes | 251 | bic r9, r9, #31 @ ... of 32 bytes |
@@ -346,7 +353,6 @@ not_relocated: mov r0, #0 | |||
346 | LC0: .word LC0 @ r1 | 353 | LC0: .word LC0 @ r1 |
347 | .word __bss_start @ r2 | 354 | .word __bss_start @ r2 |
348 | .word _end @ r3 | 355 | .word _end @ r3 |
349 | .word _start @ r5 | ||
350 | .word _edata @ r6 | 356 | .word _edata @ r6 |
351 | .word _image_size @ r9 | 357 | .word _image_size @ r9 |
352 | .word _got_start @ r11 | 358 | .word _got_start @ r11 |
@@ -1075,6 +1081,7 @@ memdump: mov r12, r0 | |||
1075 | #endif | 1081 | #endif |
1076 | 1082 | ||
1077 | .ltorg | 1083 | .ltorg |
1084 | reloc_code_end: | ||
1078 | 1085 | ||
1079 | .align | 1086 | .align |
1080 | .section ".stack", "aw", %nobits | 1087 | .section ".stack", "aw", %nobits |