zoukankan      html  css  js  c++  java
  • 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文件的方式。

  • 相关阅读:
    UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design
    UVa 1658 (拆点法 最小费用流) Admiral
    UVa 11082 (网络流建模) Matrix Decompressing
    UVa 753 (二分图最大匹配) A Plug for UNIX
    UVa 1451 (数形结合 单调栈) Average
    UVa 1471 (LIS变形) Defense Lines
    UVa 11572 (滑动窗口) Unique Snowflakes
    UVa 1606 (极角排序) Amphiphilic Carbon Molecules
    UVa 11054 Wine trading in Gergovia
    UVa 140 (枚举排列) Bandwidth
  • 原文地址:https://www.cnblogs.com/Cqlismy/p/12392820.html
Copyright © 2011-2022 走看看