搜索
bottom↓
回复: 1

【正点原子Linux连载】第九章I.MX6U启动方式详解--摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南

[复制链接]

出0入234汤圆

发表于 2020-5-26 16:57:15 | 显示全部楼层 |阅读模式
本帖最后由 正点原子 于 2020-10-24 15:54 编辑

1)实验平台:正点原子阿尔法Linux开发板
2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-300792-1-1.html
4)对正点原子Linux感兴趣的同学可以加群讨论:
876919289 QQ群头像.png
5)关注正点原子公众号,获取最新资料更新

100846rel79a9p4uelap24.jpg
100846f1ce1fg14zbg0va4.png

第九章I.MX6U启动方式详解


        I.MX6U支持多种启动方式以及启动设备,比如可以从SD/EMMC、NAND Flash、QSPI Flash等启动。用户可以根据实际情况,选择合适的启动设备。不同的启动方式其启动方式和启动要求也不一样,比如上一章中的从SD卡启动就需要在bin文件前面添加一个数据头,其它的启动设备也是需要这个数据头的。本章我们就来学习一下I.MX6U的启动方式,以及不同设备启动的要求。

9.1启动方式选择


        BOOT的处理过程是发生在I.MX6U芯片上电以后,芯片会根据BOOT_MODE[1:0]的设置来选择BOOT方式。BOOT_MODE[1:0]的值是可以改变的,有两种方式,一种是改写eFUSE(熔丝),一种是修改相应的GPIO高低电平。第一种修改eFUSE的方式只能修改一次,后面就不能在修改了,所以我们不使用。我们使用的是通过修改BOOT_MODE[1:0]对应的GPIO高低电平来选择启动方式,所有的开发板都使用的这种方式,I.MX6U有一个BOOT_MODE1引脚和BOOT_MODE0引脚,这两个引脚对应这BOOT_MODE[1:0]。I.MX6U-ALPHA开发板的这两个引脚原理图如图9.1.1所示:


image861.gif


图9.1.1 BOOT_MODE原理图

        其中BOOT_MODE1和BOOT_MODE0在芯片内部是有100KΩ下拉电阻的,所以默认是0。BOOT_MODE1和BOOT_MODE0这两个引脚我们也接到了底板的拨码开关上,这样我们就可以通过拨码开关来控制BOOT_MODE1和BOOT_MODE0的高低电平。以BOOT_MODE1为例,当我们把BOOT_CFG的第一个开关拨到“ON”的时候,就相当于BOOT_MODE1引脚通过R88这个10K电阻接到了3.3V电源,芯片内部的BOOT_MODE1又是100K下拉电阻接地,因此此时BOOT_MODE1的电压就是100/(10+100)*3.3V= 3V,这是个高电平,BOOT_CFG这个拨码开关的不管哪个位拨到“ON”就是高电平,拨到“OFF”就是低电平。
        而I.MX6U有四个BOOT模式,这四个BOOT模式由BOOT_MODE[1:0]来控制,也就是BOOT_MODE1和BOOT_MODE0这两IO,BOOT模式配置如表9.1.1所示:

9B9468E9-D98B-4dd4-8F8D-7F46339DFAAB.png

表9.1.1 BOOT类型

        在表9.1.1中,我们用到的只有第二和第三种BOOT方式。
9.1.1串行下载
当BOOT_MODE1为0,BOOT_MODE0为1的时候此模式使能,串行下载的意思就是可以通过USB或者UART将代码下载到板子上的外置存储设备中,我们可以使用OTG1这个USB口向开发板上的SD/EMMC、NAND等存储设备下载代码。我们需要将BOOT_MODE1拨到“OFF”,将BOOT_MODE0拨到“ON”。这个下载是需要用到NXP提供的一个软件,一般用来最终量产的时候将代码烧写到外置存储设备中的,我们后面讲解如何使用。
9.1.2 内部BOOT模式
        当BOOT_MODE1为1,BOOT_MODE0为0的时候此模式使能,在此模式下,芯片会执行内部的bootROM代码,这段boot ROM代码会进行硬件初始化(一部分外设),然后从boot设备(就是存放代码的设备、比如SD/EMMC、NAND)中将代码拷贝出来复制到指定的RAM中,一般是DDR。
9.2 BOOT ROM初始化内容
        当我们设置BOOT模式为“内部BOOT模式”以后,I.MX6U内部的boot ROM代码就会执行,这个boot ROM代码都会做什么处理呢?首先肯定是初始化时钟,boot ROM设置的系统时钟如图9.2.1所示:

