Commit 6d7d0ae5 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Russell King

ARM: 6750/1: improvements to compressed/head.S

In the case of a conflict between the memory used by the compressed
kernel with its decompressor code and the memory used for the
decompressed kernel, we currently store the later after the former and
relocate it afterwards.

This would be more efficient to do this the other way around i.e.
relocate the compressed data up front instead, resulting in a smaller
copy.  That also has the advantage of making the code smaller and more
straight forward.
Signed-off-by: default avatarNicolas Pitre <nicolas.pitre@linaro.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 425fc47a
...@@ -174,9 +174,7 @@ not_angel: ...@@ -174,9 +174,7 @@ not_angel:
*/ */
.text .text
adr r0, LC0
ldmia r0, {r1, r2, r3, r5, r6, r11, ip}
ldr sp, [r0, #28]
#ifdef CONFIG_AUTO_ZRELADDR #ifdef CONFIG_AUTO_ZRELADDR
@ determine final kernel image address @ determine final kernel image address
mov r4, pc mov r4, pc
...@@ -185,35 +183,108 @@ not_angel: ...@@ -185,35 +183,108 @@ not_angel:
#else #else
ldr r4, =zreladdr ldr r4, =zreladdr
#endif #endif
subs r0, r0, r1 @ calculate the delta offset
@ if delta is zero, we are bl cache_on
beq not_relocated @ running at the address we
@ were linked at. restart: adr r0, LC0
ldmia r0, {r1, r2, r3, r5, r6, r9, r11, r12}
ldr sp, [r0, #32]
/*
* We might be running at a different address. We need
* to fix up various pointers.
*/
sub r0, r0, r1 @ calculate the delta offset
add r5, r5, r0 @ _start
add r6, r6, r0 @ _edata
#ifndef CONFIG_ZBOOT_ROM
/* malloc space is above the relocated stack (64k max) */
add sp, sp, r0
add r10, sp, #0x10000
#else
/* /*
* We're running at a different address. We need to fix * With ZBOOT_ROM the bss/stack is non relocatable,
* up various pointers: * but someone could still run this code from RAM,
* r5 - zImage base address (_start) * in which case our reference is _edata.
* r6 - size of decompressed image */
* r11 - GOT start mov r10, r6
* ip - GOT end #endif
/*
* Check to see if we will overwrite ourselves.
* r4 = final kernel address
* r5 = start of this image
* r9 = size of decompressed image
* r10 = end of this image, including bss/stack/malloc space if non XIP
* We basically want:
* r4 >= r10 -> OK
* r4 + image length <= r5 -> OK
*/
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
cmp r10, r5
bls wont_overwrite
/*
* Relocate ourselves past the end of the decompressed kernel.
* r5 = start of this image
* r6 = _edata
* r10 = end of the decompressed kernel
* Because we always copy ahead, we need to do it from the end and go
* backward in case the source and destination overlap.
*/ */
add r5, r5, r0 /* Round up to next 256-byte boundary. */
add r10, r10, #256
bic r10, r10, #255
sub r9, r6, r5 @ size to copy
add r9, r9, #31 @ rounded up to a multiple
bic r9, r9, #31 @ ... of 32 bytes
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
/* Preserve offset to relocated code. */
sub r6, r9, r6
bl cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
/*
* If delta is zero, we are running at the address we were linked at.
* r0 = delta
* r2 = BSS start
* r3 = BSS end
* r4 = kernel execution address
* r7 = architecture ID
* r8 = atags pointer
* r11 = GOT start
* r12 = GOT end
* sp = stack pointer
*/
teq r0, #0
beq not_relocated
add r11, r11, r0 add r11, r11, r0
add ip, ip, r0 add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM #ifndef CONFIG_ZBOOT_ROM
/* /*
* If we're running fully PIC === CONFIG_ZBOOT_ROM = n, * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
* we need to fix up pointers into the BSS region. * we need to fix up pointers into the BSS region.
* r2 - BSS start * Note that the stack pointer has already been fixed up.
* r3 - BSS end
* sp - stack pointer
*/ */
add r2, r2, r0 add r2, r2, r0
add r3, r3, r0 add r3, r3, r0
add sp, sp, r0
/* /*
* Relocate all entries in the GOT table. * Relocate all entries in the GOT table.
...@@ -221,7 +292,7 @@ not_angel: ...@@ -221,7 +292,7 @@ not_angel:
1: ldr r1, [r11, #0] @ relocate entries in the GOT 1: ldr r1, [r11, #0] @ relocate entries in the GOT
add r1, r1, r0 @ table. This fixes up the add r1, r1, r0 @ table. This fixes up the
str r1, [r11], #4 @ C references. str r1, [r11], #4 @ C references.
cmp r11, ip cmp r11, r12
blo 1b blo 1b
#else #else
...@@ -234,7 +305,7 @@ not_angel: ...@@ -234,7 +305,7 @@ not_angel:
cmphs r3, r1 @ _end < entry cmphs r3, r1 @ _end < entry
addlo r1, r1, r0 @ table. This fixes up the addlo r1, r1, r0 @ table. This fixes up the
str r1, [r11], #4 @ C references. str r1, [r11], #4 @ C references.
cmp r11, ip cmp r11, r12
blo 1b blo 1b
#endif #endif
...@@ -246,76 +317,24 @@ not_relocated: mov r0, #0 ...@@ -246,76 +317,24 @@ not_relocated: mov r0, #0
cmp r2, r3 cmp r2, r3
blo 1b blo 1b
/*
* The C runtime environment should now be setup
* sufficiently. Turn the cache on, set up some
* pointers, and start decompressing.
*/
bl cache_on
mov r1, sp @ malloc space above stack
add r2, sp, #0x10000 @ 64k max
/* /*
* Check to see if we will overwrite ourselves. * The C runtime environment should now be setup sufficiently.
* r4 = final kernel address * Set up some pointers, and start decompressing.
* r5 = start of this image
* r6 = size of decompressed image
* r2 = end of malloc space (and therefore this image)
* We basically want:
* r4 >= r2 -> OK
* r4 + image length <= r5 -> OK
*/
cmp r4, r2
bhs wont_overwrite
add r0, r4, r6
cmp r0, r5
bls wont_overwrite
mov r5, r2 @ decompress after malloc space
mov r0, r5
mov r3, r7
bl decompress_kernel
add r0, r0, #127 + 128 @ alignment + stack
bic r0, r0, #127 @ align the kernel length
/*
* r0 = decompressed kernel length
* r1-r3 = unused
* r4 = kernel execution address * r4 = kernel execution address
* r5 = decompressed kernel start
* r7 = architecture ID * r7 = architecture ID
* r8 = atags pointer * r8 = atags pointer
* r9-r12,r14 = corrupted
*/
add r1, r5, r0 @ end of decompressed kernel
adr r2, reloc_start
ldr r3, LC1
add r3, r2, r3
1: ldmia r2!, {r9 - r12, r14} @ copy relocation code
stmia r1!, {r9 - r12, r14}
ldmia r2!, {r9 - r12, r14}
stmia r1!, {r9 - r12, r14}
cmp r2, r3
blo 1b
mov sp, r1
add sp, sp, #128 @ relocate the stack
bl cache_clean_flush
ARM( add pc, r5, r0 ) @ call relocation code
THUMB( add r12, r5, r0 )
THUMB( mov pc, r12 ) @ call relocation code
/*
* We're not in danger of overwriting ourselves. Do this the simple way.
*
* r4 = kernel execution address
* r7 = architecture ID
*/ */
wont_overwrite: mov r0, r4 mov r0, r4
mov r1, sp @ malloc space above stack
add r2, sp, #0x10000 @ 64k max
mov r3, r7 mov r3, r7
bl decompress_kernel bl decompress_kernel
b call_kernel bl cache_clean_flush
bl cache_off
mov r0, #0 @ must be zero
mov r1, r7 @ restore architecture number
mov r2, r8 @ restore atags pointer
mov pc, r4 @ call kernel
.align 2 .align 2
.type LC0, #object .type LC0, #object
...@@ -323,11 +342,11 @@ LC0: .word LC0 @ r1 ...@@ -323,11 +342,11 @@ LC0: .word LC0 @ r1
.word __bss_start @ r2 .word __bss_start @ r2
.word _end @ r3 .word _end @ r3
.word _start @ r5 .word _start @ r5
.word _image_size @ r6 .word _edata @ r6
.word _image_size @ r9
.word _got_start @ r11 .word _got_start @ r11
.word _got_end @ ip .word _got_end @ ip
.word user_stack_end @ sp .word user_stack_end @ sp
LC1: .word reloc_end - reloc_start
.size LC0, . - LC0 .size LC0, . - LC0
#ifdef CONFIG_ARCH_RPC #ifdef CONFIG_ARCH_RPC
...@@ -353,7 +372,7 @@ params: ldr r0, =0x10000100 @ params_phys for RPC ...@@ -353,7 +372,7 @@ params: ldr r0, =0x10000100 @ params_phys for RPC
* On exit, * On exit,
* r0, r1, r2, r3, r9, r10, r12 corrupted * r0, r1, r2, r3, r9, r10, r12 corrupted
* This routine must preserve: * This routine must preserve:
* r4, r5, r6, r7, r8 * r4, r7, r8
*/ */
.align 5 .align 5
cache_on: mov r3, #8 @ cache_on function cache_on: mov r3, #8 @ cache_on function
...@@ -550,43 +569,6 @@ __common_mmu_cache_on: ...@@ -550,43 +569,6 @@ __common_mmu_cache_on:
sub pc, lr, r0, lsr #32 @ properly flush pipeline sub pc, lr, r0, lsr #32 @ properly flush pipeline
#endif #endif
/*
* All code following this line is relocatable. It is relocated by
* the above code to the end of the decompressed kernel image and
* executed there. During this time, we have no stacks.
*
* r0 = decompressed kernel length
* r1-r3 = unused
* r4 = kernel execution address
* r5 = decompressed kernel start
* r7 = architecture ID
* r8 = atags pointer
* r9-r12,r14 = corrupted
*/
.align 5
reloc_start: add r9, r5, r0
sub r9, r9, #128 @ do not copy the stack
debug_reloc_start
mov r1, r4
1:
.rept 4
ldmia r5!, {r0, r2, r3, r10 - r12, r14} @ relocate kernel
stmia r1!, {r0, r2, r3, r10 - r12, r14}
.endr
cmp r5, r9
blo 1b
mov sp, r1
add sp, sp, #128 @ relocate the stack
debug_reloc_end
call_kernel: bl cache_clean_flush
bl cache_off
mov r0, #0 @ must be zero
mov r1, r7 @ restore architecture number
mov r2, r8 @ restore atags pointer
mov pc, r4 @ call kernel
/* /*
* Here follow the relocatable cache support functions for the * Here follow the relocatable cache support functions for the
* various processors. This is a generic hook for locating an * various processors. This is a generic hook for locating an
...@@ -791,7 +773,7 @@ proc_types: ...@@ -791,7 +773,7 @@ proc_types:
* On exit, * On exit,
* r0, r1, r2, r3, r9, r12 corrupted * r0, r1, r2, r3, r9, r12 corrupted
* This routine must preserve: * This routine must preserve:
* r4, r6, r7 * r4, r7, r8
*/ */
.align 5 .align 5
cache_off: mov r3, #12 @ cache_off function cache_off: mov r3, #12 @ cache_off function
...@@ -866,7 +848,7 @@ __armv3_mmu_cache_off: ...@@ -866,7 +848,7 @@ __armv3_mmu_cache_off:
* On exit, * On exit,
* r1, r2, r3, r9, r10, r11, r12 corrupted * r1, r2, r3, r9, r10, r11, r12 corrupted
* This routine must preserve: * This routine must preserve:
* r0, r4, r5, r6, r7 * r4, r6, r7, r8
*/ */
.align 5 .align 5
cache_clean_flush: cache_clean_flush:
...@@ -1088,7 +1070,6 @@ memdump: mov r12, r0 ...@@ -1088,7 +1070,6 @@ memdump: mov r12, r0
#endif #endif
.ltorg .ltorg
reloc_end:
.align .align
.section ".stack", "aw", %nobits .section ".stack", "aw", %nobits
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment