NXP的I.MX6U系列SoC启动流程

1、前言

NXP家的I.MX6U系列的SoC支持多种启动方式以及启动设备,使用该系列SoC的用户可以根据自己的实际情况,选择合适的启动方式和启动设备,例如,可以从Nnad Flash、eMMC和SDCard等不同设备中启动,从不同的启动设备中启动,启动要求一般都不同。

 

2、I.MX6UL启动方式

以I.MX6UL这款SoC为例,启动引导过程是从上电复位(POR)开始的,此硬件复位逻辑强制ARM内核从芯片上的Boot ROM开始执行,Boot ROM代码通过内部寄存器BOOT_MODE[1:0]的状态以及eFUSE和GPIO设置的状态,以确定芯片的启动方式和启动设备。

Boot ROM的主要特性包括:

  • 支持各种启动设备启动
  • 串行下载支持(USB OTG和UART)
  • 支持设备配置数据(DCD)和PLUGIN
  • 基于数字签名和加密的高保正启动(HAB)
  • 从低功耗唤醒

Boot ROM支持以下的启动设备:

  • NOR Flash
  • NAND Flash
  • OneNAND Flash
  • SD/MMC
  • SPI Flash和EEPROM
  • QSPI Flash

对于I.MX6U系列的SoC而言,有4种启动模式,这4种启动模式是由BOOT_MODE[1:0]进行控制的,其实就是芯片上的BOOT_MODE1和BOOT_MODE0这两个引脚,启动方式配置如下:

当BOOT_MODE[1:0]=01的时候,启动方式为Serial Downloader,芯片处于该模式的时候,用户可以通过USB接口进行固件下载,当BOOT_MODE[1:0]=10的时候,启动方式为Internal Boot,此时,Boot ROM代码将会读取DCD数据初始化DDR,并从启动设备,例如Nand Flash种拷贝启动镜像文件,从而引导启动,这两种启动方式是用户用得最多的。

 

3、Boot ROM设备初始化

对于I.MX6UL这款SoC而言,当用户配置BOOT_MODE[1:0]=10的时候,为Internel Boot启动模式,SoC将会执行Boot ROM代码,首先会进行SoC的时钟初始化,Boot ROM代码设置的系统时钟如下:

从图中可以知道,当BT_FREQ为0的时候,ARM PLL=396MHz,也就是主频为396MHz,System PLL=528MHz等,另外,Boot ROM为了加快执行速度还会打开MMU和Cache,中断向量偏移还会被设置到Boot ROM的起始位置,当用户代码启动以后可以重新设置中断向量偏移。

整个Boot ROM的启动流程,如下所示:

电源开启后,芯片首先进行复位并且执行Boot ROM中的代码,开始检查CPU的ID号,随后检查Reset的状态,如果是正常复位的话,检查芯片的启动模式(通过fuses或者GPIO配置),如果是内部启动模式的话,将会从启动设备中下载初始化启动镜像,并且进行镜像验证,如果镜像验证通过的话,将会将启动镜像进行执行,从而引导芯片正常启动。

对于I.MX6UL芯片,Boot ROM设备初始化下的内部ROM和RAM的内存映射如下:

Boot ROM代码的启动引导较复杂,关于整个启动流程的更详细过程,可以参考相关芯片的参考手册。

 

4、I.MX6UL启动设备选择

当I.MX6UL芯片的BOOT_MODE[1:0]=10时候,也就是从Internal Boot模式启动时,可以从下面的启动设备中启动:

  • 接到EIM接口的CS0上的16bit的NOR Flash或者OneNAND Flash
  • 接到GPMI接口上的MLC/SLC NAND Flash,NAND Flash页大小支持2KB、4KB和8KB,8bit宽
  • QSPI Flash
  • 接到USDHC接口上的SD/MMC/eMMC等设备
  • 接到SPI接口的EEPROM

对于这些启动设备的选择,可以通过eFUSE或者GPIO进行配置,接下来,我们需要了解的是如何通过GPIO进行这些启动设备的选择,和启动模式的选择类似,启动设备是通过BOOT_CFG1[7:0]、BOOT_CFG2[7:0]和BOOT_CFG4[7:0]这24个IO进行配置的,并且这些IO口对应着LCD的24根数据线LCD1_DATA00~LCD1_DATA23,引导启动完成以后,这24个IO口就可以作为LCD的数据线使用了,启动设备选择引脚如下所示:

