嵌入式之uboot源码分析-启动第二阶段学习笔记(下篇)

本文详细介绍了UBoot启动第二阶段的学习笔记,包括CFG_NO_FLASH、VFD和LCD配置、内存分配、MMC初始化、环境变量重定位、IP和MAC地址处理、设备初始化、跳转表、控制台初始化、中断启用、board_late_init、网卡初始化、预启动初始化、自动更新功能以及主循环等关键步骤。文章深入探讨了各环节的代码功能和实现细节,如CRC校验、进制转换和函数指针映射。
摘要由CSDN通过智能技术生成

接上部分---->嵌入式之uboot源码分析-启动第二阶段学习笔记(上篇)

:如下内容来自朱老师物联网大讲堂uboot课件

3.2.14 CFG_NO_FLASH

在这里插入图片描述

(1)虽然NandFlash和NorFlash都是Flash,但是一般NandFlash会简称为Nand而不是Flash,一般讲Flash都是指的Norflash。这里2行代码是Norflash相关的。
(2)flash_init执行的是开发板中对应的NorFlash的初始化、display_flash_config打印的也是NorFlash的配置信息(Flash: 8 MB就是这里打印出来的)。但是实际上X210中是没有Norflash的。所以着两行代码是可以去掉的(我也不知道为什么没去掉?猜测原因有可能是去掉着两行代码会导致别的地方工作不正常,需要花时间去移植调试,然后移植的人就懒得弄。实际上不去掉除了显示有8MB Flash实际没用之外也没有别的影响)

代码实践:去掉Flash看会不会出错。
结论:加上CONFIG_NOFLASH宏之后编译出错,说明代码移植的不好,那个文件的包含没有被这个宏控制。于是乎移植的人就直接放这没管。

3.2.15 CONFIG_VFD和CONFIG_LCD

CONFIG_VFD和CONFIG_LCD是显示相关的,这个是uboot中自带的LCD显示的软件架构。但是实际上我们用LCD而没有使用uboot中设置的这套软件架构,我们自己在后面自己添加了一个LCD显示的部分。

3.2.16 mem_malloc_init
static void mem_malloc_init (ulong dest_addr)
{
   
	mem_malloc_start = dest_addr;
	mem_malloc_end = dest_addr + CFG_MALLOC_LEN;
	mem_malloc_brk = mem_malloc_start;

	memset ((void *) mem_malloc_start, 0,
			mem_malloc_end - mem_malloc_start);
}

#define CFG_MALLOC_LEN		(CFG_ENV_SIZE + 896*1024)

(1)mem_malloc_init函数用来初始化uboot的堆管理器。
(2)uboot中自己维护了一段堆内存,肯定自己就有一套代码来管理这个堆内存。有了这些东西uboot中你也可以malloc、free这套机制来申请内存和释放内存。我们在DDR内存中给堆预留了896KB的内存。

3.2.17 mmc_initialize

(1)从536到768行为开发板独有的初始化。意思是三星用一套uboot同时满足了好多个系列型号的开发板,然后在这里把不同开发板自己独有的一些初始化写到了这里。用#if条件编译配合CONFIG_xxx宏来选定特定的开发板。
(2)X210相关的配置在603行到629行。
(3)mmc_initialize看名字就应该是MMC相关的一些基础的初始化,其实就是用来初始化SoC内部的SD/MMC控制器的。函数在uboot/drivers/mmc/mmc.c里。
(4)uboot中对硬件的操作(譬如网卡、SD卡···)都是借用的linux内核中的驱动来实现的,uboot根目录底下有个drivers文件夹,这里面放的全都是从linux内核中移植过来的各种驱动源文件。
(5)mmc_initialize是具体硬件架构无关的一个MMC初始化函数,所有的使用了这套架构的代码都掉用这个函数来完成MMC的初始化。mmc_initialize中再调用board_mmc_init和cpu_mmc_init来完成具体的硬件的MMC控制器初始化工作。
(6)cpu_mmc_init在uboot/cpu/s5pc11x/cpu.c中,这里面又间接的调用了drivers/mmc/s3c_mmcxxx.c中的驱动代码来初始化硬件MMC控制器。这里面分层很多,分层的思想一定要有,否则完全就糊涂了。

  • 程序中出现了双链表的访问
3.2.18 env_relocate

1.判断我们是否是内嵌环境变量(我们这里ENV_IS_EMBEDDED有被宏定义),如果不是则使用malloc分配

#ifdef ENV_IS_EMBEDDED
	/*
	 * The environment buffer is embedded with the text segment,
	 * just relocate the environment pointer
	 */
	env_ptr = (env_t *)((ulong)env_ptr + gd->reloc_off);
	DEBUGF ("%s[%d] embedded ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
#else
	/*
	 * We must allocate a buffer for the environment
	 */
	env_ptr = (env_t *)malloc (CFG_ENV_SIZE);
	DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
#endif
  1. 如果环境变量是无效的,并且环境变量也不存在的就输出Warning,同时将环境变量设置为默认值,这里调用set_default_env()函数,实现将系统默认的环境变量复制到分配的env_ptr->data中,更新CRC,并将env_valid设为1 ,下次启动就可直接重定位了。
知识点:什么是CRC校验

CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
更多CRC相关请参考----->CRC校验原理及步骤

void set_default_env(void)
{
   
	if (sizeof(default_environment) >
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值