ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二.I.MX6U的启动方式及头部文件

2021-12-27 02:03:19  阅读:192  来源: 互联网

标签:IVT 字节 启动 BootData DCD MX6U 地址 头部 SD


------------恢复内容开始------------

在上一章我们通过点亮LED实现了第一个小程序。在烧录程序完成插入SD卡后有个选择启动拨码开关的步骤,那么这个启动方式是如何实现的,今天我们就来大致了解下I.MX6U的启动方式

一.启动模式选择

按照I.MX6UL的开发手册上所说,整个BOOT的处理过程就是芯片上电后,芯片首先会根据BOOT_MODE[]1:0]的设置来选择启动方式

 

 

00为通过可编程熔断丝启动,这种方式只能修改一次,后面就不能修改了,我们不会使用

01为串行下载器模式,就是通过USB或者UART将代码下载到板子的外置存储设备中。针对阿尔法开发板,可以使用支持OTG的USB接口向板子上的SD/EMMC、NAND等设备下载代码。这个下载需要NXP(恩智浦)提供的一个软件,在量产的时候使用。

10为内部BOOT模式,在此模式下芯片会执行bootROM代码,这段代码会进行硬件初始化,然后从boot设备中将代码拷贝出来复制到指定的RAM中,一般就是DDR。

结合硬件原理图来看(下面拨码开关9那里标注不对,应该是LCD_DATA7。并且这个图我修改过,原图拨码开关标注左边是off)

 

 

 拨码开关1、2位就是启动方式的选择,我们常用的就是01(USB)或10(内部).

二.启动设备选择

如果要选择启动设备,前提是MODE1=1和MODE0=0,即内部BOOT模式。开发手册上说明了这个模式下支持的设备

 

 

 我们最常用的就是NANDflash,SD,EMMC,QSPIFlash(轻量级,便宜)

设备的选择是通过BOOT_CFG1,2,4几个寄存器,每个8为,通过LCD1_DATA00-23y一共24个值决定的。

 

 而在开发板上,大部分都是通过47K的下拉电阻接地(BT_CFG4全接地,CFG2上面两个上拉是DNP也就是未焊接,也是全部接地的)

                

往前翻一下那个拨码开关,可以看一下旁边画的草图,当开关on的时候,LCD_DATA点通过47K的下拉电阻可以得到近似3.3V的电压,可以判定为1。

然后除过1、2两个开关剩下6个拨码分别控制了LCD_DATA3/4/5/6/11脚,对应的BOOT_CFG1[3:7]和BOOT_CFG2[3]

下面的表是讲到BOOT_CFG2的定义

 

 3和4一同决定了板子首冲SDHC1还是SDHC2启动。6ULL支持两个SD卡接口,是通过拨码开关3选择,为1的时候是从SDHC2启动

重要的是BOOT_CFG1,还是结合图表来看

 

 首先,0,1,2都是定死的,3-7被引到了拨码开关。

由于前三种设备我们都未使用,3同2一同决定了是选择SD或MMC/eMMC的速度(能选的只有3,一般都是0),对于NANDFlash是定义了设备的数量

剩下的就直接看SD,eMMC和NAND的设置就行了

对于SD来说,[7:5]是订好的010,[4]是快速启动,我们一般都是0

eMMC时和SD一样,[7:4]是0110

NAND模式时,[7]固定为1,而[6:4]查手册可以发现

[6]是NAND的协议模式,一般我们都用0

[5:4]决定了块的页大小,这个要看NANDFlash的手册了。

三.启动头文件

我们在led的裸机试验里讲过,我们在生成的led.bin文件前要添加一些头文件,在我们选择了从内部BOOT启动时,BOOTROM就会从我们选择的设备里读取加了头部信息的bin文件。

那么BootRom要做哪些事情呢?参考下开发手册8.4设备初始化的部分可以得到

设置内核时钟:396MHz(8.4.3ARM PLL)。

使能MMU和caches(8.4.4),包含L1cache,L2cache,MMU,目的是加速启动。

从BOOT_CFG24个设置外置存储中读取image,然后做相应的处理,在读取底image文件上是包含了头部信息的,那么这里的头部信息又包含什么呢?

bin文件的头部信息

开发手册8.7里讲到下面的内容

 

IVT镜像向量表 ,包含了镜像那个的入口,DCD的地址等一系列数据信息,这个表在不同启动设备的存储地址及大小是不同的,对于不同设备的IVT起始地址是有规定的,其相应的便宜地址及初始化加载大小如下。BootRom只要知道IVT的地址,其他的组成部分在IVT中的内容就能查到。

 对于我们常用的SD/MMC什么的,偏移量是1K,因为对于SD卡等存储设备,前512个字节包含了分区表等信息,肯定是不能用的。所以前面给了个偏移量。而整个IVT+BootData+DCD还有前面被偏移的量一共是4K,那么剩下IVT+BootData+DCD的大小就剩了3K了,所以我们的实际bin地址就是3*1024,也就是0xC00。

这样就能知道我们烧写到SD卡中的load.imx文件是在SD卡中的起始地址为0x400,既然IVT是一个表(Table),那么每个地址的格式都是定死的。IVT具体结构如下表,每个成员都是32bit(4个字节)

我们用hexedit打开那个 load.imx文件,截取从0x00000000到0x0000025F一共608个字节的数据,注意打印出来的内容,左边是低字节,右边是高字节

 

 关注下前44个字节,我们把前44个字节的数据按照4个字节一起的方式组合下数据,分别就是

  • 0x402000D1
  • 0x87800000
  • 0x00000000
  • 0x877FF42C
  • 0x877FF420
  • 0x877FF400
  • 0x00000000
  • 0x00000000
  • 0x877FF000
  • 0x00200000
  • 0x00000000

这11个数据就是IVT和BootData的数据。我们对照给定的IVT的格式来看下IVT的内容

header:

 

 

Tag,固定的为1个字节,固定为0xD1;Length为2个字节,保存IVT长度,注意为大端格式,即高字节保存在低地址中;最后的Version也是1个字节,为0x40或0x41

这里有个很奇怪的点,按照这个图表上画的Tag是在前边,但是对照我们的load.imx文件的前4个字节,0x402000D1,0xD1是低字节的数据,0x40是高字节的数据,那么Tag应该就是对应的低字节。中间两个字节是长度,big endian模式,2000对应的长度应该是0x20,也就是32个字节,这个长度是包含header的。因为每条数据格式都是固定的,都是4个字节,所以IVT就有32/4=8条信息,刚好跟IVT的Format一致。

entry

入口地址,image那个第一行指令的位置,也就是编译时候指定的链接那个地址,我们在编译的时候-Ttext后面指定的链接地址是0x87800000,和第二条数据一致。

resvered1

保留,未使用,数据为0x00000000

dcd

dcd地址,镜像地址为0x87800000(bin的起始地址),IVT+BootData+DCD大小为3Kb(0xC00),因此load.imx的起始地址就是0x87800000-0xC00=0x877FF400,这个地址也就是IVT的起始地址。这个起始地址加上IVT(0x20,32字节),还有BootData的地址就是DCD的地址。BootData的大小在后面讲BootData的时候会讲到,一共12个字节(0xC),所以dcd的起始地址就是(0x877FF400+0x20+0xC=0x877FF42C),和实际数据一样。

真实数据为0x877FF42C,后面时候会再讲到

bootdata

BootData的为地址,因为IVT的起始地址为0x877FF400,长度为0x20,所以Boot的起始地址为0x0x877FF420,和实际数据一致。

self

IVT复制到DDR中的首地址,就是前面计算的IVT的起始地址0x877FF400,和实际数据相同。

csf

未使用,数据为0x00000000

resvered2

未使用,数据为0x00000000

Bootdata数据结构

BootData的数据结构有也是固定的,每条信息4个字节,共3条信息。

先看一下这三条数据也就是上面说的11条数据的最后三条:

  • 0x877FF000
  • 0x00200000
  • 0x00000000

start

第一条就是img的绝对地址,也就是load.imx的绝对地址,即0x87800000-4*1024 = 0x877FF000,和实际相同。注意这个地址是包含了1K的偏移量的(所以是4*1024,包含1K的偏移量和3K的Initial Load Region)。

length

镜像的大小,这里封顶为0x200000,换算为10进制后除以1024就是2048,即2MB。也就是镜像大小不能超过2MB。这个是提供的烧录软件定死的。

plugin

插件,这里没用。

上面的IVT和BootData是教程里从恩智浦给定的u-boot.imx文件提取出来的。整个头部的结构应该是这样的

 

 

DCD数据

I.MX6U在每次上电或复位以后,片内所有的寄存器都会被复位为默认值,但是这些值通常不是我们需要的,并且有些外设在使用的时候必须初始化。这就是DCD(Device Config Data)的作用。和IVT、BootData一样,DCD也是添加到load.imx里的,位置就在BootData后面,IVT里也指定了DCD的地址。DCD其实就是I.MX6U寄存器地址和对应的配置信息的集合。BootRom会根据这些信息去初始化相应的寄存器。要注意的是,DCD的区域不能超过1768Byte。其结构如下图所示

 

 和IVT一样,我们也截取一段程序数据看一下。由于在IVT里已经计算过了,DCD的起始是在IVT和Bootdata后即0x20+0xC=0x2C,

 

内容可以读一下,还是注意方向

  • 0x40E801D2
  • 0x04E401CC
  • 0x68400C02
  • 0xFFFFFFF
  • 0xB4040E02
  • 0xFFFFFFFF

DCD的header和IVT的header基本一样,一个固定的单字节tag,数据为0xD2,第二第三字节表明DCD大小,为0x01E8=488字节,后面为版本号为固定的0x41(实际为0x40,估计版本有出入)

header后面跟的就是命令,也是有固定格式的

 

 第一条是指定的,对应数据为0x04E401CC,0xCC对应Tag,长度为0x1E4=484个字节,是除去header的长度;后一个字节Parameter为0x04,,其结构如下表

 

0x04可以按照上表理解为目标位置宽度为4个字节, 前面的3、4bit对应的操作为写入。

从第三个数据开始依次就是寄存器地址/写入的值,我们看下第三个值:0x68400C02(注意是大端模式,反转为就是0x020C4068),看下我们的LED.s文件

 一开始我们先对时钟使能,对应的寄存器CCGR0的地址就是0x020C4068,写入的数据就是0xFFFFFFFF,是不是就是DCD里的内容了。

下面的0x020C406C,可以直接在手册里查一下(搜索关键字应为20C_406C),可以看出来对应的寄存器是CCM_CCGR1

就是对各种要操作都DDR进行初始化(CCGR1在代码里并没有初始化,查了烧录软件的源代码里的头文件,imxdownload.h,里面对DCD进行了初始化)

其他的数据

后面其实还有检查数据命令、nop命令、解锁命令等我们暂时还没用到,但是全属于DCD的,但是我们都还没用到,看下具体的数据,都是0x00000000。

整个启动的过程以及加载在bin文件前的头部信息的过程,就是上面的内容了,虽然有些枯燥,但还是要搞清楚的! 

标签:IVT,字节,启动,BootData,DCD,MX6U,地址,头部,SD
来源: https://www.cnblogs.com/yinsedeyinse/p/15732851.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有