完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
tiny210上uboot启动分析 一、 配置与使用 1、在系统根目录下的Makefile中的第601行,通过下列语句: sinclude$(obj).boards.depend $(obj).boards.depend: boards.cfg awk'(NF && $$1 !~ /^#/) { print $$1 ": " $$1 "_config;$$(MAKE)" }' $< > $@ 读取了boards.cfgboards.cfg中关于tiny210_onfig的配置项,其中.boards.depend是隐藏文件; 2、在Makefile的106行添加: + ifeq($(ARCH), arm) + CROSS_COMPILE= arm-none-linux-gnueabi- + endif 这样配置好默认的交叉编译器; 3、在uboot顶层根目录下执行: $make tiny210_config $make 经过编译即可在根目录得到tiny210-uboot.bin,可用于SD卡启动和NAND启动; 4、将uboot烧入SD卡的时候使用下面命令: dd iflag=dsync oflag=dsync if=tiny210-uboot.bin of=/dev/sdb seek=1 注:dd命令用于对SD进行烧写将tiny210-uboot.bin烧写到,SD卡的第一个Block,保留第0个block不用,每个block=512B。,根据三星手册《S5PV210_iROM_ApplicationNote_Preliminary_20091126》当从SD启动时出厂固化的代码会从SD的第1个block取出要运行的代码 5、从SD卡启动后可以就使用uboot命令可以将本身烧写到nand里: $tftp 21000000 tiny210-uboot.bin $nand erase 0 40000 $nand write 21000000 0 40000 二、启动流程分析 按照三星《S5PV210_UM_REV1.1》手册上说明的启动流程,S5PV210上电将从IROM处执行固化的启动代码,对看门狗、中断控制器、系统时钟等初始化、再通过OM引脚判断启动设备,进而调用不同的函数从启动设备中复制BL1(最大16KB)到IRAM(0xd002_0000处,其中0xd002_0010之前的16个字节储存BL1的校验信息和BL1尺寸)中,并对BL1进行校验,校验OK转入BL1进行执行;BL1阶段会继续初始化,并将BL2复制到IRAM中并对其校验,OK后转入BL2;BL2则要进行比较复杂的初始化,包括DRAM的初始化,完成后将OS代码复制到DRAM中,并转入到OS中执行并完成启动引导。 但是,上述的IRAM只有96K大小,对于日益复杂的uboot来说,肯定是不够的,所以使用UBOOT启动引导的时候,并没全按三星手册上说的执行,具体如下: BL0:是指S5PV210的IROM中固化的启动代码; BL1:是指在IRAM中执行的UBOOT的部分代码; BL2:是指在内存中执行的的UBOOT的完整代码; UBOOT其实会编译两个UBOOT.bin,即最终生成的tiny210-uboot.bin包括两部分,前段是spl文件夹内的tiny210-spl.bin,后段是用于在RAM中执行的完整UBOOT代码。所以学习UBOOT代码是也要两个部分来看。 1、第一步与三星手册上一致,执行IROM内固化的代码,即执行BL0,它会将存储于启动设备的UBOOT代码的前16KB:tiny210-spl.bin复制到IRAM。然后跳转到IRAM执行BL1,实际就是执行tiny210-spl.bin。在UBOOT的代码中并不没有将tiny210-spl.bin和完整的UBOOT代码分开两套文件进行编写,都在同样的文件中,只是通过宏定义来控制执行流程,spl文件夹内有自己的Makefile文件。 2、第一步入口程序是/arch/arm/cpu/armv7/start.S中的_start,设置异常向量地址(地址由ARM 架构决定,不能改变),执行reset,进入SVC32模式,并调用cpu_init_crit对ARM的CP15寄存器进行设置,如清空TLB,关闭MMU等,进入/board/samsung/tiny210/lowlevel_init.S中的lowlevel_init中,进行低级初始化,主要是对时钟、内存、串口、nand等进行初始化,为下一步的代码拷贝做准备。 3、从lowlevel_init出来之后执行call_board_init_f,通过读取OMR_OFFSET寄存器的值,对启动设备进行判断,看看是从mmc启动还是nand启动,判断好后跳入mmc_boot.c或nand_cp.c中,将UBOOT代码拷贝到内存中。(注:在跳转到内存中执行之前,所有的语句都是基于PC寻址的,也就是说和代码具体存放的地址没有关系,都使用的是位置无关码,进行跳转的时候都会计算相对位移再跳转过去)拷贝完成后直接转到地址0x23E0_0000处开始执行。 无论是MMC启动还是NAND启动,将代码复制到DRAM中并跳转之后,执行的是DRAM中的_start入口函数,重新执行一遍UBOOT,但是一些宏定义已经发生变化,如CONFIG_SPL_BUILD被取消定义,相应的代码也不会执行。 4、因为第一编执行UBOOT的时候ARM的状态都已经初始化OK了,包括时钟,内存等,第二遍执行时只是跳转到内存中执行了,所以这里判断是否在DRAM中执行,如果在内存中执行,则可以直接跳到call_board_init_f去进行板级初始化。 5 、进入board_init_f以后将: a、对gd_t数据结构(include/asm/global_data.h中定义)进行初始化,并填入相关数据,如内存大小、UBOOT镜像长度等; b、打印CPU信息、UBOOT版本信息等,并对串口、console进一步初始化,输出nand信息,对内存大小进行计算,并打印出来。 c、为UBOOT的重定向设置物理地址,重定向后UBOOT可使用的end地址为0x3fff_0000,UBOOT镜像起始地址为0x3ff8_5000 6、完成board_init_f中的处理后,转入start.S中的relocate_code函数进行代码搬运及重定向。搬运完成之后,清空BSS后转入board.c中的board_init_r函数执行。 7、在board_init_r中,会清空malloc()区的内存,对nand、MMC等进行初始化,执行env_relocate()对环境变量进行初始化(第6步中的问题不知道是不是由于这个函数没有处理好引起的,研究了半天也没发现问题),如果将环境变量保存在NAND中,则会将其读入到内存中来。如果出现什么问题的话,就使用默认的环境变量代替。此步还会对网络、中断等进行初始化。全部初始化完成之后则跳入/common/main.c中的main_loop()中执行,等待用户命令或自动加载内核。 三、 总结 本文对S5PV210平台uboot的启动流程做了简要的分析,只是初步了解了一下UBOOT的启动流程,uboot中还有其他很多丰富的知识,比如MMC、nand、LCD等的驱动程序,将来有时间进一步分析。 |
|
相关推荐
|
|
590 浏览 0 评论
AI模型部署边缘设备的奇妙之旅:如何在边缘端部署OpenCV
2241 浏览 0 评论
tms320280021 adc采样波形,为什么adc采样频率上来波形就不好了?
1233 浏览 0 评论
1788 浏览 0 评论
1464 浏览 0 评论
74811 浏览 21 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 22:55 , Processed in 0.565560 second(s), Total 65, Slave 47 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号