uboot源码--第二阶段

在start.s代码的414行跳转到start_armboot函数

start_armboot函数简介

一个很长的函数
(1)这个函数在uboot/lib_arm/board.c的第444行到908行结束
(2)450行还不是全部,里面还调用了别的函数
(3)这个函数整体构成了uboot启动的第二阶段
一个函数组成uboot的第二阶段
(1)uboot的第一阶段主要就是初始化了Soc内部的一些部件(譬如看门狗,系统时钟),然后初始化DDR并且完成重定位。
(2)宏观来说,uboot的第二阶段就是要初始化剩下的还没被初始化的硬件。主要是Soc外部硬件(譬如iNand,忘啦芯片)。最终初始化完必要的东西后进入uboot的命令行尊卑接收命令
uboot第二阶段完结何处?
(1)uboot启动后自动运行打印出来的信息(这些信息就是uboot在第一和第二阶段不断进行初始化时,打印出来的信息)。然后uboot进入了倒数bootdelay,然后执行bootcmd对应的启动命令
(2)如果用户没有干涉则会执行bootcmd进入自动启动内核流程(uboot就死掉了);此时用户可以按下回车键大端uboot的自动启动进入uboot的命令行下。然后uboot就一直工作在命令行下。
(3)uboot的命令行就是一个死循环,循环体内不断重复:接收命令,解析命令,执行命令

start_armboot函数源码解析

在开头发现的init_fnc_t
init_fnc_t
(1)typedef int (init_fnc_t) (void);这是一个函数类型
(2)init_fnc_ptr,这是一二重指针。二重指针的作用(其中一个指向一个一重指针,或者一个是指向一个数组)
gd_t
(1)在start_armboot的465行,定义了一个gd_t,查找gd_t,发现是在DECLARE_GLOBAL_DATA_PTR宏中,

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

这个宏定义了一个全局变量,名字叫gd,这个全局变量是一个指针类型,占4字节。用volatile 修饰,代表是可变的,register 修饰,代表是用寄存器去执行,速度更快。asm (“r8”)是gcc支持的语法,意思是要把gd放到寄存器r8中。
(2)综合分析,DECLARE_GLOBAL_DATA_PTR就是定义了一个要放在寄存器r8中的全局变量,名字叫gd,类型是一个指向gd_s类型变量的指针。
(3)为什么要定义为register?因为这个全局变量gd(global data的简称)是uboot中很重要的一个全局变量(准确的说这个全局变量是一个结构体,里面有很多内容,这些内容加起来构成的结构体即使uboot中常用的所有的全局变量),这个gd在程序中经常被访问,因此放在register中提升效率。因此纯粹是运行效率方面考虑,和功能要求无关。
(4)在global data这个结构体中,

	bd_t		*bd;	//bd_t,这个又定义了变量,这里面存的是我们开发板的硬件信息
	unsigned long	flags;		//存的是我们的一些标志位的
	unsigned long	baudrate;	//存的是我们的控制台波特率的
	unsigned long	have_console;	/* serial_init() was called */
	unsigned long	reloc_off;	/* Relocation Offset */
	unsigned long	env_addr;	/* Address  of Environment struct */
	unsigned long	env_valid;	/* Checksum of Environment valid? */
	unsigned long	fb_base;	/* base address of frame buffer */

(5)下面是在bd这个结构体中的代码,定义在inlcude/asm-arm/global_data.h中

 	int			bi_baudrate;	/* 我们开发板的波特率 */
    unsigned long	bi_ip_addr;	/* 板子的IP地址 */
    unsigned char	bi_enetaddr[6]; /* Ethernet adress */
    struct environment_s	       *bi_env;		//环境变量的指针
    ulong	        bi_arch_number;	/* 板子的机器码 */
    ulong	        bi_boot_params;	/* 启动参数的地址 */
    struct				/* RAM configuration */
    {
   
		ulong start;
		ulong size;
    }			bi_dram[CONFIG_NR_DRAM_BANKS];//板子的地址从什么地方开始,有多大,这里告诉的

总结:gd中定义了很多的全局变量,整个uboot使用的;其中有一个bd_t类型的指针,执行一个bd_t类型的变量,这个bd是开发板的板级信息的结构体,里面有不少硬件相关的参数,譬如波特率,IP地址,机器码,DDR内存分布。
从469行开始对gd分配内存

内存使用排布

为什么要分配内存
(1)DECLARE_GLOBAL_DATA_PTR 只是定义了一个指针,也就是说gd里的这些全局变量并没有分配内存,我们在使用gd之前要给他分配内存,否则gd也只是一个野指针。
(2)gd和bd需要内存,内存当前没有被人管理(因为没有操作系统同一管理内存),大片的DDR内存散放着可以随意使用(只要使用内存地址直接去访问内存即可)。但是因为uboot中后续很多操作还需要大片的连着内存,采用紧凑排布的原则
内存排布

UBOOT区 CFG_UBOOT_BASE-XX(长度为uboot的实际长度)
堆区 长度为CFG_MALLOC_LEN ,实际为912kb
栈区 长度为CFG_STACK_SIZE ,实际为512KB
gd 长度为sizeof(gd_t),实际为36字节
bd 长度为sizeof(bd-t),实际为44字节左右
内存间隔 是为了避免gcc的优化,导致程序错误
gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t);//计算我们的基地址的值
#ifdef CONFIG_USE_IRQ
	gd_base -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);
#
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值