Linux系統移植⑤:uboot啟動流程詳解-board_init_f執行過程
_main 中會調用 board_init_f 函數。
board_init_f 函數主要有兩個工作:
①初始化一系列外設,比如串口、定時器,或者打印一些消息等。
②初始化 gd 的各個成員變量, uboot 會將自己重定位到 DRAM 最后面的地址區域,也就是將自己拷貝到 DRAM 最后面的內存區域中。
board_init_f源碼如下:
其中重點為initcall_run_list函數,其運行初始化序列 init_sequence_f 里面的一些列函數, init_sequence_f 里面包含了一系列的初始化函數, init_sequence_f 也是定義在文件common/board_f.c 中,其中存在大量條件編譯函數,用于判斷是否執行。
init_sequence_f列表中包含了大量初始化函數,以下給出部分主要函數介紹
在setup_mon_len函數中計算了mon_len的長度,由于設備是ARM因此其計算規則如圖:
gd->mon_len的值實際上是U-Boot鏡像在內存中的實際占用大小也就是zImage的大小
initf_malloc 函數初始化 gd 中跟 malloc 有關的成員變量,比如 malloc_limit,此函數會設置 gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN=0X400。 malloc_limit 表示 malloc內存池大小。
(剩下部分函數僅做介紹不再查看其源碼)
get_clocks 函數:用于獲取一些時鐘值, I.MX6ULL 獲取的是 sdhc_clk 時鐘,也就是 SD 卡外設的時鐘。
env_init 函數:是和環境變量有關的,設置 gd 的成員變量 env_addr,也就是環境變量的保存地址。
init_baud_rate函數:用于初始化波特率,根據環境變量 baudrate 來初始化 gd->baudrate。
serial_init函數:初始化串口。
console_init_f函數:設置 gd->have_console 為 1,表示有個控制臺,此函數也將前面暫存在緩沖區中的數據通過控制臺打印出來。
display_options函數:通過串口輸出一些信息。
display_text_info函數:打印一些文本信息,如果開啟 UBOOT 的 DEBUG 功能的話就會輸出 text_base、 bss_start、 bss_end。
print_cpuinfo 函數:用于打印 CPU 信息。
show_board_info 函數:用于打印板子信息,會調用 checkboard 函數。
init_func_i2c 函數:用于初始化 I2C。
post_init_f函數:此函數用來完成一些測試,初始化 gd->post_init_f_time。
reserve_uboot函數: 留出重定位后的 uboot 所占用的內存區域, uboot 所占用大小由gd->mon_len 所指定,留出 uboot 的空間以后還要對 gd->relocaddr 做 4K 字節對齊,并且重新設置 gd->start_addr_sp
reserve_malloc函數:留出 malloc 區域,調整 gd->start_addr_sp 位置, malloc 區域由宏TOTAL_MALLOC_LEN 定義
reserve_board 函數:留出板子 bd 所占的內存區, bd 是結構體 bd_t, bd_t 大小為80 字節。
reserve_global_data 函數:保留出 gd_t 的內存區域, gd_t 結構體大小為 248B。
reserve_fdt函數:留出設備樹相關的內存區域。
reserve_stacks函數:留出棧空間,先對 gd->start_addr_sp 減去 16,然后做 16 字節對齊。如果使能 IRQ 的話還要留出 IRQ 相應的內存,具體工作是由 arch/arm/lib/stack.c 文件中的函數 arch_reserve_stacks 完成。
setup_dram_config 函數:設置 dram 信息,就是設置 gd->bd->bi_dram[0].start 和gd->bd->bi_dram[0].size,后面會傳遞給 linux 內核,告訴 linux DRAM 的起始地址和大小。
display_new_sp 函數:顯示新的 sp 位置,也就是 gd->start_addr_sp,不過要定義宏 DEBUG。
setup_reloc函數:設置 gd 的其他一些成員變量,供后面重定位的時候使用,并且將以前的 gd 拷貝到 gd->new_gd 處。需要使能 DEBUG 才能看到相應的信息輸出。
至此, board_init_f 函數就執行完成了。
其最終的內存分配圖如下: