已經對board_init_f函式進行了簡單介紹,在這個函式當中,會呼叫一系列的函式去初始化一些早期的板子外設和gd結構體的成員變數,但是board_init_f函式並沒有將所有的外設進行初始化,還有一些後續的工作需要完成,這些工作就是由board_init_r函式去完成。
在介紹board_init_r函式之前,先來回憶一下_main函式的簡單呼叫流程,如下:
_main
|board_init_f_alloc_reserve--
>reserve gd and early malloc area
|board_init_f_init_reserve--
>initialize global data
|board_init_f--
>initialize ddr,timer...
,and fill gd_t
|relocate_code--
>relocate uboot code
|relocate_vectors--
>relocate vectors
|board_init_r--
>calling board_init_r
可以看到board_init_r函式處於_main函式的最後階段了,board_init_r函式的執行過程和board_init_f函式非常類似,因此,將會使用相同的方法對該函式過程進行分析。
在uboot原始碼中,board_init_r函式的定義在下面的檔案中:
uboot/common/board_r.c
函式的定義如下所示:
void
board_init_r
(gd_t *new_gd, ulong dest_addr)
和board_init_f函式類似,呼叫initcall_run_list()函式來進行初始化,init_sequence_r是乙個陣列,也就是函式初始化序列,為了相容多款板子,裡面包含了大量的條件編譯函式,將一些無關條件編譯**去掉後,其定義如下:
init_fnc_t init_sequence_r=
;
接下來,對init_sequence_r內定義的函式進行簡要分析:
首先是initr_trace()函式,該函式的定義如下:
static
intinitr_trace
(void
)
該函式中,如果定義了config_trace巨集的話,將呼叫trace_init()函式,是與初始化和除錯跟蹤相關的內容。
接下來,呼叫initr_reloc()函式,該函式定義如下:
static
intinitr_reloc
(void
)
initr_reloc函式設定了gd->flags成員,標記uboot重定位完成。
接下來,判斷是否定義了巨集config_arm,對於imx6ul定義了該巨集,將呼叫initr_caches()函式,該函式定義如下:
static
intinitr_caches
(void
)
從**可以知道,該函式用於使能晶元的caches。
接下來呼叫initr_reloc_global_data()函式用於初始化重定為後gd的一些成員變數。
對於imx6ul,initr_barrier()為空函式,直接返回。
bootstage_relocate()函式用於重定位bootstage相關的東西。
接下來,繼續呼叫initr_bootstage()函式,用於初始化bootstage相關的內容。
uboot/board/freescale/mx6ul_comp6ul_nand/mx6ul_comp6ul_nand.c
該函式的定義如下所示:
int
board_init
(void
)
從函式中可以看到,這是個板級初始化函式,主要是用來初始化了板子上的一些外設,例如gpio、i2c介面和網路相關介面等。
接下來,繼續呼叫stdio_init_tables()函式用於初始化stdio相關東西。
呼叫initr_serial()函式初始化串列埠相關東西。
呼叫initr_announce()函式,除錯相關的內容,用於通知已經在dram中執行。
繼續呼叫power_init_board()函式,用於初始化電源相關的晶元。
接下來,判斷有沒有定義巨集config_sys_no_flash,如果沒有定義該巨集的話,呼叫函式initr_flash(),但是對於imx6ul中,定義了該巨集,因此,該函式無效。
函式繼續執行,接下來,判斷是否定義了巨集config_cmd_nand,對於使用nand flash啟動的,將會定義該巨集,因此會呼叫initr_nand()函式初始化nand,該函式定義如下:
#ifdef config_cmd_nand
/* go init the nand */
static
intinitr_nand
(void
)#endif
函式執行後,會將nand flash進行初始化,並在串列埠以字串的形式輸出nand flash的大小。
接下來,判斷是否定義了config_generic_mmc巨集,對於imx6ul,該巨集定義在檔案:
uboot/include/imx6_common.h
因此,函式initr_mmc()會執行,用來初始化和sd/mmc相關的介面。
initr_env()函式用來初始化環境變數。
initr_secondary_cpu()用來初始化其它的cpu核,但是對於imx6ul只有乙個cpu核,因此此函式無效。
stdio_add_devices()函式用於初始化各種輸入輸出裝置,例如lcd相關的裝置。
initr_jumptable()函式用來初始化跳轉表相關的內容。
console_init_r()函式用於完成控制器臺的初始化,該函式呼叫後,uboot將輸出如下:
in: serial
out: serial
err: serial
board_late_init()函式用於板級後續的一些外設初始化。
接下來,呼叫函式initr_net()初始化板子上的網路裝置,該函式的定義如下:
#ifdef config_cmd_net
static
intinitr_net
(void
)#endif
需要定義相關巨集config_cmd_net才會呼叫該函式,如果初始化成功的話,串列埠會輸出對應的資訊。
最後,執行run_main_loop()函式,主迴圈函式,用於處理輸入的命令,該函式的實現過程分析另起文章分析。
本篇文章主要是對board_init_r()函式進行簡單分析,該函式用於板級後期的一些外設初始化和設定gd結構體的成員變數,函式的呼叫過程和board_init_f()函式類似。
imx6ull uboot 修改除錯串列埠1為串列埠3
board myir imx6ull y2 512 ddr 4gb emmc 總的來說,乙個board目錄下的c檔案,2個configs目錄下的 件。1.修改uboot原始碼下的include configs mx6 common.件 define config cons index 32.修改ub...
IMX6ULL啟動流程
假設板子設定為sd tf卡啟動,boot rom程式會做什麼?把程式從sd tf卡讀出來,執行。從 讀?從sd tf卡讀,這需要先初始化sd tf卡 根據efuse或gpio的設定初始化sd tf卡。讀到 去?讀到記憶體即ddr去,這需要先初始化ddr。除了初始化啟動裝置 初始化ddr,還需要初始化...
imx6q LINUX 啟動時間優化
1 u boot的優化 1 首先去掉無關緊要的串列埠資訊 2 將config bootdelay改為0 3 去掉一些不用的驅動,例如spi usb hdmi等等 4 關閉config cmd net 5 u boot會重複初始化mmc,修改do mmc dev 2 kernel的優化 1 首先開啟c...