第九章I1606.png

图9.2.1boot ROM系统时钟设置

        在图9.2.1中BT_FREQ模式为0,可以看到,boot ROM会将I.MX6U的内核时钟设置为396MHz,也就是主频为396Mhz。System PLL=528Mhz,USB PLL=480MHz,AHB=132MHz,IPG=66MHz。关于I.MX6U的系统时钟,我们后面会详细讲解。
        内部boot ROM为了加快执行速度会打开MMU和Cache,下载镜像的时候L1ICache会打开,验证镜像的时候L1DCache、L2 Cache和MMU都会打开。一旦镜像验证完成,boot ROM就会关闭L1 DCache、L2 Cache和MMU。
        中断向量偏移会被设置到boot ROM的起始位置,当boot ROM启动了用户代码以后就可以重新设置中断向量偏移了。一般是重新设置到我们用户代码的开始地方,关于中断的内容后面会详细讲解。
9.3启动设备
        当BOOT_MODE设置为内部BOOT模式以后,可以从一下设备中启动:
        、接到EIM接口的CS0上的16位NOR Flash。
        、接到EIM接口的CS0上的OneNAND Flash。
        、接到GPMI接口上的MLC/SLC NAND Flash,NAND Flash页大小支持2KByte、4KByte和8KByte,8位宽。
        、Quad SPI Flash。
        、接到USDHC接口上的SD/MMC/eSD/SDXC/eMMC等设备。
        、SPI接口的EEPROM。
        这些启动设备如何选择呢?I.MX6U同样提供了eFUSE和GPIO配置两种,eFUSE就不讲解了。我们重点看如何通过GPIO来选择启动设备,因为所有的I.MX6U开发板都是通过GPIO来配置启动设备的。正如启动模式由BOOT_MODE[1:0]来选择一样,启动设备是通过BOOT_CFG1[7:0]、BOOT_CFG2[7:0]和BOOT_CFG4[7:0]这24个配置IO,这24个配置IO刚好对应着LCD的24根数据线LCD_DATA0~LCDDATA23,当启动完成以后这24个IO就可以作为LCD的数据线使用。这24根线和BOOT_MODE1、BOOT_MODE0共同组成了I.MX6U的启动选择引脚,如图9.3.1所示:

image864.png

图9.3.1启动引脚

        通过图9.3.1中的26个启动IO即可实现I.MX6U从不同的设备启动,BOOT_MODE1和BOOT_MODE0已经讲过了。看到这24个IO是不是头大?调整这24个IO的高低电平得多复杂啊?其实不然,虽然有24个IO,但是实际需要调整的只有那几个IO,其它的IO全部下拉接地即可,也就是设置为0。打开I.MX6U-ALPHA开发板的核心板原理图,这24个IO的默认设置如图9.3.1所示:


image866。。.jpg
[size=12.6316px]图9.3.1 BOOT_CFG默认设置

        可以看出在图9.3.1中大部分的IO都接地了,只有几个IO接高,尤其是BOOT_CFG4[7:0]这8个IO都10K电阻下拉接地,所以我们压根就不需要去关注BOOT_CFG4[7:0]。我们需要重点关注的就只剩下了BOOT_CFG2[7:0]和BOOT_CFG1[7:0]这16个IO。这16个配置IO含义在原理图的左侧已经贴出来了,如图9.3.2所示:

微信图片_2640.png

图9.3.2 BOOT_CFG引脚含义

        图9.3.2看着是不是也很头大,BOOT_CFG1[7:0]和BOOT_CFG2[7:0]这16个IO还能不能在减少呢?可以!打开I.MX6U-ALPHA开发板的底板原理图,底板上启动设备选择拨码开关原理图如图9.3.3所示:

dcdc.png

图9.3.3 BOOT选择拨码开关

        在图9.3.3中,除了BOOT_MODE1和BOOT_MODE0必须引出来,LCD_DATA3~LCDDATA7、LCD_DATA11这6个IO也被引出来了,可以通过拨码开关来设置其对应的高低电平,拨码开关拨到“ON”就是1,拨到“OFF”就是0。其中LCD_DATA11就是BOOT_CFG2[3],LCD_DATA3~LCD_DATA7就是BOOT_CFG1[3]~BOOT_CFG1[7],这6个IO的配置含义如表9.3.1所示:

微信图片_20200527110214.png
微信图片_20200527110235.png


表9.3.1 BOOT IO含义

        根据表9.3.1中的BOOT IO含义,I.MX6U-ALPHA开发板从SD卡、EMMC、NAND启动的时候拨码开关各个位设置方式如表9.3.2所示:
