1. 程式人生 > >Uboot啟動過程原始碼分析之第二階段

Uboot啟動過程原始碼分析之第二階段

UBoot的最終目標是啟動核心
1.從Flash中讀出核心
2.啟動核心
通過呼叫lib_arm/board.c中的start_armboot函式進入uboot第二階段
第二階段總結圖
在這裡插入圖片描述

typedef	struct	global_data {
	bd_t		*bd;
	unsigned long	flags;
	unsigned long	baudrate;
	unsigned long	cpu_clk;	/* CPU clock in Hz!		*/
	unsigned long	have_console;	/* serial_init() was called */
	unsigned long	ram_size;	/* RAM size */
	unsigned long	reloc_off;	/* Relocation Offset */
	unsigned long	env_addr;	/* Address  of Environment struct */
	unsigned long	env_valid;	/* Checksum of Environment valid */
#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
	unsigned long	post_log_word;	/* Record POST activities */
	unsigned long	post_init_f_time; /* When post_init_f started */
#endif
	void		**jt;		/* Standalone app jump table */
} gd_t;

gd_t定義在include/asm-arm/global_data.h中。gd_t中定義了很多全域性變數,都是整個uboot使用的;其中有一個bd_t型別的指標,指向一個bd_t型別的變數,
這個bd是開發板的板級資訊的結構體,裡面有不少硬體相關的引數,譬如波特率、IP地址、機器碼(bi_arch_number)、uboot給kernel傳參時引數所在的地址(bi_boot_params),
DDR記憶體分佈(bi_dram)

#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")

定義了一個全域性變數名字叫gd,這個全域性變數是一個指標型別,佔4位元組。用volatile修飾表示可變的,用register修飾表示這個變數要儘量放到暫存器中,
後面的asm(“r8”)是gcc支援的一種語法,意思就是要把gd放到暫存器r8中。
為什麼要定義為register?
因為這個全域性變數gd(global data的簡稱)是uboot中很重要的一個全域性變數,這個gd在程式中經常被訪問,因此放在register中提升效率。因此純粹是執行效率方面考慮,和功能要求無關。並不是必須的。

DECLARE_GLOBAL_DATA_PTR只能定義了一個指標,也就是說gd裡的這些全域性變數並沒有被分配記憶體,我們在使用gd之前要給他分配記憶體,否則gd也只是一個野指標而已。gd和bd需要記憶體,記憶體當前沒有被人管理(因為沒有作業系統統一管理記憶體),大片的DDR記憶體散放著可以隨意使用(只要使用記憶體地址直接去訪問記憶體即可),在uboot中需要有一個整體規劃. 如下:

來源在這裡插入圖片描述
圖片來源
在這裡插入圖片描述

在這裡插入圖片描述

U-Boot啟動核心時要給核心傳遞引數,這時就要使用gd_t,bd_t結構體中的資訊來設定標記列表。