启动设备的选择引脚非常多,但是在实际开发的时候,需要调整的只有BOOT_CFG1[7:4],其它的引脚根据实际需要接高电平或者低电平即可,通过芯片的参考手册可以知道,这几个IO口的配置和对应的启动设备如下所示:

例如,当配置BOOT_CFG1[7:4]=1xxx的时候,启动设备将选择为Nand Flash,Boot ROM代码将会从该启动设备中读取下载启动镜像,从而将系统进行启动。

 

5、可编程Image镜像文件

接下来,介绍I.MX6UL的可编程镜像文件,使用过I.MX6UL的用户应该都知道,当我们针对I.MX6UL这款SoC进行Uboot编译烧写的时候,最终烧写到启动设备中的二进制文件是u-boot.imx,以.imx结尾的文件就是可编程Image镜像文件,它除了用户的代码和数据以外,还包括了一些特定的数据结构,例如:Image Vector Table(IVT)、Device Configure Data(DCD)等。

一个可编程的Image文件(.imx结尾)包括以下内容:

  • Image Vector Table—固定在ROM中的一系列指针,用于指定可编程镜像的其它组件在哪里
  • Boot Data—指定可编程镜像的位置、大小以及插件标志
  • Device Configure Data—IC的配置信息
  • 用户的代码和数据—用户编写的.bin文件

所以,对于u-boot.imx这个可编程Image镜像文件来说,其实它包含的组件为:IVT + Boot Data + DCD + u-boot.bin,其中u-boot.bin就是用户的代码和数据,接下来,依次介绍这几部分,它们都是具有一定的固定的格式的。

(1)Image Vector Table(IVT)

可编程镜像文件.imx的最前面的数据结构就是Image Vector Table(IVT),它是Boot ROM从启动设备提供的镜像文件中读取的数据结构,包含了芯片引导启动成功的数据组件,IVT包含了程序镜像的入口地址、指向Device Configure Data(DCD)的指针,以及Boot ROM引导启动过程中使用的其它指针。

IVT所在的固定地址是由芯片所使用的启动设备决定的,对于不同的启动设备,IVT的偏移地址(从基本地址开始)和Init Load Region的大小的相关定义如下图所示,IVT的位置要求是固定的,剩余的数据结构和镜像内存映射则是灵活。

以SD/MMC设备为例,从上表可以知道,IVT的偏移为1Kbyte,Initial Load Region的大小为4Kbyte,所以IVT + Boot Data + DCD = 4Kbyte - 1Kbyte = 3Kbyte,如果SD/MMC设备的每个扇区为512字节的话,那么.imx可编程镜像文件应该从启动设备的第三个扇区开始存储,所以.imx文件从第3Kbyte开始才是用户真正的.bin文件。

接下来,我们详细了解一下IVT里面包含了哪些内容,IVT里面的每个元素都是32bit word的,如下所示:

从上面的IVT格式表中可以看到,IVT存放的第一个元素就是header,也就是头部,它的格式如下所示:

从图中可以看到,header的元素有3个,分别是Tag、Length和Version,其中Tag为一个字节的长度,固定为0xD1,Length是两个字节,为大端模式(高字节在低内存),保存着IVT的长度,Version为一个字节,表示版本信息,为0x40或者0x41。

IVT的其它元素的介绍在上面给出的表都有相应的介绍,例如:entry表示用户可执行镜像第一条指令的绝对地址,Image Vector Table的整个示意图,如下:

(2)Boot Data Structure(Boot Data)

Boot Data数据结构中的每个元素也是32bit word的,它的格式如下所示:

在Boot Data数据结构中,start表示了可编程镜像的绝对地址,length表示了可编程镜像文件的大小,plugin表示为Plugin Image的标志位。

(3)Device Configure Data(DCD)

我们都知道,当芯片上电复位后,芯片上所有的外设寄存器使用的都是默认的寄存器值,但是,有一些寄存器的默认配置,往往不是我们想要的,因为它们达不到系统的最佳性能,并且,对于一些外围设备,我们在使用之前,需要先进行配置,例如DDR的控制器,Device Configure Data(DCD)和IVT、Boot Data一样,也是一种数据结构,同样是添加到.imx文件中,它其实就是一些寄存器的地址,以及寄存器的配置信息,Boot ROM会使用这些寄存器地址和寄存器配置来初始化芯片上的外设,DCD的区域不能超过1768bytes,它格式如下所示:

