Boot Rom需要初始化DDR才能将uboot载入到DDR,故要在bin前添加DDR寄存器初始化
在第八章中我们使用 imxdownload 这个软件将 led.bin 烧写到了 SD 卡中。imxdownload 会在 led.bin前面添加一些头信息,重新生成一个叫做 load.imx 的文件,最终实际烧写的是 laod.imx。这个工具是第三方工具,NXP有官方程序mkimage,他的作用是根据imximage.cfg.cfgtmp内容将bin添加头信息变成imx。经过测试发现imximage.cfg与DCD完全一致!本节我们就来详细的讲解一下 imxdownload 是如何将 led.bin 打包成 load.imx 的。学习 STM32 的时候我们可以直接将编译生成的.bin 文件烧写到 STM32 内部 flash 里面,但是 I.MX6U 不能直接烧写编译生成的.bin 文件,我们需要在.bin 文件前面添加一些头信息构成满足 I.MX6U 需求的最终可烧写文件,I.MX6U 的最终可烧写文件组成如下:
①、Image vector table,简称 IVT,IVT 里面包含了一系列的地址信息,这些地址信息在ROM 中按照固定的地址存放着。
②、Boot data,启动数据,包含了镜像要拷贝到哪个地址,拷贝的大小是多少等等。
③、Device configuration data,简称 DCD,设备配置信息,重点是 DDR3 的初始化配置。
④、用户代码可执行文件,比如 led.bin。
可以看出最终烧写到 I.MX6U 中的程序其组成为:IVT+Boot data+DCD+.bin。所以第八章中的 imxdownload 所生成的 load.imx 就是在 led.bin 前面加上 IVT+Boot data+DCD。内部 BootROM 会将 load.imx 拷贝到 DDR 中,用户代码是要一定要从0X87800000 这个地方开始的,因为链接地址为 0X87800000,load.imx 在用户代码前面又有 3KByte 的 IVT+Boot Data+DCD 数据。
如上,NXP对于不同的启动方式有不同的存储偏移量,以及整个头部大小的定义,从SD卡启动时,读取偏移地址为1KB,恰好时SD卡2个块大小,正是这2个块包含了分区信息。然后时头部数据4K-1K=3KB,占用了6个块(也就是说第3-8个块包含头部信息),从第九个块写入bin文件。
const int imx6_512mb_ivtdcd_table[256] = { 0X402000D1,0X87800000,0X00000000,0X877FF42C,0X877FF420,0X877FF400,0X00000000,0X00000000, 0X877FF000,0X00200000,0X00000000,0X40E801D2,0X04E401CC,0X68400C02,0XFFFFFFFF,0X6C400C02, 0XFFFFFFFF,0X70400C02,0XFFFFFFFF,0X74400C02,0XFFFFFFFF,0X78400C02,0XFFFFFFFF,0X7C400C02, 0XFFFFFFFF,0X80400C02,0XFFFFFFFF,0XB4040E02,0X00000C00,0XAC040E02,0X00000000,0X7C020E02, 0X30000000,0X50020E02,0X30000000,0X4C020E02,0X30000000,0X90040E02,0X30000000,0X88020E02, 0X30000C00,0X70020E02,0X00000000,0X60020E02,0X30000000,0X64020E02,0X30000000,0XA0040E02, 0X30000000,0X94040E02,0X00000200,0X80020E02,0X30000000,0X84020E02,0X30000000,0XB0040E02, 0X00000200,0X98040E02,0X30000000,0XA4040E02,0X30000000,0X44020E02,0X30000000,0X48020E02, 0X30000000,0X1C001B02,0X00800000,0X00081B02,0X030039A1,0X0C081B02,0X0B000300,0X3C081B02, 0X44014801,0X48081B02,0X302C4040,0X50081B02,0X343E4040,0X1C081B02,0X33333333,0X20081B02, 0X33333333,0X2C081B02,0X333333F3,0X30081B02,0X333333F3,0XC0081B02,0X09409400,0XB8081B02, 0X00080000,0X04001B02,0X2D000200,0X08001B02,0X3030331B,0X0C001B02,0XF3526B67,0X10001B02, 0X630B6DB6,0X14001B02,0XDB00FF01,0X18001B02,0X40172000,0X1C001B02,0X00800000,0X2C001B02, 0XD2260000,0X30001B02,0X23106B00,0X40001B02,0X4F000000,0X00001B02,0X00001884,0X90081B02, 0X00004000,0X1C001B02,0X32800002,0X1C001B02,0X33800000,0X1C001B02,0X31800400,0X1C001B02, 0X30802015,0X1C001B02,0X40800004,0X20001B02,0X00080000,0X18081B02,0X27020000,0X04001B02, 0X2D550200,0X04041B02,0X06100100,0X1C001B02,0X00000000};
上面就是imxdownload在bin文件前增加的头部信息一共256(int)*4=1KB,一共有256个u32数据,实际应该时3KB,但是后面都是0故这里只申请了1KB。
①、Image vector table,简称 IVT(32B 8个int),第一行全部(小端)
header 0X402000D1 第一个字节 Tag 为0XD1,第二三这两个字节为 IVT 大小,为大端模式,所以 IVT 大小为 0X20=32 字节。第四个字节为 0X40
entry 0X87800000 入口DDR地址,也就是镜像第一行指令所在的DDR位置。0X87800000 就是我们的链接地址。
reserved1 0X00000000 未使用,保留。
dcd 0X877FF42C DCD DDR开始地址。
boot data 0X877FF420 boot DDR开始地址,header 里面已经设置了 IVT 大小是 32个 字 节 ,所 以 boot data 的地址就是=0X877FF420。
self 0X877FF400 IVT DDR开始地址。
csf 0X00000000 CSF 地址。
reserved2 0X00000000 保留,未使用。
②、Boot data(12B 3个int),第二行开始3个int(小端)
start 0X877FF000 load.imx 的DDR开始地址=self-1KB,包括前面 1KByte 的地址偏移。
length 0X00200000 镜像大小,这里设置 2MByte。镜像大小不能超过2MByte。
plugin 0X00000000 插件。
③、Device configuration data,简称 DCD 第二行第4个int 开始,前2个是控制(小端),后面全部是(大段)
复位以后,I.MX6U 片内的所有寄存器都会复位为默认值,但是这些默认值往往不是我们想要的值,而且有些外设我们必须在使用之前初始化它。Boot ROM 会使用这些寄存器地址和配置集合来初始化相应的寄存器,比如开启某些外设的时钟、初始化 DDR 等等。DCD 区域不能超过 1768Byte
header 0X40E801D2 第一个字节 Tag 为 0XD2,第二和三这两个字节为 DCD 大小(大段)为 0X01E8=488 字节。第四个字节为 0X40。
WriteData Command 0X04E401CC 第一个为 Tag,固定为 0XCC,第二和三这两个字节是长度(大段),为 0X01E4=484 个字节。第四个字节是 Parameter,为 0X04,表示目标位置宽度为 4 个字节。
后续就是各种寄存器的赋值