历史上的今天
返回首页

历史上的今天

今天是:2025年02月23日(星期日)

正在发生

2021年02月23日 | cortex-a8 uboot系列:第九章 uboot源码分析5-启动第二阶段

2021-02-23 来源:eefocus

一、start_armboot 4 解析

1. DATAFLASH初始化

clip_image002

CONFIG_HAS_DATAFLASH为串行接口的FLASH,如spi接口的FLASH或者IIC接口的FLASH。小容量的FLASH芯片。但是x210没有这个东西,这部分代码不执行。


2.环境变量设置

clip_image004

环境变量的初始化,这里是对环境变量的重定位,将SD/MMC的环境变量读取到DDR中。

 

clip_image006

ENV_IS_EMBEDDED表示环境变量是内嵌到设备内部(也就是环境变量时内嵌到text段中)。该宏在程序中没有被定义。因此下面的代码是没有被执行的。

clip_image008

在gd_t结构体中,有reloc_off变量,因为环境变量是内嵌在text段中的,所以这个变量指环境变量在相对于text段中首地址的偏移量。

clip_image010

env_ptr是第一个环境变量的地址。

clip_image012

 

clip_image014

这段代码是被执行的,为环境变量使用malloc分配CFG_ENV_SIZE大小(16K)的内存区域。分配了后,env_ptr就指向DDR中环境变量的首地址。

 

SD卡中有一些独立的扇区作为环境变量存储区域的。但是在烧录/部署系统时,只是烧录了uboot分区、kernel分区和rootfs分区,根本没有烧录env分区。当烧录完系统第一次启动时ENV分区是空的,本次uboot启动尝试去SD卡的ENV分区读取环境变量失败(读取回来后进行CRC校验时失败),uboot选择从uboot内部代码中设置的一套默认的环境变量用来使用(默认环境变量)。这套默认的环境变量在本次运行时会被读取到DDR中的环境变量中,然后被写入(可能是uboot自动写入,也可能是输入命令save写入)SD卡的ENV分区。下次再次启动时,uboot就会从SD卡的ENV分区读取环境变量到DDR中,读取就不会失败了。

clip_image016

Set_default_env(common/env_common.c),就是设置默认的环境变量,将默认的环境变量的值拷贝到DDR中的环境变量中。

clip_image018

 

当第二次启动的时候,执行env_relocate_spec函数(common/env_movi.c)

clip_image020

clip_image022

因为没有定义ENV_IS_EMBEDDED宏,所以这里什么都没有执行。这里是当环境变量是嵌入到text段中的话,从外部SD/MMC卡中读取环境变量的值,然后进行CRC判断。

virt_to_phys是虚拟地址转物理地址的函数。

movi_read_env(common/env_movi.c)是从外部MMC设备读取环境变量到DDR中。实际上是调用movi_read函数(drivers/mmc/mmc.c)。

clip_image024

 

最后将全局变量gd的环境变量指向内存中的环境变量首地址。这样,以后通过gd->env_addr参数,就可以获知环境变量。

clip_image026

3.P地址初始化

clip_image028

获取IP地址,使用getenv_IPaddr函数(net/net.c)从环境变量的ipaddr获取。

getenv函数(common/cmd_nvedit.c)就是获取环境变量的值(字符串形式),使用string_to_ip函数(net/net.c)

clip_image030

IPaddr_t就是一个ulong类型的别名。

clip_image032

使用string_to_ip函数(net/net.c)将IP形式的字符串转化为ulong型。

clip_image034

如,对于192.168.0.1。 转化之后的结果为

C0

A8

00

01

192的十六进制

168的十六进制

0的十六进制

1的十六进制

         所以addr = 0xc0a80001。

         使用htonl函数将addr转化为网络字节序。

 

         IP地址由4个0-255之间的数字组成,因此一个IP地址在程序中最简单的存储方法就是一个unsigned int。但是这种对于我们不易读,使用点分十进制类型(192.168.0.1),两种方式可以相互转化。


         在计算机中,使用IPaddr_t类型来存储IP地址,以节省空间。而对于我们,使用点分十进制类型来表示。所以在存储的时候,要进行转化,将点分十进制类型转化为IPaddr_t类型保存,显示的时候要将IPaddr_t类型转化为点分十进制类型。


4.物理网卡设置

         clip_image036

设置网卡物理地址。    

通过getenv_r函数获取ethaddr环境变量的值,保存在tmp数组中。然后通过处理,将变量的值写入到gd->bd->bi_enetaddr数组变量中。


没有使用第二块网卡,所以CONFIG_HAS_ETH1宏没有定义,对第二块网卡的物理地址就没有设置。


5.设备初始化

clip_image038

设备的初始化。这里的设备指开发板上的硬件设备。这里的初始化设备都是驱动设备,这个函数是从驱动框架从衍生出了的。Uboot中很多设备的驱动是直接移植linux内核的(如网卡、SD卡),linux内核中的驱动都有相应的设备初始化函数。Linux内核在启动过程中就有一个devices_init函数,作用就是集中执行各种硬件驱动的init函数。


