|
2#
樓主 |
發表於 2008-10-9 15:32:16
|
只看該作者
既然跳到真正的kernel開始跑,表示進入重頭戲,在進入kernel之前arm的平台有一些預設的狀況,也就是說arm kernel image會預設目前的cpu和系統的狀況是在某個狀態,這樣對一個剛要跑起來的OS比較決定目前要怎麼boot起來。2 q. j; u1 I6 Q. l
$ Z0 q2 k2 `( c; W
可以看一下comment,有清楚的描述。這也幫助我們了解為什麼decompresser的程式跑完之後,還要把cache關掉。- 59 /*7 A1 K2 Z) p6 S1 r3 O. j* {1 B
- 60 * Kernel startup entry point.1 A! p, ?2 q, K/ ~' b
- 61 * ---------------------------
Q5 X; F- a5 F$ e+ c - 62 *
: j! t [: T, X: P1 V5 v M8 `' X - 63 * This is normally called from the decompressor code. The requirements
: |: h9 O, w% }& H+ w$ _ - 64 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,# V; n9 l- `, l( s3 p
- 65 * r1 = machine nr, r2 = atags pointer.
複製代碼 基於以上的假設,當program counter指到kernel的程式的時候,就會從line 80開始跑。- Y& L+ o5 c/ |7 p6 p: }1 V
line 80, msr指令會把, operand的值搬到cpsr_c裡面。這是用來確保arm cpu目前是跑在svc mode, irq&fiq都disable。(設成0x1就會disable,definition在./include/asm-arm/ptrace.h)
$ f$ u# k5 w" e; k3 k) f) Gline 82, 讀取CPU ID到r9
0 z2 ]6 \6 A' t- M$ dline 83, 跳到 __lookup_processor_type 執行(bl會記住返回位址)。- 77 .section ".text.head", "ax"! Y t1 Q1 x6 i5 z; E7 W
- 78 .type stext, %function1 B7 L8 U& m7 u& z$ o5 `
- 79 ENTRY(stext)
3 W$ ?! k( \; t+ I! p) o8 r1 V - 80 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
9 |- _6 x# [% S3 m g - 81 @ and irqs disabled
: U% X% O& J0 I$ x - 82 mrc p15, 0, r9, c0, c0 @ get processor id7 z6 I" I; N" [/ F U9 l& |
- 83 bl __lookup_processor_type @ r5=procinfo r9=cpuid
複製代碼 接著會跳到head-common.S這個檔,
% s' R) k. R7 I9 y; U5 }line 158, (3f表示forware往前找叫做『3』label)將label 3的address放到r3。! R/ w# _; g( m! R" n* q( i
line 159, 將r3指到的位址的資料,依序放到r7, r6, r5.(ldmda的da是要每次都位址減一次)
1 J L2 N% e2 C+ a2 h- Tline l60, 161, 利用真實得到位址r3減去取得資料的位址得到一個offset值,這樣可計算出r5, r6真正應該要指到的地方。
1 N4 Y+ z; J! I8 V" Y/ L: Aline 163~169,這邊的程式應該不陌生,就是在各個CPU info裡面找尋對應的structure。找到的話就跳到line 171,返回head.S
; a, {% Z& ~! l% i) L4 F- r4 Yline 170, 找不到的話,r5的processor id就放0x0.表示unknown id。' u1 r, b% E7 h3 q
i. ], h* R( e9 t: v/ R. H" N__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: H) ^) F2 |+ F X8 a
- 157 __lookup_processor_type:9 b2 D1 V/ ~/ g8 `, g5 m) u
- 158 adr r3, 3f0 G9 I0 A2 h Q2 g6 g
- 159 ldmda r3, {r5 - r7}! G" p, R2 G- S! [# t
- 160 sub r3, r3, r7 @ get offset between virt&phys
1 m8 ?# G/ k$ F! E* X - 161 add r5, r5, r3 @ convert virt addresses to, V$ s4 d! A* g2 x2 O+ F
- 162 add r6, r6, r3 @ physical address space
0 a8 N& @( a) o - 163 1: ldmia r5, {r3, r4} @ value, mask5 o6 T' V5 S; v: \0 d' F3 L% r% X
- 164 and r4, r4, r9 @ mask wanted bits4 s; H# h3 ]7 }6 L
- 165 teq r3, r42 G5 F, s! F5 I
- 166 beq 2f/ e# w4 ~" p l7 A6 e: ~
- 167 add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)$ ?! O( M, k4 U- W. G c4 R
- 168 cmp r5, r63 v* P2 a: c& v+ v: v- Y* L% F: a
- 169 blo 1b
+ \% P2 \, X7 _" r" } - 170 mov r5, #0 @ unknown processor9 f, u+ J# d, {* N& W- \2 j# `
- 171 2: mov pc, lr
; a! q" G" Y. {, c
9 s2 d& _; N: i& b- 187 .long __proc_info_begin
# x* H" s9 K6 S" U$ h3 |3 n - 188 .long __proc_info_end# K6 j8 J. y% i/ |
- 189 3: .long .# P$ h' _% B* R1 T
- 190 .long __arch_info_begin
$ r, U( |# X# }7 a6 y" y - 191 .long __arch_info_end
複製代碼 跳了很多檔案,建議指令和object code如何link的概念要有,就會很清楚了。 |
|