245 mov r5, r2 @ decompress after malloc space( Z- ?, N4 A. N
246 mov r0, r5 ! R) @; t3 H* ]$ L
247 mov r3, r7 1 I' q# B- i7 D6 G) u+ K: y# b& K
248 bl decompress_kernel* ~; t" V* [) j5 O: ?! t
249" _4 R5 D# t3 F9 ^+ T" s
250 add r0, r0, #127 + 128 @ alignment + stack0 r q7 H- f9 r
251 bic r0, r0, #127 @ align the kernel length
複製代碼
跳到wont_overwrite之後,當然就是要開始把kernel解壓縮,2 y# `4 @, c) {+ m: b. Z
line 283,把r4搬到r0,r4就是我們剛剛說的kernel被解壓縮之後的位址。(也就是解完之後應該要執行的位置)8 a" c: c9 g9 H* _; u
line 284,把r7搬到r3,r7從一開始讀進來之後,也沒用過,理論上是architecture ID。+ u, ~2 v0 Y# {% D+ ~! v
line 285,是跳到decompress_kernel,這邊我們發現decompress_kernel是被定義在misc.c檔,所以這是第一次從assembly code跳到c code的地方。這樣一來我們就知道原來剛剛要把cache打開和設定好sp的用意,原來就是為了要執行c code,因為c的程式碼有固定的執行方式,會需要用到sp,這部份可以參考『procedure call standard for the ARM architecture』,這也是r4和r7被搬到r0, r3的原因,因為r0~r3是用來傳遞C function的參數用的,r0就是arg0, r1=arg1, etc.
283 wont_overwrite: mov r0, r4 ) c' {8 x- q- m( G/ m3 N( S
284 mov r3, r7+ M+ B5 |3 u, ~* n4 V
285 bl decompress_kernel ( {6 Y4 _5 x' }. G8 H" X2 U2 e
286 b call_kernel
複製代碼
偷看misc.c
346 decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr, int arch_id)
複製代碼
果然r0~r3就是的參數。作者: gogojesse 時間: 2008-10-7 01:01 PM
由於解壓縮不是我們的重點; T# i1 D( ^3 [6 t* b& R
沒有trace 1 n& U4 W+ `; {3 B; @, ^假設一切都順利 1 O, r/ T. {2 p- Udecompress_kernel結束後& B! G0 ^: `" m5 S6 w. n$ M& D
我們就得到一個解壓縮完的kernel放在r4指向的位置$ `( [% Z0 m5 q2 Y
line 286,會jump到call_kernel,如下: 9 O9 U$ a" R% Zline 516, flush cache, \7 N0 h, V9 q6 c
line 517, 關掉 cache6 p) x2 l: N1 s" l% W5 l# ?. j
line 518~520,將r0, r1, r2分別填值。 . u6 c* M( C% N* p! iline 521,將program counter指到r4,也就是解壓縮的kernel的一開頭。 2 e& t% J# E0 H& i7 l3 `# r5 Q, ?3 y- x' l9 B; r2 M' w, u- C: Z
到這邊我們終於結束head.S的工作,解壓縮並且跳到另外一個object code的開始。跳到解壓縮的開始位置,究竟會進入哪一個function?
516 call_kernel: bl cache_clean_flush 9 T* q$ O3 v) C& E c( p6 D