Uboot的这个函数其实就是从linux内核中移植过来,作用也是去执行所有的从linux内核中继承来的那些硬件驱动的初始化函数。

clip_image040

对设备创建列表,然后各自调用硬件的初始化。device_t是一个结构体,表征所有的设备。

clip_image042

clip_image044

jumptable跳转表,本身是一个函数指针数组,里面记录了很多函数的函数名。应该是实现一个函数指针到具体函数的映射关系,将来通过跳转表中的函数指针就可以执行具体的函数。这个其实就是用C语言实现面向对象编程。Linux内核中有很多这种技巧。  

      

这个函数就是对gd中的jt变量赋值,不过赋值了之后没有被使用。因此在uboot中没有对jumptable进行使用。

clip_image046

6. 控制台初始化

clip_image048

控制台的第二阶段初始化。console_init_r是第二阶段初始化,console_init_f是第一阶段初始化。之前分析第一阶段没有做什么实质性工作。

console_init_r函数(common/console.c中)

clip_image050

对输入输出设备进行扫描。

clip_image052

设置输入输出设备。

clip_image054

判断输入输出设备是否设置正确。正确的话打印信息。所以在uboot启动信息可以看到上述打印信息。

clip_image055

所以console_init_r函数,做的事就是console纯软件架构方面的初始化(就是给console相关的数据结构中填充相应的值),所以属于纯软件配置类型的初始化。


Uboot的console实际上没有做有意义的转化,就是直接调用串口通信的函数。所以用不用console实际并没有什么分别。(linux中console可以提供缓冲机制等)。


7.中断设置

clip_image057

设置中断的使能,其实就是设置CPSR寄存器的I位。但是在这里是没有设置的。

clip_image059

因为uboot中没有使用中断,所以CONFIG_USE_IRQ宏是无定义的,所以enable_interrupts函数(cpu/s5pc11x/interrupts.c)就是一个空函数。


8.获取loadaddr,bootfile环境变量

clip_image061

获取两个环境变量值,这两个环境变量都是和内核启动有关的,在启动linux内核是会参考这两个环境变量的值。


9.board_late_init

clip_image063

board_late_init函数(board/samsung/x210/x210.c)是开发板级别的一些晚期初始化。此时说明开发板级别的硬件软件初始化结束了。

clip_image065

因为不满足预编译条件,所以这个函数是空的。

clip_image067

没有定义CONFIG_NET_MULTI宏,所以puts不被编译。


10.网卡初始化

clip_image069

网卡相关的初始化。eth_initialize函数(net/eth.c)。

这里不是soc的网卡控制器的初始化,而是外部网卡芯片本身的一些初始化。


对于x210(DM9000网卡)来说,这个函数是空的。X210的网卡控制器初始化在board_init函数中,网卡芯片的初始化在驱动中。

clip_image071

宏编译条件都不成立,该函数直接返回0。

 

clip_image073

对phy复位


11.IDE设备初始化

clip_image075

如果开发板有接IDE接口硬盘,对硬盘进行初始化。

12.LCD初始化

clip_image077

声明x210_preboot_init(board/samsung/x210/x210.c)为外部函数,这里直接调用该函数。

clip_image079

而这个函数又是去调用了一个外部函数mpadfb_init(drivers/video/mpadfb.c)

clip_image081

对LCD进行初始化,并将logo显示在LCD上。

fb_init函数(drivers/video/mpadfb.c),对显存设置

lcd_port_init函数(drivers/video/mpadfb.c),对LCD的port设置

lcd_reg_init函数(drivers/video/mpadfb.c),对LCD控制器的内部寄存器设置

display_logo函数(drivers/video/logo.c),将指定的log图片信息保存到显存中,从而LCD显示图片。


13.自动升级

clip_image083

Uboot启动的最后阶段,设计了自动更新的功能。就是:可以将要升级的镜像放到SD卡的固定目录中,然后开机时,在uboot启动的最后阶段检查升级标志(是一个按键,按键中标志为“LEFT“的按键,这个按键如果按下则表示update mode,如启动时未按下则表示boot mode)。如果进入了update mode则uboot会自动从SD卡中读取镜像文件然后烧录到iNand中;如果进入了boot mode则uboot不执行update,直接启动正常运行

这种机制能够帮助我们快速烧录系统,常用于量产时用SD卡进行系统烧录部署。

14.进入main_loop

clip_image085

进入到了uboot中的命令模式下了。等待命令输入,然后解析命令,最后执行命令。


推荐阅读

史海拾趣

岑科(CENKER)公司的发展小趣事

岑科公司成立于2001年,初期主要从事电子元器件的贸易业务。在创始人蔡旌章的带领下,岑科以优质的服务和灵活的运营策略,在国内外市场上赢得了良好的口碑。这一时期,岑科的服务对象主要是海内外的电子元器件需求商,通过精准把握市场需求和优质的产品供应,逐渐在电子元器件贸易领域站稳了脚跟。随着业务的不断拓展,岑科开始思考如何进一步提升自身的竞争力,以实现更长远的发展。

BeagleBoard公司的发展小趣事

