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结构体中的信息来设置标记列表。

猜你喜欢

转载自blog.csdn.net/wmdshhzsmile/article/details/84134976