|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
( Y% g5 a$ V4 a1 B0 ~6 m# x* K
Linux内核是由Uboot进行调用的,在执行内核前,需要满足什么条件呢?% R. u: x8 \$ [. ?
2 m+ `3 g# p8 G0 h
我们来看下内核文档Documentation/ARM/booting。内核版本为3.7.6。
: q1 ?8 @* s5 k5 d2 ~+ q2 h3 L1 M0 `
。。。。。。3 s) C" ~* y# ^! l
3 s) |1 q9 F: C) m6 l" Q, I7 H
3 J: O. ]0 P0 Q* `6 p) x7 |4 S
' ~9 p" ^& I7 b) w7 o% ]" j5. Calling the kernel image
0 s# x& q0 f; P$ h+ O0 a9 K---------------------------
, f8 m/ }7 I% H% a, {7 o; E
* n4 R" ]' H6 W, T" t7 iExisting boot loaders: MANDATORY
0 O X! P( |9 xNew boot loaders: MANDATORY0 Z9 g& E4 s! ^) h5 B: x
+ X8 x8 J! `3 X( p7 O1 z' VThere are two options for calling the kernel zImage. If the zImage$ a( C+ p( [7 d8 @9 T d- ?0 u1 B
is stored in flash, and is linked correctly to be run from flash,
+ ^; b4 c0 i5 G) g8 Gthen it is legal for the boot loader to call the zImage in flash
2 U7 \- I5 B. W: Z ?, s3 edirectly.! m2 t `# c; u! C, T- a& m
; p9 R0 M7 x: Q! \# z
The zImage may also be placed in system RAM (at any location) and
2 z+ Z$ T; {% N& |: Y' \, i: Tcalled there. Note that the kernel uses 16K of RAM below the image: B( L- O) T( W# r- a1 z
to store page tables. The recommended placement is 32KiB into RAM.2 m1 p9 s; I1 `) M" H: ^& N$ G
0 v/ @8 [2 ~$ u# f m* K
In either case, the following conditions must be met:
& T# K q) c' l9 s- m
/ M/ o2 t A& T8 ]- Quiesce all DMA capable devices so that memory does not get
" F0 M: {5 B& l7 f5 w% V corrupted by bogus network packets or disk data. This will save
9 Y8 k e. K( Y/ p' x you many hours of debug.
& M( g* N/ a( w7 E( d1 n8 }& f e" V$ A
- CPU register settings
( ?) l+ D% ] V+ y0 _# ^& | r0 = 0,
* O. b1 d7 g! U0 ]1 Z+ K r1 = machine type number discovered in (3) above.+ W( }! p& I% x5 p5 n' z- U! U
r2 = physical address of tagged list in system RAM, or
1 c: x! S1 j( e physical address of device tree block (dtb) in system RAM& g Z, a( K6 N1 r) p0 _; z
& a2 j$ [! B0 Y/ h
- CPU mode
) O& R# W% Y( o d9 z' B All forms of interrupts must be disabled (IRQs and FIQs)
7 r" \* W& b0 @1 C' P
' k+ \% ]# s% N% q V* v For CPUs which do not include the ARM virtualization extensions, the9 `1 q0 ~# G% f- e2 Y
CPU must be in SVC mode. (A special exception exists for Angel)
" u' I* K9 s0 g0 A
; w$ Y; \2 s2 _3 F+ E/ T CPUs which include support for the virtualization extensions can be
+ }6 o9 o- J' @+ Q( }! H. c7 x entered in HYP mode in order to enable the kernel to make full use of
3 N- w9 o( G3 f0 w these extensions. This is the recommended boot method for such CPUs,/ _( l. a: o" B( k* Q# F
unless the virtualisations are already in use by a pre-installed4 h4 w4 D" p& r) E0 T
hypervisor.
x( E K. ] F6 r, X( p/ B# D8 s" g7 |8 \
If the kernel is not entered in HYP mode for any reason, it must be& x; E ]% n4 s3 q
entered in SVC mode.
' d2 a( ]! k- a7 M- V; q% g+ Z% d# ]2 w8 D- N# [' M1 h
- Caches, MMUs- v* h. I0 O* Y5 _ x3 b( f
The MMU must be off.; C( \* [$ i( V
Instruction cache may be on or off.7 C2 W" _! |. { |
Data cache must be off.6 V7 t8 ?. L! c( F. z: h8 M
+ [4 W- A- W$ d0 [( k If the kernel is entered in HYP mode, the above requirements apply to
- Z. a; i: E7 J$ r# [0 P5 ^ the HYP mode configuration in addition to the ordinary PL1 (privileged
5 s! l3 ]% C/ Y. e+ ~2 c( G9 P kernel modes) configuration. In addition, all traps into the3 {/ l" u0 _9 {9 y
hypervisor must be disabled, and PL1 access must be granted for all
* r! _, Y8 s$ r$ Z, o peripherals and CPU resources for which this is architecturally
0 z: J( G) K1 I6 r1 ^; g. { possible. Except for entering in HYP mode, the system configuration
* a) r6 V9 L. i2 b4 B- V$ g* | should be such that a kernel which does not include support for the
1 ~' o! n/ T9 H virtualization extensions can boot correctly without extra help.2 v# h; i/ h. ~
5 X; v6 {3 s' I" ?! J; y- B
- The boot loader is expected to call the kernel image by jumping0 \$ g! \8 r/ a* J) S
directly to the first instruction of the kernel image.
; Y; ~$ V. ~- V' x" M+ h# d8 G6 \5 H: c/ R8 B# p3 [+ q* L
On CPUs supporting the ARM instruction set, the entry must be
; D8 j1 L! Q3 b. S+ M8 e made in ARM state, even for a Thumb-2 kernel.
+ R$ z- w1 ~7 `9 R1 N# e
) U7 o2 a8 q2 ? On CPUs supporting only the Thumb instruction set such as6 {5 d6 h2 U, ]/ s# e0 I* @( L
Cortex-M class CPUs, the entry must be made in Thumb state.
) ~! V* B6 w# x: t! ?- R* q) Z% B( z) Z- X+ B: g! z
5 Z7 J8 f0 h( ?) C
这里,省略了该文档中不感兴趣的部分。5 S3 L, E6 \( _$ h) Q3 O
2 d, w/ b; G/ v
根据文档,
' W! G/ `+ H: X0 `1 h) [5 o2 C( E+ R/ p" E
第一, 必须禁止所有使用DMA的设备。 感觉这个有点多余,Uboot使用的设备,包括网卡之类的,一般都不会使用DMA。
7 ~, l8 ~+ d7 \4 j
% N$ \5 ?$ }+ `第二,必须设置r0,r1和r2寄存器为相应的值。这个是由下面的函数调用实现的。
4 K" k: S7 _* h. e$ O" Z' T) }* I
该函数在Uboot/lib_arm/armlinux.c的do_bootm_linux函数中被调用。* E& u- L/ [4 r+ g. f. t& [
, a' @ n, ]( _) |0 b5 x
theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
9 k$ R; f: i' V% A$ |. e
/ c. U) T) q) Q/ ?$ d根据ATPCS的规则,函数的实参将分别传入r0到r3寄存器。这里有正好传入三个参数对应着0,机器码和参数列表的地址。7 G, Z# |( E) B4 @ E& K0 I
3 X0 @3 [" ]7 W& h
第三,必须禁止中断,并且将CPU置入SVC(管理)模式。这些工作已经由start.S完成了。
( x1 f6 } J) x1 M9 {, w4 E. `# x3 a" P8 k8 L, o- k) `
第四,必须禁止数据cache和MMU,可以使能或禁止指令cache。这个是由下面的函数调用实现的。& Z( v/ ^9 X) B/ j0 x' N. |7 ]% a- b2 K
+ w, o; `2 X6 l" J
该函数位在Uboot/lib_arm/armlinux.c的do_bootm_linux函数中被调用。
) h1 l& O" c" y. ^4 E+ ?2 \& e7 Q1 o; r( P9 W6 N# s
下列函数位于:Uboot/cpu/arm920t/cpu.c中。
* L3 h( y _) z1 K, h5 `
7 u; S/ `8 T) _) hint cleanup_before_linux (void)& ^' b; U% B: H7 P% V3 _
{
- R P0 E# | k- { /*; B6 w7 j6 ^+ f) K
* this function is called just before we call linux8 T2 h) q8 f. e {+ G7 [( F- z
* it prepares the processor for linux" E3 |# ^' d4 h2 X& N
*( `: G. H& v2 o
* we turn off caches etc ...
, r8 I6 Y) n- K# ^ */& U# i3 E" d4 D
1 P; ^9 N' e, B& ? b1 i
unsigned long i;0 z4 R l* o m, @9 v3 b3 } X& v8 y2 y
$ X2 g: n1 d- |0 c4 g
disable_interrupts ();8 F, {) J/ U, I, Q0 ~% L
* t4 j$ e+ q, K4 G
/* turn off I/D-cache */
& T) D/ J/ G' G. z. Y asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));& k' @/ I) ~* I: y4 V% |) K& j+ l
i &= ~(C1_DC | C1_IC);
4 l ~8 `- d4 y& w9 }$ {7 c) A0 i asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));5 O o0 n- P3 T$ }
: t" ~8 `# ^& b( l; {3 r
/* flush I/D-cache */) }% r1 _- {; b3 O) @1 n
i = 0;
4 J8 k. l+ B& g. Z3 f# N' V6 k+ M+ _ asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));' O. I, {- U5 }2 K! `" ?
6 \0 ^) I1 w# h7 k4 W$ R. Q return (0);
5 R' d6 Y; I3 h; u) L}
7 w5 N# I* I$ v4 M1 C9 K5 ~ o4 X) k1 P+ V6 G" w9 A% f6 W
可以看出该函数禁止了数据和指令cache,同时冲刷了cache。9 B: y: B/ B( ^ L. Q
这里并没有禁止MMU,MMU禁止是在start.S中完成的。; b' I1 i" F" W" U
4 P' S$ m9 y! C' s0 k( y9 ^
6 l, y+ t' ~4 R- }2 l1 j1 ?
2 t) I0 @2 O/ c6 r; T5 O: \
4 w( N5 r9 b. s* \) S; P1 P+ m% O7 ~) S
% g. B6 D) [/ P( I* N* @- i" h
% V4 d' a% Q. j2 z+ Q2 c* A' K+ [1 e3 ?) s7 |* U
. j: c- n7 A' [' d( l
|
|