System Boot启动的分析

描述

Boot Mode

I.MX6ULL使用BOOT_MODE[1:0]两个寄存器来确定通电或者复位时的启动方式,下面这个表格列举了具体的四种启动方式:

寄存器Boot From Fuses: 从熔丝引导启动,这个启动与Internal Boot模式很像,但这种方式对于GPIO配置的启动参数无效,需要使用eFuses专用的配置进行引导。它的配置只能修改一次,后面就不能再修改了,所以这种方式基本不用。

Serial Downloader: 通过USB或者UART下载一个镜像引导程序到内部的RAM中启动。

Internal Boot: 从内部boot code启动。boot code是固定在SOC上面的一段代码,boot code还会对硬件进行初始化(如果初始化系统时钟频率)。根据BOOT_CFG的配置选择从启动设备进行启动,跳转到指定的镜像文件地址开始执行。如果在启动过程中遇到了错误,则会从Serial Downloader进行启动。

开发板开关电路图分析

下面这张图展示了开发板上面连接的具体引脚寄存器以BOOT_MODE0为例,管脚芯片内部接了一个100K的下拉电阻,默认状态是低电平(值0),当把开关拨到ON后电源接通,引脚通过一个10K的电阻接到了一个3.3V的电源,通过计算可得到引脚上分到了3V的电压为高电平,则引用值是1。

Internal Boot 配置

I.MX6ULL提供BOOT_MODE[1:0]与其它的24根LCD引脚共通组成了复杂的启动配置选项,但是在使用时能用到的只有其中少部分,其它大部分都是默认下拉接地(即值是0)不需要额外配置,如下图:寄存器其中BT_CFG4全部下拉接地了,这一组就忽略它。下面这张图给出了BT_CFG1BT_CFG2的配置与其功能:寄存器

BT_CFG2[4:3]: I.MX6ULL支持两个SD/eMMC,00是SD1/eMMC1,01是SD2/eMMC2。10与11是保留未使用,可见实际起作用的是BT_CFG2[3]这个引用的值决定了从哪一张SD卡启动。BT_CFG2[3]对应了I.MX6ULL手册中的LCD_DATA11引用。I.MX6ULL开发板上面0用于外接SDK卡,1用于板载的eMMC。

BOOT_CFG1[3]: 当从 SD/EMMC 启动的时候设置启动速度,当从 NAND 启动的话设置 NAND 数量。寄存器

BOOT_CFG1[7:4]的配置如下图:寄存器图中某些位是用x来表示的,即这个位不管是0还是1都是同等的启动效果。

更完整的详解表格如下图:寄存器

实例启动配置表:

启动方式 BOOT_MODE0 BOOT_MODE1 BOOT_CFG2[3] BOOT_CFG1[3] BOOT_CFG1[7:4]
USB 0 1 0 0 0000
SD 1 0 0 0 010x
eMMC 1 0 1 0 011x
NAND 1 0 0 0 100x

通过以上的配置可将指定具体的启动设备,如果了启动设备之后,boot code会从指定设备中读取镜像文件来执行。

镜像文件分析

I.MX6ULL使用的是小端模式,手册中使用大端模式的地方会特意说明。

通过对LED驱动实现最终烧写的load.mix文件得到如下图表:寄存器

IVT(Image Vector Table)

寄存器上面这个表格详细的描述了IVT+BOOT DATA+DCD在不同启动设备中的固定位置(相对设备起始地址的偏移量)以及从起始地址开始可用的初始化加载范围,SD/eMMC启动模式偏移量为1KB,整个初始化加载范围是4KB,则IVT+BOOT DATA+DCD可使用的范围是3KB。

寄存器

  • header: 描述了整个IVT
Tag Length Version
0xD1 0x0020(32) 0x40
  • entry: 0x87800000,bin文件第一条指令地址,这个地址是在DDR中的地址。
  • boot data: 0x877FF420,相对于IVT的起始地址: 0x877FF400偏移了32个字节。
  • dcd: 0x877FF42C,即dcd的数据在DDR中的地址。entry的地址是0x87800000,那可以计算(减去3KB: 0xC00)得到IVT的起始地址是: 0x877FF400。dcd的起始地址相对于IVT起始地址偏移了44个字节(ivt+boot data结构,即: 0x2C), IVT的地址加上0x2C得到dcd的地址是: 0x877FF42C。
BOOT DATA
  • start: 描述了整个load.mix(烧写到SD卡中的文件)的起始地址(在DDR中),包括了偏移的1KB,entry地址(链接起始地址)为:0x87800000 - 0x1000(4KB) = 0x877FF000。
  • length: 描述了整个load.mix的大小,在烧写的时候写入的是0x00200000,即2MB大小,整个镜像文件的大小不能超过2MB。
  • plugin: 0x00000000,没有插件设置成0
DCD(Device Configuration Data)

DCD数据的作用则是在boot code启动加载的时候对三件设备进行配置以及检查,通过配置寄存器的写入数据可快速高效的实现寄存器或者DDR的初始化。

  • header: 头部结构描述了整个DCD的长度
Tag Length Version
0xD2 0x01E8(488) 0x40
  • Write Data Command: 对指定寄存器进行数据写入操作 每一个Command的都有一个头部,描述了这个Command需要执行的指令长度, Parameter的第0、1、2三位描述了指定目标的长度,0x04(100)表示指令目标(指令对应的Value)的长度是4字节。Length描述了整个Command有484个字节的指令数量,包含了头信息,那实际操作的指令是: (484 - 4) / 8 = 60,即当前Command有60条写寄存器数据的操作指令。
Tag Length Parameter
0xCC 0x01E4(484) 0x04

除了Write Data Command还有Check data commandNOP command以及Unlock command指令块。

boot code根据启动设备的不同从固定的地址开始加载镜像文件之后并对镜像文件进行解析,通过IVT中的地址将数据拷贝到DDR中指定的地址,读取DCD初始化硬件(比如DDR)之后,开始执行bin文件0x87800000的第一条指令。这样就实现了从SD/eMMC/NAND等设备的启动了。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分