上海百度關(guān)鍵詞推廣名片seo什么意思
一.?? uboot啟動流程中函數(shù)
之前了解了uboot鏈接腳本文件 u-boot.lds。
從 u-boot.lds 中我們已經(jīng)知道了入口點是 arch/arm/lib/vectors.S 文件中的 _start。
本文了解 一下,uboot啟動過程中涉及的 reset 函數(shù)。本文繼上一篇文章學(xué)習(xí),地址如下:
uboot啟動流程-uboot鏈接腳本u-boot.lds_凌肖戰(zhàn)的博客-CSDN博客
二.?? reset 函數(shù)源碼詳解
從 u-boot.lds 中,我們已經(jīng)知道了入口點是 arch/arm/lib/vectors.S 文件中的 _start,代碼如下:?
38 /*
39 *************************************************************
40 *
41 * Exception vectors as described in ARM reference manuals
42 *
43 * Uses indirect branch to allow reaching handlers anywhere in
44 * memory.
45 **************************************************************
46 */
47
48 _start:
49
50 #ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
51 .word CONFIG_SYS_DV_NOR_BOOT_CFG
52 #endif
53
54 b reset
55 ldr pc, _undefined_instruction
56 ldr pc, _software_interrupt
57 ldr pc, _prefetch_abort
58 ldr pc, _data_abort
59 ldr pc, _not_used
60 ldr pc, _irq
61 ldr pc, _fiq
第 48 行:? _start 開始的是中斷向量表,其中 54~61 行就是中斷向量表,和我們裸機例程里面一樣。
1.?? start.S 文件中的 reset 函數(shù)
第 54 行跳轉(zhuǎn)到 reset 函數(shù)里面, reset 函數(shù)在 arch/arm/cpu/armv7/start.S 里面,代碼如下:
32 .globl reset
33 .globl save_boot_params_ret
34
35 reset:
36 /* Allow the board to save important registers */
37 b save_boot_params
start.S 文件的第 35 行就是 reset 函數(shù)。
第 37 行從 reset 函數(shù)跳轉(zhuǎn)到了 save_boot_params 函數(shù),而 save_boot_params 函數(shù)同樣定義在 start.S 里面,定義如下:
100????? ENTRY ( save_boot_params )101 ????? b save_boot_params_ret @ back to my caller
2.?? start.S文件中的save_boot_params_ret 函數(shù)
save_boot_params 函數(shù)也是只有一句跳轉(zhuǎn)語句,跳轉(zhuǎn)到 save_boot_params_ret 函數(shù),
save_boot_params_ret 函數(shù)代碼如下:
38 save_boot_params_ret:
39 /*
40 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32
41 * mode, except if in HYP mode already
42 */
43 mrs r0, cpsr
44 and r1, r0, #0x1f @ mask mode bits
45 teq r1, #0x1a @ test for HYP mode
46 bicne r0, r0, #0x1f @ clear all mode bits
47 orrne r0, r0, #0x13 @ set SVC mode
48 orr r0, r0, #0xc0 @ disable FIQ and IRQ
49 msr cpsr,r0
save_boot_params_ret 函數(shù)中,第43行~49行,將處理器設(shè)置為SVC模式,并且關(guān)閉FIQ和IRQ。
繼續(xù)分析 start.S 下面的代碼:
56 #if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
57 /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
58 mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
59 bic r0, #CR_V @ V = 0
60 mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register
61
62 /* Set vector address in CP15 VBAR register */
63 ldr r0, =_start
64 mcr p15, 0, r0, c12, c0, 0 @Set VBAR
65 #endif
第 56 行,如果沒有定義 CONFIG_OMAP44XX 和 CONFIG_SPL_BUILD 的話條件成立,此處條件成立。
第 58 行讀取 CP15 中 c1 寄存器的值到 r0 寄存器中,根據(jù) 17.1.4 小節(jié)可知,這里是讀取 SCTLR 寄存器的值。
第 59 行,CR_V 在 arch/arm/include/asm/system.h 中有如下所示定義:
#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */
因此,第 59 行的目的就是清除 SCTLR 寄存器中的 bit13 , SCTLR 寄存器結(jié)構(gòu) 如下:
可以看出, bit13 為 V 位,此位是向量表控制位,當為 0 的時候向量表基地址為 0X00000000 ,軟件可以重定位向量表。為 1 的時候向量表基地址為 0XFFFF0000 ,軟件不能 重定位向量表。這里將 V 清零,目的就是為了接下來的向量表重定位。
第 60 行將 r0 寄存器的值重寫寫入到寄存器 SCTLR 中。
第 63 行設(shè)置 r0 寄存器的值為 _start , _start 就是整個 uboot 的入口地址,其值為 0X87800000 , 相當于 uboot 的起始地址,因此 0x87800000 也是向量表的起始地址。
第 64 行將 r0 寄存器的值 ( 向量表值 ) 寫入到 CP15 的 c12 寄存器中,也就是 VBAR 寄存器。
因此,第 58~64 行就是設(shè)置向量表重定位的。
繼續(xù)分析 start.S 下面的代碼:
67 /* the mask ROM code should have PLL and others stable */
68 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
69 bl cpu_init_cp15
70 bl cpu_init_crit
71 #endif
72
73 bl _main
第 68 行如果沒有定義 CONFIG_SKIP_LOWLEVEL_INIT 的話條件成立。我們沒有定義
CONFIG_SKIP_LOWLEVEL_INIT ,因此條件成立,執(zhí)行下面的語句。
第 68 行~ 73行的內(nèi)容比較簡單,就是分別調(diào)用函數(shù) cpu_init_cp15 、 cpu_init_crit 和 _main 。
函數(shù) cpu_init_cp15 用來設(shè)置 CP15 相關(guān)的內(nèi)容,比如關(guān)閉 MMU 啥的,此函數(shù)同樣在 start.S
文件中定義的??梢宰孕胁榭?#xff0c; 函數(shù) cpu_init_cp15 都是一些和 CP15 有關(guān)的內(nèi)容,我們不用關(guān)心,有興趣的可以詳細的看 一下。
函數(shù) cpu_init_crit 也在是定義在 start.S 文件中,函數(shù)內(nèi)容如下:
268 ENTRY(cpu_init_crit)
269 /*
270 * Jump to board specific initialization...
271 * The Mask ROM will have already initialized
272 * basic memory. Go here to bump up clock rate and handle
273 * wake up conditions.
274 */
275 b lowlevel_init @ go setup pll,mux,memory
276 ENDPROC(cpu_init_crit)
可以看出函數(shù) cpu_init_crit 內(nèi)部僅僅是調(diào)用了函數(shù) lowlevel_init ,接下來就是詳細的分析一
下 lowlevel_init 和 _main 這兩個函數(shù)。