618.png


表9.3.2 I.MX6U-ALPHA开发板启动设置

        我们在“第八章汇编LED灯试验”中,最终的可执行文件led.bin烧写到了SD卡里面,然后开发板从SD卡启动,其拨码开关就是根据表9.3.2来设置的,通过上面的讲解就知道为什么拨码开关要这么设置了。
9.4镜像烧写
注意!本小节会分析bin文件添加的头部信息,但是在笔者写本教程的时候关于I.MX系列SOC头部信息的资料很少,基本只能参考NXP官方资料,而官方资料有些地方讲解的又不是很详细。所以本节有部分内容是笔者根据NXP官方u-boo.imx文件的头部信息反推出来的,因此难免有错误的地方,还望大家谅解!如有发现错误之处,欢迎大家在www.openedv.com论坛上留言。
        前面我们设置好BOOT以后就能从指定的设备启动了,但是你的设备里面得有代码啊,在第八章中我们使用imxdownload这个软件将led.bin烧写到了SD卡中。imxdownload会在led.bin前面添加一些头信息,重新生成一个叫做load.imx的文件,最终实际烧写的是laod.imx。那么肯定就有人问:imxdownload究竟做了什么?load.imx和led.bin究竟是什么关系?本节我们就来详细的讲解一下imxdownload是如何将led.bin打包成load.imx的。
        学习STM32的时候我们可以直接将编译生成的.bin文件烧写到STM32内部flash里面,但是I.MX6U不能直接烧写编译生成的.bin文件,我们需要在.bin文件前面添加一些头信息构成满足I.MX6U需求的最终可烧写文件,I.MX6U的最终可烧写文件组成如下:
        、Image vectortable,简称IVT,IVT里面包含了一系列的地址信息,这些地址信息在ROM中按照固定的地址存放着。
        、Bootdata,启动数据,包含了镜像要拷贝到哪个地址,拷贝的大小是多少等等。
        、Deviceconfigurationdata,简称DCD,设备配置信息,重点是DDR3的初始化配置。
        、用户代码可执行文件,比如led.bin。
        可以看出最终烧写到I.MX6U中的程序其组成为:IVT+Bootdata+DCD+.bin。所以第八章中的imxdownload所生成的load.imx就是在led.bin前面加上IVT+Bootdata+DCD。内部Boot ROM会将load.imx拷贝到DDR中,用户代码是要一定要从0X87800000这个地方开始的,因为链接地址为0X87800000,load.imx在用户代码前面又有3KByte的IVT+Boot Data+DCD数据,下面会讲为什么是3KByte,因此load.imx在DDR中的起始地址就是0X87800000-3072=0X877FF400。 
9.4.1 IVT和Boot Data数据
        load.imx最前面的就是IVT和Boot Data,IVT包含了镜像程序的入口点、指向DCD的指针和一些用作其它用途的指针。内部Boot ROM要求IVT应该放到指定的位置,不同的启动设备位置不同,而IVT在整个load.imx的最前面,其实就相当于要求load.imx在烧写的时候应该烧写到存储设备的指定位置去。整个位置都是相对于存储设备的起始地址的偏移,如图9.4.1.1所示:

image872.png


图9.4.1.1  IVT偏移

        以SD/EMMC为例,IVT偏移为1Kbyte,IVT+Bootdata+DCD的总大小为4KByte-1KByte=3KByte。假如SD/EMMC每个扇区为512字节,那么load.imx应该从第三个扇区开始烧写,前两个扇区要留出来。load.imx从第3KByte开始才是真正的.bin文件。那么IVT里面究竟存放着什么东西呢?IVT里面存放的内容如图9.4.1.2所示:

image874.png


图9.4.1.2 IVT格式

        从图9.4.1.2可以看到,第一个存放的就是header(头),header格式如图9.4.1.3所示:
image876.png



图9.4.1.3 IVT header格式

        在图9.4.1.3中,Tag为一个字节长度,固定为0XD1,Length是两个字节,保存着IVT长度,为大端格式,也就是高字节保存在低内存中。最后的Version是一个字节,为0X40或者0X41。
        Boot Data的数据格式如图9.4.1.4所示:



image878.png


图9.4.1.4 Boot Data数据格式

实际情况是不是这样的呢?我们用winhex软件打开load.imx一看便知,winhex可以直接查看一个文件的二进制格式数据,winhex软件我们已经放到了开发板光盘中,路径为:开发板光盘->3、软件->winhexv19.7.zip,大家自行安装。用winhex打开以后的load.imxd如图9.4.1.4所示:

