Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | /* * linux/arch/unicore32/boot/compressed/head.S * * Code specific to PKUnity SoC and UniCore ISA * * Copyright (C) 2001-2010 GUAN Xue-tao * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <linux/linkage.h> #include <mach/memory.h> #define csub cmpsub #define cand cmpand #define nop8 nop; nop; nop; nop; nop; nop; nop; nop .section ".start", #alloc, #execinstr .text start: .type start,#function /* Initialize ASR, PRIV mode and INTR off */ mov r0, #0xD3 mov.a asr, r0 adr r0, LC0 ldm (r1, r2, r3, r5, r6, r7, r8), [r0]+ ldw sp, [r0+], #28 sub.a r0, r0, r1 @ calculate the delta offset /* * if delta is zero, we are running at the address * we were linked at. */ beq not_relocated /* * We're running at a different address. We need to fix * up various pointers: * r5 - zImage base address (_start) * r7 - GOT start * r8 - GOT end */ add r5, r5, r0 add r7, r7, r0 add r8, r8, r0 /* * we need to fix up pointers into the BSS region. * r2 - BSS start * r3 - BSS end * sp - stack pointer */ add r2, r2, r0 add r3, r3, r0 add sp, sp, r0 /* * Relocate all entries in the GOT table. * This fixes up the C references. * r7 - GOT start * r8 - GOT end */ 1001: ldw r1, [r7+], #0 add r1, r1, r0 stw.w r1, [r7]+, #4 csub.a r7, r8 bub 1001b not_relocated: /* * Clear BSS region. * r2 - BSS start * r3 - BSS end */ mov r0, #0 1002: stw.w r0, [r2]+, #4 csub.a r2, r3 bub 1002b /* * Turn on the cache. */ mov r0, #0 movc p0.c5, r0, #28 @ cache invalidate all nop8 movc p0.c6, r0, #6 @ tlb invalidate all nop8 mov r0, #0x1c @ en icache and wb dcache movc p0.c1, r0, #0 nop8 /* * Set up some pointers, for starting decompressing. */ mov r1, sp @ malloc space above stack add r2, sp, #0x10000 @ 64k max /* * Check to see if we will overwrite ourselves. * r4 = final kernel address * 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 */ ldw r4, =KERNEL_IMAGE_START csub.a r4, r2 bea wont_overwrite add r0, r4, r6 csub.a r0, r5 beb wont_overwrite /* * If overwrite, just print error message */ b __error_overwrite /* * We're not in danger of overwriting ourselves. * Do this the simple way. */ wont_overwrite: /* * decompress_kernel: * r0: output_start * r1: free_mem_ptr_p * r2: free_mem_ptr_end_p */ mov r0, r4 b.l decompress_kernel @ C functions /* * Clean and flush the cache to maintain consistency. */ mov r0, #0 movc p0.c5, r0, #14 @ flush dcache nop8 movc p0.c5, r0, #20 @ icache invalidate all nop8 /* * Turn off the Cache and MMU. */ mov r0, #0 @ disable i/d cache and MMU movc p0.c1, r0, #0 nop8 mov r0, #0 @ must be zero ldw r4, =KERNEL_IMAGE_START mov pc, r4 @ call kernel .align 2 .type LC0, #object LC0: .word LC0 @ r1 .word __bss_start @ r2 .word _end @ r3 .word _start @ r5 .word _image_size @ r6 .word _got_start @ r7 .word _got_end @ r8 .word decompress_stack_end @ sp .size LC0, . - LC0 print_string: #ifdef CONFIG_DEBUG_OCD 2001: ldb.w r1, [r0]+, #1 csub.a r1, #0 bne 2002f mov pc, lr 2002: movc r2, p1.c0, #0 cand.a r2, #2 bne 2002b movc p1.c1, r1, #1 csub.a r1, #'\n' cmoveq r1, #'\r' beq 2002b b 2001b #else mov pc, lr #endif __error_overwrite: adr r0, str_error b.l print_string 2001: nop8 b 2001b str_error: .asciz "\nError: Kernel address OVERWRITE\n" .align .ltorg .align 4 .section ".stack", "aw", %nobits decompress_stack: .space 4096 decompress_stack_end: |