DCD数据结构的Header元素格式和IVT的header格式类似,大小为4字节,格式如下:

同样是包括了Tag、Length和Version,其中,Tag为单个字节,固定为0xD2,Length的大小为2个字节,格式为大端格式(高字节在低内存),为整个DCD数据结构(包含头部)的长度大小,Version为单个字节,固定为0x41。

[CMD]就是命令Command,表示要初始化的寄存器地址和寄存器的值,存储格式为大端存储(高字节在低内存),例如:Write Data Command,它的格式如下所示:

在Write Data Command格式表中,Tag为1个字节,固定为0xCC,Length的大小为2个字节,大端格式,表示Write Data Command的长度,包括header,Address表示数据要写入的目标寄存器地址,Value/Mask表示寄存器要写入的值或者bitmask,Parameter的大小为1个字节,该字节的每一位含义如下所示:

其中,bytes表示目标位置的宽度大小,可以选择1、2或者4字节,flags表示命令行为的控制标志位,bit3表示为Data Mask,bit4表示为Data Set,这两位的配置,决定了写命令的行为,如下:

另外,还有一些其它的命令,例如Check Data Command、NOP Command等,就不一一介绍了,有兴趣的可以去查看芯片的参考手册。

 

6、可编程镜像.imx实例分析

在前面,我们已经对.imx文件的整个结构组成进行了大概地分析,包括对Image Vector Table(IVT)、Boot Data Structure(Boot Data)和Device Configure Data(DCD)的数据结构格式分析,可是实际上到底是不是这样的呢?我们需要通过一个实例进行验证,例如从uboot源码中编译出来的u-boot.imx文件,可以使用WinHex软件进行查看,打开的u-boot.imx如下:

根据上面打开的u-boot.imx可编程镜像文件,将前面的32个字节的数据,按照每4个字节为一组进行组合,得到就是IVT数据结构,然后根据上面分析的IVT格式进行对应,得到如下表格:

Image Vector Table(IVT)数据结构
IVT元素 数据 说明
header 0x402000D1 第一个字节为Tag,固定为0xD1,第二和第三字节为IVT的Length,大端模式,为0x20=32字节,第四个字节为version,固定为0x40。
entry 0x87800000 用户镜像.bin文件的入口地址,也是镜像第一行指令所在的地址,用户程序的链接地址。
reserved1 0x00000000 保留,未使用,全部设置为0。
dcd 0x877FF42C DCD的地址,用户镜像的地址为0x87800000,IVT+Boot Data+DCD的整个大小为3KB,所以u-boot.imx的起始地址为0x87800000-0xC00=0x877FF400,因此DCD的起始地址相对于u-boot.imx起始地址的偏移量为0x877FF42C-0x877FF400=0x2C,所以从打开的u-boot.imx文件中,从0x2C地址开始的数据就是DCD数据。
boot data 0x877FF420 Boot Data的地址,IVT中的header中设置了IVT长度大小为0x20=32字节,因此Boot Data的地址为0x877FF400+0x20=0x877FF420。
self 0x877FF400 IVT被复制到DRAM中的首地址。
csf 0x00000000 CFS地址。
reserved2 0x00000000 保留,未使用,全部设置为0。

分析了u-boot.imx文件中的IVT的数据结构后,接下来,将后面接着的12个字节数据,同样按照每4个字节为一组进行组合,得到的就是Boot Data数据结构,并根据上面分析的Boot Data格式进行对应,得到如下表格:

Boot Data数据结构
结构元素 数据 说明
start 0x877FF000 整个u-boot.imx镜像的起始地址,包括1KB的地址偏移。
length 0x00073000 可编程镜像u-booti.imx文件的大小,0x73000=460KB。 
plugin 0x00000000 Plugin Image标志,在这未使用。

分析了u-boot.imx文件中的Boot Data数据结构后,接下来,从偏移地址0x2C开始就是DCD数据结构,同样按照4个字节为一组进行组合,得到的就是DCD数据结构,根据上面分析的DCD格式进行对应,得到如下表格:

