aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-02-25 18:56:38 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-02-25 19:10:47 -0500
commit98e12b5a6e05413420a7e3b3eca7fbfc2ff41b6d (patch)
tree0d8e2d7f6dab7baf96da5a32678bd85095778853
parentbaac35c4155a8aa826c70acee6553368ca5243a2 (diff)
ARM: Fix decompressor's kernel size estimation for ROM=y
Commit 2552fc2 changed the way the decompressor decides if it is safe to decompress the kernel directly to its final location. Unfortunately, it took the top of the compressed data as being the stack pointer, which it is for ROM=n cases. However, for ROM=y, the stack pointer is not relevant, and results in the wrong answer. Fix this by explicitly storing the end of the biggybacked data in the decompressor, and use that to calculate the compressed image size. CC: <stable@kernel.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/boot/compressed/head.S50
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.in3
2 files changed, 26 insertions, 27 deletions
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 4fddc509e78e..6b84a0471171 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -170,8 +170,8 @@ not_angel:
170 170
171 .text 171 .text
172 adr r0, LC0 172 adr r0, LC0
173 ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp} ) 173 ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
174 THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, ip} ) 174 THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip} )
175 THUMB( ldr sp, [r0, #28] ) 175 THUMB( ldr sp, [r0, #28] )
176 subs r0, r0, r1 @ calculate the delta offset 176 subs r0, r0, r1 @ calculate the delta offset
177 177
@@ -182,12 +182,13 @@ not_angel:
182 /* 182 /*
183 * We're running at a different address. We need to fix 183 * We're running at a different address. We need to fix
184 * up various pointers: 184 * up various pointers:
185 * r5 - zImage base address 185 * r5 - zImage base address (_start)
186 * r6 - GOT start 186 * r6 - size of decompressed image
187 * r11 - GOT start
187 * ip - GOT end 188 * ip - GOT end
188 */ 189 */
189 add r5, r5, r0 190 add r5, r5, r0
190 add r6, r6, r0 191 add r11, r11, r0
191 add ip, ip, r0 192 add ip, ip, r0
192 193
193#ifndef CONFIG_ZBOOT_ROM 194#ifndef CONFIG_ZBOOT_ROM
@@ -205,10 +206,10 @@ not_angel:
205 /* 206 /*
206 * Relocate all entries in the GOT table. 207 * Relocate all entries in the GOT table.
207 */ 208 */
2081: ldr r1, [r6, #0] @ relocate entries in the GOT 2091: ldr r1, [r11, #0] @ relocate entries in the GOT
209 add r1, r1, r0 @ table. This fixes up the 210 add r1, r1, r0 @ table. This fixes up the
210 str r1, [r6], #4 @ C references. 211 str r1, [r11], #4 @ C references.
211 cmp r6, ip 212 cmp r11, ip
212 blo 1b 213 blo 1b
213#else 214#else
214 215
@@ -216,12 +217,12 @@ not_angel:
216 * Relocate entries in the GOT table. We only relocate 217 * Relocate entries in the GOT table. We only relocate
217 * the entries that are outside the (relocated) BSS region. 218 * the entries that are outside the (relocated) BSS region.
218 */ 219 */
2191: ldr r1, [r6, #0] @ relocate entries in the GOT 2201: ldr r1, [r11, #0] @ relocate entries in the GOT
220 cmp r1, r2 @ entry < bss_start || 221 cmp r1, r2 @ entry < bss_start ||
221 cmphs r3, r1 @ _end < entry 222 cmphs r3, r1 @ _end < entry
222 addlo r1, r1, r0 @ table. This fixes up the 223 addlo r1, r1, r0 @ table. This fixes up the
223 str r1, [r6], #4 @ C references. 224 str r1, [r11], #4 @ C references.
224 cmp r6, ip 225 cmp r11, ip
225 blo 1b 226 blo 1b
226#endif 227#endif
227 228
@@ -247,6 +248,7 @@ not_relocated: mov r0, #0
247 * Check to see if we will overwrite ourselves. 248 * Check to see if we will overwrite ourselves.
248 * r4 = final kernel address 249 * r4 = final kernel address
249 * r5 = start of this image 250 * r5 = start of this image
251 * r6 = size of decompressed image
250 * r2 = end of malloc space (and therefore this image) 252 * r2 = end of malloc space (and therefore this image)
251 * We basically want: 253 * We basically want:
252 * r4 >= r2 -> OK 254 * r4 >= r2 -> OK
@@ -254,8 +256,7 @@ not_relocated: mov r0, #0
254 */ 256 */
255 cmp r4, r2 257 cmp r4, r2
256 bhs wont_overwrite 258 bhs wont_overwrite
257 sub r3, sp, r5 @ > compressed kernel size 259 add r0, r4, r6
258 add r0, r4, r3, lsl #2 @ allow for 4x expansion
259 cmp r0, r5 260 cmp r0, r5
260 bls wont_overwrite 261 bls wont_overwrite
261 262
@@ -271,7 +272,6 @@ not_relocated: mov r0, #0
271 * r1-r3 = unused 272 * r1-r3 = unused
272 * r4 = kernel execution address 273 * r4 = kernel execution address
273 * r5 = decompressed kernel start 274 * r5 = decompressed kernel start
274 * r6 = processor ID
275 * r7 = architecture ID 275 * r7 = architecture ID
276 * r8 = atags pointer 276 * r8 = atags pointer
277 * r9-r12,r14 = corrupted 277 * r9-r12,r14 = corrupted
@@ -312,7 +312,8 @@ LC0: .word LC0 @ r1
312 .word _end @ r3 312 .word _end @ r3
313 .word zreladdr @ r4 313 .word zreladdr @ r4
314 .word _start @ r5 314 .word _start @ r5
315 .word _got_start @ r6 315 .word _image_size @ r6
316 .word _got_start @ r11
316 .word _got_end @ ip 317 .word _got_end @ ip
317 .word user_stack+4096 @ sp 318 .word user_stack+4096 @ sp
318LC1: .word reloc_end - reloc_start 319LC1: .word reloc_end - reloc_start
@@ -336,7 +337,6 @@ params: ldr r0, =params_phys
336 * 337 *
337 * On entry, 338 * On entry,
338 * r4 = kernel execution address 339 * r4 = kernel execution address
339 * r6 = processor ID
340 * r7 = architecture number 340 * r7 = architecture number
341 * r8 = atags pointer 341 * r8 = atags pointer
342 * r9 = run-time address of "start" (???) 342 * r9 = run-time address of "start" (???)
@@ -542,7 +542,6 @@ __common_mmu_cache_on:
542 * r1-r3 = unused 542 * r1-r3 = unused
543 * r4 = kernel execution address 543 * r4 = kernel execution address
544 * r5 = decompressed kernel start 544 * r5 = decompressed kernel start
545 * r6 = processor ID
546 * r7 = architecture ID 545 * r7 = architecture ID
547 * r8 = atags pointer 546 * r8 = atags pointer
548 * r9-r12,r14 = corrupted 547 * r9-r12,r14 = corrupted
@@ -581,19 +580,19 @@ call_kernel: bl cache_clean_flush
581 * r1 = corrupted 580 * r1 = corrupted
582 * r2 = corrupted 581 * r2 = corrupted
583 * r3 = block offset 582 * r3 = block offset
584 * r6 = corrupted 583 * r9 = corrupted
585 * r12 = corrupted 584 * r12 = corrupted
586 */ 585 */
587 586
588call_cache_fn: adr r12, proc_types 587call_cache_fn: adr r12, proc_types
589#ifdef CONFIG_CPU_CP15 588#ifdef CONFIG_CPU_CP15
590 mrc p15, 0, r6, c0, c0 @ get processor ID 589 mrc p15, 0, r9, c0, c0 @ get processor ID
591#else 590#else
592 ldr r6, =CONFIG_PROCESSOR_ID 591 ldr r9, =CONFIG_PROCESSOR_ID
593#endif 592#endif
5941: ldr r1, [r12, #0] @ get value 5931: ldr r1, [r12, #0] @ get value
595 ldr r2, [r12, #4] @ get mask 594 ldr r2, [r12, #4] @ get mask
596 eor r1, r1, r6 @ (real ^ match) 595 eor r1, r1, r9 @ (real ^ match)
597 tst r1, r2 @ & mask 596 tst r1, r2 @ & mask
598 ARM( addeq pc, r12, r3 ) @ call cache function 597 ARM( addeq pc, r12, r3 ) @ call cache function
599 THUMB( addeq r12, r3 ) 598 THUMB( addeq r12, r3 )
@@ -778,8 +777,7 @@ proc_types:
778 * Turn off the Cache and MMU. ARMv3 does not support 777 * Turn off the Cache and MMU. ARMv3 does not support
779 * reading the control register, but ARMv4 does. 778 * reading the control register, but ARMv4 does.
780 * 779 *
781 * On entry, r6 = processor ID 780 * On exit, r0, r1, r2, r3, r9, r12 corrupted
782 * On exit, r0, r1, r2, r3, r12 corrupted
783 * This routine must preserve: r4, r6, r7 781 * This routine must preserve: r4, r6, r7
784 */ 782 */
785 .align 5 783 .align 5
@@ -852,10 +850,8 @@ __armv3_mmu_cache_off:
852/* 850/*
853 * Clean and flush the cache to maintain consistency. 851 * Clean and flush the cache to maintain consistency.
854 * 852 *
855 * On entry,
856 * r6 = processor ID
857 * On exit, 853 * On exit,
858 * r1, r2, r3, r11, r12 corrupted 854 * r1, r2, r3, r9, r11, r12 corrupted
859 * This routine must preserve: 855 * This routine must preserve:
860 * r0, r4, r5, r6, r7 856 * r0, r4, r5, r6, r7
861 */ 857 */
@@ -967,7 +963,7 @@ __armv4_mmu_cache_flush:
967 mov r2, #64*1024 @ default: 32K dcache size (*2) 963 mov r2, #64*1024 @ default: 32K dcache size (*2)
968 mov r11, #32 @ default: 32 byte line size 964 mov r11, #32 @ default: 32 byte line size
969 mrc p15, 0, r3, c0, c0, 1 @ read cache type 965 mrc p15, 0, r3, c0, c0, 1 @ read cache type
970 teq r3, r6 @ cache ID register present? 966 teq r3, r9 @ cache ID register present?
971 beq no_cache_id 967 beq no_cache_id
972 mov r1, r3, lsr #18 968 mov r1, r3, lsr #18
973 and r1, r1, #7 969 and r1, r1, #7
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in
index a5924b9b88bd..cbed030b55cf 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.in
+++ b/arch/arm/boot/compressed/vmlinux.lds.in
@@ -36,6 +36,9 @@ SECTIONS
36 36
37 _etext = .; 37 _etext = .;
38 38
39 /* Assume size of decompressed image is 4x the compressed image */
40 _image_size = (_etext - _text) * 4;
41
39 _got_start = .; 42 _got_start = .;
40 .got : { *(.got) } 43 .got : { *(.got) }
41 _got_end = .; 44 _got_end = .;