U-Boot启动机制总结笔记


1 I.MX6ULL启动方式

1.1 启动方式选择

  芯片上电后根据BOOT_MODE[1:0]的设置来选择 BOOT 方式。BOOT_MODE1 和 BOOT_MODE0 这两 IO,BOOT 模式配置如下表:

在这里插入图片描述

图1.1 boot模式配置表

  启动模式选择完成后,还要选择启动设备,如SD卡,EMMC,NANDFLASH等,启动设备是通过BOOT_CFG1[7:0]、 BOOT_CFG2[7:0]和 BOOT_CFG4[7:0]这 24 个配置 IO,但实际上我们只用到BOOT_CFG2[3]和BOOT_CFG1[3]~BOOT_CFG1[7]。

1.2 内部BOOT模式启动流程

  首先要区分“存储地址”和“运行地址”两个概念,“存储地址”就是可执行文件存储在哪里,可执行文件的存储地址可以随意选择。“运行地址”就是代码运行的时候所处的地址。也就是说,我们编译好的程序放在任意存储介质中,然后通过内部BOOT将编译好的程序拷贝到我们指定的运行地址上,然后单片机就可以从该运行地址上执行程序。
  在此模式下,芯片会执行内部的 boot ROM 代码,这段 boot ROM 代码会进行硬件初始化(一部分外设),然后从 boot 设备(就是存放代码的设备、比如 SD/EMMC、 NAND)中将代码拷贝出来复制到指定的 RAM 中,一般是 DDR。

1.3 镜像烧写

  使用 imxdownload 这个软件将 led.bin 烧写到了 SD 卡中。imxdownload 会在 led.bin前面添加一些头信息,重新生成一个叫做 load.imx 的文件,最终实际烧写的是 laod.imx。
  学习 STM32 的时候我们可以直接将编译生成的.bin 文件烧写到 STM32 内部 flash 里面,但是 I.MX6U 不能直接烧写编译生成的.bin 文件,我们需要在.bin 文件前面添加一些头信息构成满足 I.MX6U 需求的最终可烧写文件,I.MX6U 的最终可烧写文件组成如下:

  1. Image vector table,简称 IVT,IVT里面包含了一系列的地址信息,比如入口地址(链接地址),DCD地址,Boot data地址,IVT复制到DDR中以后的地址。这些地址信息在ROM中按照固定的地址存放着。且这些地址信息是相对链接地址来说。
  2. Boot data,启动数据,包含了镜像要拷贝到哪个地址,拷贝的大小是多少等等。
  3. Device configuration data,简称 DCD,设备配置信息,重点是 DDR3 的初始化配置。
  4. 用户代码可执行文件,比如led.bin。

  可以看出最终烧写到 I.MX6U 中的程序其组成为:IVT+Boot data+DCD+.bin。整个头部信息大小为4KB,但是load.imx是要先偏移1KB再存入进去,所以load.imx的头部信息实际大小为3KB。需要注意的是,内部 Boot ROM 会将 load.imx中的.bin代码拷贝到DDR中0X87800000这个地址,而这个load.imx中的头部信息将会存放在0X87800000这个地址前3KB的存储空间内。
  IVT里面存放了头部信息各个数据段的起始地址,如IVT的起始地址,Boot data的起始地址,DCD的起始地址,bin的起始地址。Boot data里存放了load.imx的起始地址,这个地址加上了最开始的1KB偏移大小。还存放了整个镜像的大小,最大为2MB。DCD里面存放了用来初始化外设的数据,如开启某些外设时钟,初始化DDR等等。

2 S5PV210启动方式

2.1 S3C6410启动机制

  S5PV210启动机制很怪,为了搞懂里面的机制,得先去了解S3C6410的机制。

在这里插入图片描述

图2.1 S3C6410启动流程

  上电过后,S3C6410会启动iROM里面的程序,这个程序主要做两件事情,第一是初始化时钟,看门狗等事情,第二是把SD卡或者FLASH中头4K的内容(也就是BL1)加载到片内RAM中运行。但是这4K内容很小,干不了什么事情,只会做一些很简单的配置,主要是用来配置好DDR的主存。配置好主存后再把uboot的剩下大部分内容(也就是BL2)加载到DDR中,然后再把程序的入口跳转到BL2去运行,然后BL2会把SD卡或者FLASH中的OS加载到DDR中,再把程序入口跳转到OS处运行,这样就完成了整个bootloader的过程。
  其中需要注意的细节是,在上电过后,iROM会把头4K的内容加载到片内RAM中运行,然后头4K的内容会判断一下,自己是在静态SRAM中还是在动态DDR中,如果是在静态内存中,它就会去配置DDR主存,然后把整个bootloader加载到DDR主存中,然后再跳到uboot入口运行,这个uboot也先做一件事情,判断自己是在静态内存中还是在动态内存中,如果是在动态内存中,就直接跳转到4K以后的内容运行,然后再把OS内容加载到主存中,然后把程序指针跳转到OS入口处。

  注:为什么需要判定自己是在静态SRAM中还是动态DDR中?原因如下:
  原因1:BL1(uboot的前一部分)在SRAM中有一份,在DDR中也有一份,因此如果是冷启动那么当前代码应该是在SRAM中运行的BL1,如果是低功耗状态的复位这时候应该就是在DDR中运行的。
  原因2:我们判定当前运行代码的地址是有用的,可以指导后面代码的运行。譬如在lowlevel_init.S中判定当前代码的运行地址,就是为了确定要不要执行时钟初始化和初始化DDR的代码。如果当前代码是在SRAM中,说明冷启动,那么时钟和DDR都需要初始化;如果当前代码是在DDR中,那么说明是热启动则时钟和DDR都不用再次初始化。

2.2 S5PV210启动机制

在这里插入图片描述

图2.2 S5PV210启动流程

  和S3C6410相比S5PV210主要做了两部分改进,第一个增加了片内iROM的大小,把一些固件的函数做了进去,比如读取mmc的函数或者读取flash的函数都放在里面了。第二个是增加了片内SRAM的大小,本来三星是出于好意,是想在BL1加载到片内SRAM以后能将整个bootloader也就是BL2同样加载到片内SRAM中运行,这样就不会局限在头4K或者头16K地址了,能在BL2中从容不迫的去配置SDRAM和一些初始化操作,再接着把整个OS加载到SDRAM中去运行。但是uboot编译下来有200多K,片内SRAM根部装不下,所以uboot设计者重新搞了一套东西,uboot设计者直接把uboot做成了两个镜像,一个叫ubootspl.bin,这个镜像很小只有16K,余下的部分大概210K左右仍然叫做uboot.bin。上电以后,先自动把小的ubootspl.bin加载到片内SRAM中去运行,然后绕开了BL2,直接去配置DDR内存,然后再把210K主体的部分加载到DDR中,然后直接跳转到主体的uboot.bin中开始运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

努力一点,幸运一点

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

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

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

打赏作者

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

抵扣说明:

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

余额充值