|
2#
樓主 |
發表於 2008-10-9 15:32:16
|
只看該作者
既然跳到真正的kernel開始跑,表示進入重頭戲,在進入kernel之前arm的平台有一些預設的狀況,也就是說arm kernel image會預設目前的cpu和系統的狀況是在某個狀態,這樣對一個剛要跑起來的OS比較決定目前要怎麼boot起來。
. W' W0 ^- g1 t' G: t8 }! f! c, l& x( B. R
可以看一下comment,有清楚的描述。這也幫助我們了解為什麼decompresser的程式跑完之後,還要把cache關掉。- 59 /** ~' a# j- W$ O) m' L
- 60 * Kernel startup entry point.
) C& a& K/ P% Z! o" H - 61 * ---------------------------
5 Y1 \, [4 ` [. | - 62 *
& y1 E+ D& Q( a- ? - 63 * This is normally called from the decompressor code. The requirements7 i' i% D; i. X' k' B) p
- 64 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, l8 U3 v' P, D h7 S8 Y7 f+ [8 s
- 65 * r1 = machine nr, r2 = atags pointer.
複製代碼 基於以上的假設,當program counter指到kernel的程式的時候,就會從line 80開始跑。
# j2 q# j: E1 b4 |1 E9 ^1 p% nline 80, msr指令會把, operand的值搬到cpsr_c裡面。這是用來確保arm cpu目前是跑在svc mode, irq&fiq都disable。(設成0x1就會disable,definition在./include/asm-arm/ptrace.h)4 `9 a: E/ b/ \. c9 j& \) a
line 82, 讀取CPU ID到r9/ b, _# z6 Y: A1 _( o
line 83, 跳到 __lookup_processor_type 執行(bl會記住返回位址)。- 77 .section ".text.head", "ax"
4 l O9 x3 r+ p3 L4 I7 w+ j - 78 .type stext, %function
! E! i4 ~ M/ }5 F - 79 ENTRY(stext)
9 N* J3 H$ c' C0 G9 i' ~& g5 _ - 80 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
' `1 \" C1 j% e7 s: e - 81 @ and irqs disabled7 M* n+ Z, F# A
- 82 mrc p15, 0, r9, c0, c0 @ get processor id
( a1 W) |8 ?- `, k7 h* ]5 F; { - 83 bl __lookup_processor_type @ r5=procinfo r9=cpuid
複製代碼 接著會跳到head-common.S這個檔,3 B6 K* D8 N% L- A, ]
line 158, (3f表示forware往前找叫做『3』label)將label 3的address放到r3。' i* |# m+ v- C. ?2 D9 w) m4 R9 @" s; M
line 159, 將r3指到的位址的資料,依序放到r7, r6, r5.(ldmda的da是要每次都位址減一次)
' b3 d7 N+ N" q- l% m- U5 {# _line l60, 161, 利用真實得到位址r3減去取得資料的位址得到一個offset值,這樣可計算出r5, r6真正應該要指到的地方。5 S$ { U. C: a1 I1 W W/ @
line 163~169,這邊的程式應該不陌生,就是在各個CPU info裡面找尋對應的structure。找到的話就跳到line 171,返回head.S
- U5 K' J' v. Y' W! aline 170, 找不到的話,r5的processor id就放0x0.表示unknown id。
& K! k1 ?' W9 z, ^& s- f( `, P- ?$ V# ^: @
__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
/ W/ u+ t& d2 j9 L - 157 __lookup_processor_type:
. _: r2 j3 N9 r2 N. b7 V* Q& |2 x4 A5 u - 158 adr r3, 3f4 Z. H# [0 @2 J. |/ A
- 159 ldmda r3, {r5 - r7}" `' v8 \: f6 R/ {" p" n* h
- 160 sub r3, r3, r7 @ get offset between virt&phys
! }- e' _. ~# G1 _' F: ]3 @ - 161 add r5, r5, r3 @ convert virt addresses to
# o2 A4 m: _0 x; h7 m/ F; M5 O - 162 add r6, r6, r3 @ physical address space& a: ]: e8 b7 G
- 163 1: ldmia r5, {r3, r4} @ value, mask
3 q7 h$ w$ ^. B4 w7 ` F - 164 and r4, r4, r9 @ mask wanted bits) x. G+ y7 ~2 ` ]6 l$ p
- 165 teq r3, r4
7 }' @. N% b4 p6 B - 166 beq 2f
+ R" v4 q* @0 {5 a t9 R+ Q1 v7 g - 167 add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
8 ~! y6 X X1 f8 D/ P3 k) u. r - 168 cmp r5, r64 E! A& B" o) h8 s& V
- 169 blo 1b
- _& j! m9 i: }. _1 n7 m' h* H( ^ - 170 mov r5, #0 @ unknown processor" M* i- T# _. |. ~0 m
- 171 2: mov pc, lr9 l) @% Z; j7 L( q: U) o
- * e! b5 E* e/ |/ N+ c Z
- 187 .long __proc_info_begin1 A8 F8 V3 B- I; w0 O+ s7 `
- 188 .long __proc_info_end
% t. C- ]0 ?) s3 \ - 189 3: .long .# }- f5 K3 { F9 ~# J8 d
- 190 .long __arch_info_begin j6 e6 |0 q6 A) w k% ?
- 191 .long __arch_info_end
複製代碼 跳了很多檔案,建議指令和object code如何link的概念要有,就會很清楚了。 |
|