|
2#
樓主 |
發表於 2008-10-9 15:32:16
|
只看該作者
既然跳到真正的kernel開始跑,表示進入重頭戲,在進入kernel之前arm的平台有一些預設的狀況,也就是說arm kernel image會預設目前的cpu和系統的狀況是在某個狀態,這樣對一個剛要跑起來的OS比較決定目前要怎麼boot起來。
& D" ^ S8 N5 O* |- e6 Q" E! d; [4 V* c( }) k4 X2 V+ P
可以看一下comment,有清楚的描述。這也幫助我們了解為什麼decompresser的程式跑完之後,還要把cache關掉。- 59 /*
% M' ?3 A3 \- o; Q0 y2 T - 60 * Kernel startup entry point.. q) @: Q( ^, D5 K) w
- 61 * ---------------------------
5 u0 }) W% P/ c2 p2 _1 O - 62 *
7 Q& i1 Q5 F- K$ ]8 [ - 63 * This is normally called from the decompressor code. The requirements
. t4 j+ c) f/ M" } - 64 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
: J- E( ~7 J' o7 y2 n4 M' c" e% Y - 65 * r1 = machine nr, r2 = atags pointer.
複製代碼 基於以上的假設,當program counter指到kernel的程式的時候,就會從line 80開始跑。6 ?& k# Z) [1 V$ m8 j; Q
line 80, msr指令會把, operand的值搬到cpsr_c裡面。這是用來確保arm cpu目前是跑在svc mode, irq&fiq都disable。(設成0x1就會disable,definition在./include/asm-arm/ptrace.h)- r3 S2 C' Y# m0 h9 t, t0 }
line 82, 讀取CPU ID到r9
* B$ t, B2 u3 q* h4 Tline 83, 跳到 __lookup_processor_type 執行(bl會記住返回位址)。- 77 .section ".text.head", "ax"! y" |: V4 }: ?" x0 r6 {5 V/ Q
- 78 .type stext, %function& X( D1 S/ w% q8 I P4 t
- 79 ENTRY(stext)
m" ~, b' f/ ] - 80 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
& t9 W5 j7 t/ w$ Z9 K - 81 @ and irqs disabled
. o4 P0 m7 a* R - 82 mrc p15, 0, r9, c0, c0 @ get processor id0 P0 Z, @$ B$ T3 o3 Y" `9 X
- 83 bl __lookup_processor_type @ r5=procinfo r9=cpuid
複製代碼 接著會跳到head-common.S這個檔,+ s$ d7 u w. A H# w
line 158, (3f表示forware往前找叫做『3』label)將label 3的address放到r3。
+ { S% L& D+ h D6 C: Jline 159, 將r3指到的位址的資料,依序放到r7, r6, r5.(ldmda的da是要每次都位址減一次)
9 G' X/ ~0 }2 G" H2 S3 Z9 Sline l60, 161, 利用真實得到位址r3減去取得資料的位址得到一個offset值,這樣可計算出r5, r6真正應該要指到的地方。
( Q" F8 @+ M9 E4 R# xline 163~169,這邊的程式應該不陌生,就是在各個CPU info裡面找尋對應的structure。找到的話就跳到line 171,返回head.S- `& N1 x) {. M3 s3 R
line 170, 找不到的話,r5的processor id就放0x0.表示unknown id。
- Q ?- N9 [! n7 [2 \0 U0 l+ \' R7 {- M6 N0 A
__proc_info_xxx可以在 vmlinux.lds.S 找到,是用來包住CPU info的所有data.資料則是被定義在./arch/arm/mm/proc-xxx.S,例如arm926就有 proc-arm926.S,裡面有相對應的data宣告,compiling time的時候,這些資料會被編譯到這個區段當中。- 156 .type __lookup_processor_type, %function
6 r) d! E& o7 I9 R' _ - 157 __lookup_processor_type:. m, q6 S$ }% C
- 158 adr r3, 3f8 M: g/ u9 E2 [* i
- 159 ldmda r3, {r5 - r7}: F- d, f5 L* \% _+ f
- 160 sub r3, r3, r7 @ get offset between virt&phys1 Z+ I( w% q3 V! J% G7 ?8 w
- 161 add r5, r5, r3 @ convert virt addresses to+ P" m! Y2 G. X" b' T7 f
- 162 add r6, r6, r3 @ physical address space
3 C ~# X# m! O) U - 163 1: ldmia r5, {r3, r4} @ value, mask% j8 i; x" ?6 W. B# s
- 164 and r4, r4, r9 @ mask wanted bits
7 o/ Z( q4 R9 b' O) v- f6 l - 165 teq r3, r4
4 ^& U" a" |% V+ t - 166 beq 2f
( d! i* i9 c; { - 167 add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
4 A1 X+ s( A9 D) [5 Y& f - 168 cmp r5, r6
' G/ A( f p8 P7 w: \& W3 g - 169 blo 1b
9 U8 q7 n. B# p4 x' ` - 170 mov r5, #0 @ unknown processor
! N3 M# p+ ^1 Z% |/ u - 171 2: mov pc, lr8 }. _6 p6 h# B9 [& y
- , x1 R! c: X0 n% c+ F& ]0 r, |
- 187 .long __proc_info_begin. P3 h1 M) i# i0 n
- 188 .long __proc_info_end& N- ?* G% m: F, Y
- 189 3: .long .
2 o- M @2 f( [! {1 x" v9 l - 190 .long __arch_info_begin% }, o) u. a1 T ]
- 191 .long __arch_info_end
複製代碼 跳了很多檔案,建議指令和object code如何link的概念要有,就會很清楚了。 |
|