Device Configure Data(DCD)数据结构
DCD元素 数据 说明
Header 0x40E001D2 第一个字节为Tag,固定为0xD2,第二和第三字节为DCD的长度大小,大端格式存储,为0x01E0=480字节,第四个字节为Version,固定为0x40。
Write Data Command 0x04DC01CC 第一个字节为Tag,固定为0xCC,第二和第三字节为Write Data Command的总长度,包括header,大端格式存储,为0x01DC=476字节,第四个字节为Parameter,为0x04,表示目标位置宽度为4个字节。
Address 0x020C4068 CCM_CCGR0寄存器地址。
Value 0xFFFFFFFF 写入CCM_CCGR0寄存器的值,表示开启CCM_CCGR0控制的外设的所有时钟。
... ... CCM_CCGR1-CCM_CCGR6寄存器的地址以及写入寄存器的值,表示开启CCM_CCGR1-CCM_CCGR6控制的外设的所有时钟。
Address 0x020E04B4 IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE寄存器地址。
Value 0x000C0000 IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE寄存器写入的值,设置为DDR3模式。
Address 0x020E04AC IOMUXC_SW_PAD_CTL_GRP_DDRPKE寄存器地址。
Value 0x00000000 bit12写入0,表示所有的DDR引脚关闭Pull/Keeper功能。
Address 0x020E027C IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK0_P寄存器地址。
Value 0x00000028 设置DRAM_SDCLK0_P引脚驱动能力为R0/5。
... ... 和上面类似,都是DDR相关引脚的配置,相关寄存器的地址和寄存器要写入的值。
Address 0x020E0248 IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1寄存器地址。
Value 0x00000028 设置DRAM_DQM1引脚驱动能力为R0/5。
Address 0x021B001C MMDC Core Special Command Register的地址。
Value 0x00008000 bit15设置为1,表示申请MMDC配置是有效的。
Address 0x021B0800 MMDC PHY ZQ SW control register的地址。
Value 0xA1390003 MMDC寄存器写入的值。
... ... MMDC相关配置寄存器的地址和寄存器要配置的值。

到这里,u-boot.imx文件中的DCD数据结构就总结完成了,里面就主要的就是一些芯片外设时钟的开启,以及MMDC寄存器地址和MMDC寄存器里面要配置的值,目的就是用来初始化DDR。

 

7、.imx文件的产生方式

对于.imx文件的生成,在uboot源码里面集成了一个工具mkimage,关于.imx文件的生成的更详细信息,可以查看下面的文件:

uboot/doc/README.imximage

对于mkimage工具的使用,命令如下:

./tools/mkimage -T imximage \
        -n <board specific configuration file> \
        -e <execution address> -d <u-boot binary>  <output image file>

其中,-T imximage表示生成的目标文件类型,-n指定板子特定的配置文件,需要是编译uboot时候imximage.cfg产生的imximage.cfg.cfgtmp文件,其实imximage.cfg中包含的就是我们需要添加的DCD数据,-e指定了用户镜像的入口地址,也就是用户镜像的链接地址,-d指定uboot.bin二进制文件,最后则是要生成的镜像的文件名称,例如u-boot.imx,其实u-boot.bin也是一个比较复杂的裸机程序,该工具不只是局限于uboot使用,也可以用于我们自己编写的.bin文件,用来产生.imx文件。

以mx6ul_14x14_evk的板子为例,对于该工具的使用命令如下:

./tools/mkimage -n ./board/freescale/mx6ul_14x14_evk/imximage.cfg.cfgtmp \
        -T imximage -e 0x87800000  \
        -d u-boot.bin u-boot.imx

用户镜像的入口地址为0x87800000,该地址也是uboot编译时的链接地址,最后生成的文件为u-boot.imx,将该文件烧写到Nand Flash或MMC启动设备即可。

 

8、小结

本文主要对NXP家的I.MX6U系列的SoC的的启动流程进行大概的总结,包括从芯片上电复位执行Boot ROM的流程的分析,还有就是介绍了可编程镜像.imx文件中的组件,IVT、Boot Data和DCD相关数据结构的详细介绍,最后则是介绍了使用uboot源码集成的工具mkimage生成.imx文件的方式。

posted @ 2020-03-01 22:56  Cqlismy  阅读(922)  评论(0编辑  收藏  举报