1
2
3
4
5
6
7
8
9 #include <linux/linkage.h>
10 #include <mach/memory.h>
11
12 #define csub cmpsub
13 #define cand cmpand
14 #define nop8 nop; nop; nop; nop; nop; nop; nop; nop
15
16 .section ".start", #alloc, #execinstr
17 .text
18 start:
19 .type start,#function
20
21
22 mov r0, #0xD3
23 mov.a asr, r0
24
25 adr r0, LC0
26 ldm (r1, r2, r3, r5, r6, r7, r8), [r0]+
27 ldw sp, [r0+], #28
28 sub.a r0, r0, r1 @ calculate the delta offset
29
30
31
32
33
34 beq not_relocated
35
36
37
38
39
40
41
42
43 add r5, r5, r0
44 add r7, r7, r0
45 add r8, r8, r0
46
47
48
49
50
51
52
53 add r2, r2, r0
54 add r3, r3, r0
55 add sp, sp, r0
56
57
58
59
60
61
62
63 1001: ldw r1, [r7+], #0
64 add r1, r1, r0
65 stw.w r1, [r7]+, #4
66 csub.a r7, r8
67 bub 1001b
68
69 not_relocated:
70
71
72
73
74
75 mov r0, #0
76 1002: stw.w r0, [r2]+, #4
77 csub.a r2, r3
78 bub 1002b
79
80
81
82
83 mov r0, #0
84 movc p0.c5, r0, #28 @ cache invalidate all
85 nop8
86 movc p0.c6, r0, #6 @ tlb invalidate all
87 nop8
88
89 mov r0, #0x1c @ en icache and wb dcache
90 movc p0.c1, r0, #0
91 nop8
92
93
94
95
96
97 mov r1, sp @ malloc space above stack
98 add r2, sp, #0x10000 @ 64k max
99
100
101
102
103
104
105
106
107
108
109
110 ldw r4, =KERNEL_IMAGE_START
111 csub.a r4, r2
112 bea wont_overwrite
113 add r0, r4, r6
114 csub.a r0, r5
115 beb wont_overwrite
116
117
118
119
120 b __error_overwrite
121
122
123
124
125
126 wont_overwrite:
127
128
129
130
131
132
133 mov r0, r4
134 b.l decompress_kernel @ C functions
135
136
137
138
139 mov r0, #0
140 movc p0.c5, r0, #14 @ flush dcache
141 nop8
142 movc p0.c5, r0, #20 @ icache invalidate all
143 nop8
144
145
146
147
148 mov r0, #0 @ disable i/d cache and MMU
149 movc p0.c1, r0, #0
150 nop8
151
152 mov r0, #0 @ must be zero
153 ldw r4, =KERNEL_IMAGE_START
154 mov pc, r4 @ call kernel
155
156
157 .align 2
158 .type LC0, #object
159 LC0: .word LC0 @ r1
160 .word __bss_start @ r2
161 .word _end @ r3
162 .word _start @ r5
163 .word _image_size @ r6
164 .word _got_start @ r7
165 .word _got_end @ r8
166 .word decompress_stack_end @ sp
167 .size LC0, . - LC0
168
169 print_string:
170 #ifdef CONFIG_DEBUG_OCD
171 2001: ldb.w r1, [r0]+, #1
172 csub.a r1, #0
173 bne 2002f
174 mov pc, lr
175 2002:
176 movc r2, p1.c0, #0
177 cand.a r2, #2
178 bne 2002b
179 movc p1.c1, r1, #1
180 csub.a r1, #'\n'
181 cmoveq r1, #'\r'
182 beq 2002b
183 b 2001b
184 #else
185 mov pc, lr
186 #endif
187
188 __error_overwrite:
189 adr r0, str_error
190 b.l print_string
191 2001: nop8
192 b 2001b
193 str_error: .asciz "\nError: Kernel address OVERWRITE\n"
194 .align
195
196 .ltorg
197
198 .align 4
199 .section ".stack", "aw", %nobits
200 decompress_stack: .space 4096
201 decompress_stack_end: