/*
|
/*
|
* linux/arch/arm/boot/compressed/head.S
|
* linux/arch/arm/boot/compressed/head.S
|
*
|
*
|
* Copyright (C) 1996 Russell King
|
* Copyright (C) 1996 Russell King
|
*/
|
*/
|
.text
|
.text
|
/*
|
/*
|
* sort out different calling conventions
|
* sort out different calling conventions
|
*/
|
*/
|
start: teq r0, #0
|
start: teq r0, #0
|
beq newparams
|
beq newparams
|
mov r4, #0x02000000
|
mov r4, #0x02000000
|
add r4, r4, #0x7C000
|
add r4, r4, #0x7C000
|
mov r3, #0x4000
|
mov r3, #0x4000
|
sub r3, r3, #4
|
sub r3, r3, #4
|
1: ldmia r0!, {r5 - r12}
|
1: ldmia r0!, {r5 - r12}
|
stmia r4!, {r5 - r12}
|
stmia r4!, {r5 - r12}
|
subs r3, r3, #32
|
subs r3, r3, #32
|
bpl 1b
|
bpl 1b
|
newparams: adr r2, LC0
|
newparams: adr r2, LC0
|
ldmia r2, {r2, r3, r4, r5, r6, sp}
|
ldmia r2, {r2, r3, r4, r5, r6, sp}
|
adr r7, start
|
adr r7, start
|
sub r6, r7, r6
|
sub r6, r7, r6
|
/*
|
/*
|
* Relocate pointers
|
* Relocate pointers
|
*/
|
*/
|
add r2, r2, r6
|
add r2, r2, r6
|
add r3, r3, r6
|
add r3, r3, r6
|
add r5, r5, r6
|
add r5, r5, r6
|
add sp, sp, r6
|
add sp, sp, r6
|
/*
|
/*
|
* Clear zero-init
|
* Clear zero-init
|
*/
|
*/
|
mov r6, #0
|
mov r6, #0
|
1: str r6, [r2], #4
|
1: str r6, [r2], #4
|
cmp r2, r3
|
cmp r2, r3
|
blt 1b
|
blt 1b
|
str r1, [r5] @ save architecture
|
str r1, [r5] @ save architecture
|
/*
|
/*
|
* Uncompress the kernel
|
* Uncompress the kernel
|
*/
|
*/
|
mov r1, #0x8000
|
mov r1, #0x8000
|
add r2, r2, r1, lsl #1 @ Add 64k for malloc
|
add r2, r2, r1, lsl #1 @ Add 64k for malloc
|
sub r1, r1, #1
|
sub r1, r1, #1
|
add r2, r2, r1
|
add r2, r2, r1
|
bic r5, r2, r1 @ decompress kernel to after end of the compressed
|
bic r5, r2, r1 @ decompress kernel to after end of the compressed
|
mov r0, r5
|
mov r0, r5
|
bl _decompress_kernel
|
bl _decompress_kernel
|
add r0, r0, #7
|
add r0, r0, #7
|
bic r2, r0, #7
|
bic r2, r0, #7
|
/*
|
/*
|
* Now move the kernel to the correct location (r5 -> r4, len r0)
|
* Now move the kernel to the correct location (r5 -> r4, len r0)
|
*/
|
*/
|
mov r0, r4 @ r0 = start of real kernel
|
mov r0, r4 @ r0 = start of real kernel
|
mov r1, r5 @ r1 = start of kernel image
|
mov r1, r5 @ r1 = start of kernel image
|
add r3, r5, r2 @ r3 = end of kernel
|
add r3, r5, r2 @ r3 = end of kernel
|
adr r4, movecode
|
adr r4, movecode
|
adr r5, movecodeend
|
adr r5, movecodeend
|
1: ldmia r4!, {r6 - r12, lr}
|
1: ldmia r4!, {r6 - r12, lr}
|
stmia r3!, {r6 - r12, lr}
|
stmia r3!, {r6 - r12, lr}
|
cmp r4, r5
|
cmp r4, r5
|
blt 1b
|
blt 1b
|
mrc p15, 0, r5, c0, c0
|
mrc p15, 0, r5, c0, c0
|
eor r5, r5, #0x44 << 24
|
eor r5, r5, #0x44 << 24
|
eor r5, r5, #0x01 << 16
|
eor r5, r5, #0x01 << 16
|
eor r5, r5, #0xa1 << 8
|
eor r5, r5, #0xa1 << 8
|
movs r5, r5, lsr #4
|
movs r5, r5, lsr #4
|
mov r5, #0
|
mov r5, #0
|
mcreq p15, 0, r5, c7, c5, 0 @ flush I cache
|
mcreq p15, 0, r5, c7, c5, 0 @ flush I cache
|
ldr r5, LC0 + 12 @ get architecture
|
ldr r5, LC0 + 12 @ get architecture
|
ldr r5, [r5]
|
ldr r5, [r5]
|
add pc, r1, r2 @ Call move code
|
add pc, r1, r2 @ Call move code
|
|
|
/*
|
/*
|
* r0 = length, r1 = to, r2 = from
|
* r0 = length, r1 = to, r2 = from
|
*/
|
*/
|
movecode: add r3, r1, r2
|
movecode: add r3, r1, r2
|
mov r4, r0
|
mov r4, r0
|
1: ldmia r1!, {r6 - r12, lr}
|
1: ldmia r1!, {r6 - r12, lr}
|
stmia r0!, {r6 - r12, lr}
|
stmia r0!, {r6 - r12, lr}
|
cmp r1, r3
|
cmp r1, r3
|
blt 1b
|
blt 1b
|
mrc p15, 0, r0, c0, c0
|
mrc p15, 0, r0, c0, c0
|
eor r0, r0, #0x44 << 24
|
eor r0, r0, #0x44 << 24
|
eor r0, r0, #0x01 << 16
|
eor r0, r0, #0x01 << 16
|
eor r0, r0, #0xa1 << 8
|
eor r0, r0, #0xa1 << 8
|
movs r0, r0, lsr #4
|
movs r0, r0, lsr #4
|
mov r0, #0
|
mov r0, #0
|
mcreq p15, 0, r0, c7, c5, 0 @ flush I cache
|
mcreq p15, 0, r0, c7, c5, 0 @ flush I cache
|
mov r1, r5 @ call kernel correctly
|
mov r1, r5 @ call kernel correctly
|
add pc, r4, #0x20 @ call via EXEC entry
|
add pc, r4, #0x20 @ call via EXEC entry
|
|
|
movecodeend:
|
movecodeend:
|
LC0: .word __edata
|
LC0: .word __edata
|
.word __end
|
.word __end
|
.word LOADADDR
|
.word LOADADDR
|
.word _architecture
|
.word _architecture
|
.word start
|
.word start
|
.word _user_stack+4096
|
.word _user_stack+4096
|
|
|
.bss
|
.bss
|
_architecture: .word 0
|
_architecture: .word 0
|
|
|