|
2#
樓主 |
發表於 2008-10-9 15:32:16
|
只看該作者
既然跳到真正的kernel開始跑,表示進入重頭戲,在進入kernel之前arm的平台有一些預設的狀況,也就是說arm kernel image會預設目前的cpu和系統的狀況是在某個狀態,這樣對一個剛要跑起來的OS比較決定目前要怎麼boot起來。
. u! c. ] q, d' T
% I! O3 e2 e0 ^/ a" j" H1 N, t可以看一下comment,有清楚的描述。這也幫助我們了解為什麼decompresser的程式跑完之後,還要把cache關掉。- 59 /*
7 Y3 M- z$ w8 Z. L ]/ n9 b - 60 * Kernel startup entry point.
+ z8 K" a6 o# {0 L) r# K0 p2 e0 y2 J2 A - 61 * ---------------------------
+ M- U/ a k; _7 v0 k9 O - 62 *
- P# J. V8 c1 u3 H - 63 * This is normally called from the decompressor code. The requirements: A: M1 q$ f* j; ~' n; \* B. Z
- 64 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,4 D! S( Q5 r* X
- 65 * r1 = machine nr, r2 = atags pointer.
複製代碼 基於以上的假設,當program counter指到kernel的程式的時候,就會從line 80開始跑。
# J K" Y# W; [- _' N/ w$ vline 80, msr指令會把, operand的值搬到cpsr_c裡面。這是用來確保arm cpu目前是跑在svc mode, irq&fiq都disable。(設成0x1就會disable,definition在./include/asm-arm/ptrace.h)# H5 @$ g' Z" J" u$ |. z
line 82, 讀取CPU ID到r9, c% J2 F9 g+ P) O3 T4 R$ B$ N
line 83, 跳到 __lookup_processor_type 執行(bl會記住返回位址)。- 77 .section ".text.head", "ax"2 z: ]4 F* [# G: R2 j" X0 Q7 q
- 78 .type stext, %function
" {0 v, \) ~# W3 C) W, ^ - 79 ENTRY(stext)
2 ^, h- U: k! ? `- d& H - 80 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
. W4 M4 g, u, l8 Z - 81 @ and irqs disabled+ z. J& U5 s7 F: h) r2 J2 I" `
- 82 mrc p15, 0, r9, c0, c0 @ get processor id
k2 |8 W6 }) i7 E/ D4 h; K - 83 bl __lookup_processor_type @ r5=procinfo r9=cpuid
複製代碼 接著會跳到head-common.S這個檔, R3 R& }* p8 [5 ~+ k, k
line 158, (3f表示forware往前找叫做『3』label)將label 3的address放到r3。) R$ C; K6 I/ ]2 w4 Q& c
line 159, 將r3指到的位址的資料,依序放到r7, r6, r5.(ldmda的da是要每次都位址減一次): K, P. y+ O/ b1 F3 d4 k* i
line l60, 161, 利用真實得到位址r3減去取得資料的位址得到一個offset值,這樣可計算出r5, r6真正應該要指到的地方。" Z6 T6 F. N$ G& v J7 ^4 G& h7 P& K
line 163~169,這邊的程式應該不陌生,就是在各個CPU info裡面找尋對應的structure。找到的話就跳到line 171,返回head.S9 E$ t6 U6 w9 J E* |
line 170, 找不到的話,r5的processor id就放0x0.表示unknown id。. @# x% G9 T1 F" |" V
1 \$ d1 D/ M! f t, c# t" c
__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
" }) }0 N& |. t M: M# F - 157 __lookup_processor_type:- X" s) k8 F/ f: \! J
- 158 adr r3, 3f
0 A- H6 |6 Y& O/ ~! G0 \" e - 159 ldmda r3, {r5 - r7}4 l9 T. _! T) M8 z
- 160 sub r3, r3, r7 @ get offset between virt&phys* x& \9 |) o8 p2 X/ E2 y$ o9 C
- 161 add r5, r5, r3 @ convert virt addresses to
8 {7 `7 I" e" y2 ^$ T& K5 k& ~2 B - 162 add r6, r6, r3 @ physical address space
9 @! S' k" N8 ~ - 163 1: ldmia r5, {r3, r4} @ value, mask8 n$ x$ Z5 E3 c; s+ u1 L
- 164 and r4, r4, r9 @ mask wanted bits% z8 S) g B% n; m% t+ q
- 165 teq r3, r4
, X1 s+ M; b6 r - 166 beq 2f6 S2 k1 \( l8 i. @1 x0 z$ c
- 167 add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)2 s9 S9 L! T5 j; I$ Z( t4 ^/ b4 q
- 168 cmp r5, r6
8 L! I Z' @* ^1 ]* b! ~9 p - 169 blo 1b" ]- I+ e( ]1 C# q% d
- 170 mov r5, #0 @ unknown processor
9 K& f; q4 x8 _6 q3 k5 n - 171 2: mov pc, lr
0 p; b# f; s3 O! j0 _
7 I& n8 R# I: z, W- 187 .long __proc_info_begin7 T9 v4 |' }. m3 J4 [
- 188 .long __proc_info_end
' }3 T) z! ]+ [+ D; h - 189 3: .long .! e0 K' {5 f" C5 d: H q8 u( ?6 q
- 190 .long __arch_info_begin
- ?4 q0 q5 X, \4 j - 191 .long __arch_info_end
複製代碼 跳了很多檔案,建議指令和object code如何link的概念要有,就會很清楚了。 |
|