image880.png

图9.4.1.4load.imx部分内容

        图9.4.1.4是我们截取的load.imx的一部分内容,从地址0X00000000~0X000025F,共608个字节的数据。我们将前44个字节的数据按照4个字节一组组合在一起就是:0X402000D1、0X87800000、0X00000000、0X877FF42C、0X877FF420、0X877FF400、0X00000000、0X00000000、0X877FF000、0X00200000、0X00000000。这44个字节的数据就是IVT和Boot Data数据,按照图9.4.1.2和图9.4.1.4所示的IVT和Boot Data所示的格式对应起来如表9.4.1.1所示:


ivt.png


表9.4.1.1load.imx结构分析

        在表9.4.1.1中,我们详细的列出了load.imx的IVT+Boot Data每32位数据所代表的意义。这些数据都是由imxdownload这个软件添加进去的。
9.4.2 DCD数据
        复位以后,I.MX6U片内的所有寄存器都会复位为默认值,但是这些默认值往往不是我们想要的值,而且有些外设我们必须在使用之前初始化它。为此I.MX6U提出了一个DCD(Device Config Data)的概念,和IVT、Boot Data一样,DCD也是添加到load.imx里面的,紧跟在IVT和Boot Data后面,IVT里面也指定了DCD的位置。DCD其实就是I.MX6U寄存器地址和对应的配置信息集合,Boot ROM会使用这些寄存器地址和配置集合来初始化相应的寄存器,比如开启某些外设的时钟、初始化DDR等等。DCD区域不能超过1768Byte,DCD区域结构如图9.4.2.1所示:

head.png

图9.4.2.1 DCD区域结构

        DCD的header和IVT的header类似,结构如图9.4.2.2所示:

lengh.png

图9.4.2.2 DCD的header结构

        其中Tag是单字节,固定为0XD2,Length为两个字节,表示DCD区域的大小,包含header,同样是大端模式,Version是单字节,固定为0X40或者0X41。
        图9.4.2.1中的CMD就是要初始化的寄存器地址和相应的寄存器值,结构如图9.4.2.3所示:
tag.png


图9.4.2.3 DCD CMD命令格式

        图9.4.2.3中Tag为一个字节,固定为0XCC。Length是两个字节,包含写入的命令数据长度,包含header,同样是大端模式。Parameter为一个字节,这个字节的每个位含义如图9.4.2.4所示:

555555.png

图9.4.2.4 Parameter结构

        图9.4.2.4中的bytes表示是目标位置宽度,单位为byte,可以选择1、2、和4字节。flags是命令控制标志位。
        图9.4.2.3中的Address和Vlalue/Mask就是要初始化的寄存器地址和相应的寄存器值,注意采用的是大端模式!DCD结构就分析到这里,在分析IVT的时候我们就已经说过了,DCD数据是从图9.4.1.4的0X2C地址开始的。根据我们分析的DCD结构可以得到load.imx的DCD数据如表9.4.2.1所示:


30FBD14A-5D04-4e51-B1C9-3F23E25E369A.png




表9.4.2.1 DCD数据结构

        从图9.4.2.1中可以看出,DCD里面的初始化配置主要包括三方面:
        ①、设置CCGR0~CCGR6这7个外设时钟使能寄存器,默认打开所有的外设时钟。
        ②、配置DDR3所用的所有IO。
        ③、配置MMDC控制器,初始化DDR3。
        I.MX6U的启动过程我们就讲解到这里,本章我们详细的讲解了I.MX6U的启动模式、启动设备类型和镜像烧写过程。总结一下,我们编译出来的.bin文件不能直接烧写到SD卡中,需要在.bin文件前面加上IVT、Boot Data和DCD这三个数据块。这三个数据块是有指定格式的,我们必须按照格式填写,然后将其放到.bin文件前面,最终合成的才是可以直接烧写到SD卡中的文件。











阿莫论坛20周年了!感谢大家的支持与爱护!!

如果想吃一顿饺子,就得从冰箱里取出肉,剁馅儿,倒面粉、揉面、醒面,擀成皮儿,下锅……
一整个繁琐流程,就是为了出锅时那一嘴滚烫流油的热饺子。

如果这个过程,禁不住饿,零食下肚了,饺子出锅时也就不香了……《非诚勿扰3》

出0入0汤圆

发表于 2021-5-13 08:55:55 | 显示全部楼层
买了imx6u开发板
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-28 22:36

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表