line 245, tst會去做and動作。並且update flags。這邊的用意是判斷位址是不是aligned。! q ?0 V$ z$ ?4 n& Q7 x
line 246, 沒有aligned跳到label 1,就返回了。7 y- J7 w n5 f9 _1 i# T
line 248~250, 讀取atags所在的address裡頭的值到r5,看看是否不等於ATAG_CORE_SIZE,不等於的話也是返回。, W* D" P5 Z h9 y. l; `% H
line 251~254, 判斷一下第一個達到的atag pointer是不是等於ATAG_CORE。如果正確的話,等一下要讀取atag的資料,才會正確。 " ~& R: c9 S9 A. o6 @1 u(atag是由bootloader帶給linux kernel的東西,用來告知booting所需要知道的參數。例如螢幕寬度,記憶體大小等等)
227 str r3, [r0], #41 W" |+ O% J3 R# I. z: H- S1 s
228 teq r0, r6 ) H# z% r5 z g- {2 b/ O
229 bne 1b
複製代碼
line 231, 將位址等於 r10+PROCINFO_MM_MMUFLAGS 裡頭的值放到r7。r10是proc_info的位址。proc的info data structure被定義在『./include/asm-arm/procinfo.h』,offset取得的方式用compiler的功能,以便以後新增structure的欄位的時候不需要更動程式碼。這邊的動作合起來就是讀預設要設給mmu flags的值。
99 ldr r13, __switch_data @ address to jump to after+ |' k1 \& r# g" E/ t# O# K
100 @ mmu has been enabled 6 R7 b+ j7 w, E2 ~: a8 s
101 adr lr, __enable_mmu @ return (PIC) address' i, Y6 N" R4 j8 Z$ y( o
102 add pc, r10, #PROCINFO_INITFUNC
複製代碼
line 99, 將__switch_data放到r13。(留作之後用)* Z8 Z& C8 C! ]% q. F) C% C
line 101, 將__enable_mmu的addr放到lr。(留作之後用) + C; b) e, J1 Y, a, Rline 102, 將 r10+#PROCINFO_INITFUNC 放到pc,也就是jump過去的意思。r10是proc_info的位址。PROCINFO_INITFUNC則是用之前提過的技巧,指向定義在./arch/arm/mm/proc-xxx.S的資料結構,以arm926為例,最後會指到
463 b __arm926_setup
複製代碼
所以程式碼就跳到了 __arm926_setup。
373 .type __arm926_setup, #function& H3 B3 v9 i+ z
374 __arm926_setup: ( L3 Y7 p/ g1 ~$ C8 s# L" ~
375 mov r0, #0+ w# q5 b3 m/ {' _1 {
376 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 * K* o+ i, J' }, [
59 stmia r7, {r0, r4} @ Save control register values. C) c) f x! o1 e" V
60 b start_kernel$ Y4 ~0 l3 m$ a8 ]" @ C
61 ENDPROC(__mmap_switched)
複製代碼
switch_data的第一行就是 __mmap_switched,所以我們直接看line 39。# ^( H" I, P; }1 {8 H7 s% T
line 39,將__data_loc的addr放到r30 y+ r) [6 r& l/ p. c
line 42,從r3的位址,連續讀取四筆資料到r4, r5, r6, r75 d% _. _, |6 h
line 43~47,看看data segment是不是需要搬動。 : m4 ?1 f9 t3 @; I. M+ G( D: Jline 49~52, clear BSS。9 x( I: n. {9 t# H6 T& A
3 G! {3 v' {% f( j( _' p; d8 ^: J由於linux kernel在進入start_kernel前有一些前提必須要滿足: ) L" A8 A' u6 `. F$ |r0 = cp#15 control register 9 v6 F& f/ v' ]) [r1 = machine ID 4 N2 C9 i1 g$ g, ir2 = atags pointer 4 b) @8 h# d h: ]" }( q% pr9 = processor ID . w, G9 D% j r/ b$ ^$ E8 f$ T3 a1 @8 D7 s7 y
所以line 54~59就是在做這些準備。0 K* o! w" ~" n f
最後呢? 我們就跳到start_kernel了。(而且還是用b start_kernel,表示我們不會再回來了)$ d, P6 \6 A/ S" o, N& U) x5 [