u-boot之start_armboot分析(一)

  • 略过所有没有定义的宏定义
  • 这是uboot第二阶段的入口函数
  • 函数位于lib_arm/board.c

DECLARE_GLOBAL_DATA_PTR

#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")
  • 定义了一个要放到寄存器r8中的全局变量,名字叫gd,类型是一个指向gd_t类型变量的指针。
  • gd_t在include/asm-arm/global_data.h中定义,内容如下
typedef	struct	global_data {
	bd_t		*bd;
	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 */
#ifdef CONFIG_VFD
	unsigned char	vfd_type;	/* display type */
#endif
	void		**jt;		/* jump table */
} gd_t;
  • 这就是板子的一些配置文件。
  • bd->bi_arch_number是板子的机器码
  • bd->bi_boot_params是传给linux的启动参数的地址

内存分布

#ifdef CONFIG_MEMORY_UPPER_CODE
	ulong gd_base;
	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);
#endif  //CONFIG_USE_IRQ
	gd = (gd_t*)gd_base;
#else  //CONFIG_MEMORY_UPPER_CODE
	gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
#endif //CONFIG_MEMORY_UPPER_CODE
	/* compiler optimization barrier needed for GCC >= 3.4 */
	__asm__ __volatile__("": : :"memory");

	memset ((void*)gd, 0, sizeof (gd_t));
	gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
	memset (gd->bd, 0, sizeof (bd_t));
  • 只有第一次定义的gd_base对我们来说是有效的
  • 变量gd_base指的gd在DDR中分配内存的起始地址
  • gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t)最后的结果是0xc3e00000+(2x1024x1024) - 912*1024 - 512*1024 - 36 = 0xc3e9bfdc
  • 直接将gd_base赋值给全局变量的gd
  • gd->bd在gd往下sizeof(bd_t)的位置
  • 结合uboot启动第一阶段最后一次sp指针的设置,最后的内存结构如下
    在这里插入图片描述

硬件初始化

monitor_flash_len = _bss_start - _armboot_start;

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
	if ((*init_fnc_ptr)() != 0) {
		hang ();
	}
}
  • 为全局变量monitor_flash_len赋值
  • init_fnc_ptr的定义为init_fnc_t **init_fnc_ptr,而init_func_t的定义为typedef int (init_fnc_t) (void);这表明init_func_t是一个接收参数是void而返回值是int的函数类型
  • init_sequence里定义了一系列函数,此代码的功能就是执行这里面的初始化函数,如果有任何一个返回的函数返回值不为0,则串口输出### ERROR ### Please RESET the board ###,然后进入死循环
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贱贱的剑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值