随着技术的不断进步,BeagleBoard公司始终保持着对创新的追求。他们不断研发新的技术,优化产品设计,推出了一系列具有创新性的产品。其中,BeagleBone Black是该公司的一款明星产品,它集成了高性能处理器、丰富的外设接口和强大的扩展能力,为开发者提供了更加便捷的开发体验。此外,公司还推出了工业宽温应用的变体,以满足不同领域的需求。

Capar Components Corp公司的发展小趣事

作为一家有社会责任感的企业,Capar Components Corp积极参与公益事业,回馈社会。公司定期组织员工参与社区服务活动,帮助困难群体解决实际问题。此外,公司还设立了奖学金和助学金,支持教育事业的发展。这些举措不仅彰显了公司的社会责任感,也为公司树立了良好的企业形象。


这些故事是基于一个虚构的电子行业公司背景编写的,您可以根据Capar Components Corp的实际情况进行调整和修改,以使其更符合该公司的历史和发展轨迹。请注意,由于我无法获取Capar Components Corp的具体信息,这些故事仅为示例性质,并非真实事件。

Gespac Inc公司的发展小趣事

在追求经济效益的同时,Capar Components Corp也注重环保和可持续发展。公司积极采用环保材料和生产工艺,减少生产过程中的污染排放。同时,公司还推出了一系列绿色电子产品,满足消费者对环保产品的需求。这些举措不仅提升了公司的社会形象,还为公司赢得了更多客户的青睐。

遨格芯微(AGM)公司的发展小趣事

遨格芯微(AGM)自2012年成立以来,始终致力于可编程逻辑技术的研发。经过数年的努力,AGM成功开发出具有自主知识产权的FPGA核心技术,并在FPGA编译软件和电路领域取得了先进和成熟的技术成果。2014年,AGM的PLD芯片成熟并开始在行业得到应用,这标志着AGM在可编程逻辑技术领域取得了重大突破。随后,AGM推出三个系列的CPLD、FPGA、Programmable SoC产品,并进入量产阶段,得到了包括三星在内的多家知名厂商的认证,为公司的进一步发展奠定了坚实基础。

DCD [Digital Core Design]公司的发展小趣事

在快速变化的市场环境中,创新成为DCD公司持续发展的关键。公司不断加大研发投入,鼓励员工提出创新性的想法和建议。同时,公司还积极引进国内外先进的技术和管理经验,为公司的发展注入了新的活力。在创新驱动下,DCD公司不断推出具有竞争力的新产品和解决方案,赢得了客户的广泛赞誉和市场的持续认可。

问答坊 | AI 解惑

CPLD的双向端口问题!毕设啊求助!

现在PCI数据线与CPLD相连,有一个功能是测速,首先用LAD0发一个控制信号,然后如入LAD[15..0]的数据。 由于LAD0需要双向,因此将LAD[15..0]都设为Bir(在顶层框图中)但是发现通过LAD0根本写入不了命令,不知为什么? 现在只能LAD0只作输入 其余1 ...…

查看全部问答>

请教WINCE动态库的问题

为什么PB编译的动态库通常要比EVC编译的动态库小一点呢?…

查看全部问答>

自制廉价的GPS外接天线

    有网友试过,效果确实不错:宿舍窗台上(11楼)不到20秒,显示了时间,再过几秒,就显示了经纬度,没调,就收到4颗心!!     材料: 同轴线 直径1mm的漆包线200mm以上 敷铜板:长:100mm; 宽:100mm; 敷铜条 ...…

查看全部问答>

电子产品总PCB的散热设计

PCB的热设计摘要:热分析、热设计是提高印制板热可靠性的重要措施.基于热设计的基本知识,讨论了PCB设计中散热方式的选择、热设计和热分析的技术措施.关键词:印制板;热设计;热分析  1、热设计的重要性  电子设备在工作期间所消 ...…

查看全部问答>

版主,咨询一个TIM分频的疑问

                                 APB主频是24MHz, timer 我想分频到100Hz。 但是分频寄存器是16位的,PSC无法一次分频到100Hz。如果不改变原APB主频 ...…

查看全部问答>

有没有人用过430读写sd卡呀?

不知道各位大虾有没有关于430读写sd卡方面的资料?小弟拜求了! Email:zwiceman@hotmail.com…

查看全部问答>

FPGA控制W5300

有没有大神做过这个项目呀,手头没什么资料,不知道从何下手。…

查看全部问答>

MSP430AFE221 读取SD24位极不稳定

本人最近在用AFE221,但是读取SD24的值很不稳定,后面有近16位的数在变动,这是为什么?望大家帮忙解决下,谢谢!…

查看全部问答>

急!!!〈德州仪器第三方员工招聘〉工作地点上海浦东(3个岗位)

新的一年开始啦,大神们是不是在看新机会呢!急招哦~~ TI 产品线亚太地区技术支持,主要负责TI 亚太区C2000/Interface/Power芯片的技术支持工作。 通过德州仪器平台邮件和论坛的回复,主要为亚太地区的研发工程师提供研发解决方案,包括产品选型 ...…

查看全部问答>