野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 28280|回复: 0

[经验\资料] i.MX6系列SD卡烧写原理分析及源码讲解

[复制链接]
发表于 2021-2-26 14:56:14 | 显示全部楼层 |阅读模式
最近用i.MX6ULL的时候,发现LCD刷新率跟不上(不知道是自己能力不行还是RGB本身就是慢),研究了NXP官方的一些资料后,发现6D系列支持MIPI的屏幕,而且是两路,主频也比6U快,双核结构,支持OpenGL3.1,简直是爽的不要不要的!可惜,火哥家没有,某宝中找到了飞凌嵌入式的OKMX6DL-C这个型号的板子,但用6ULL的烧写器烧写裸机程序无法启动,我想可能是启动地址问题导致的,这个后期可以找原理图确认一下。飞凌比火哥还懒,下载器只有官方提供的那个好几百M的,每次烧写必须把u-boot到根文件系统都搞一遍,反正我研究了好久也没搞明白他这个怎么烧裸机程序。于是想用正点原子的下载器改一版,但竟然找不到他源码放哪了!明明记得当初教程中他们说有源码的,而且我印象中还看过,用的时候找不到了!
还是自己写吧!顺便把自己写下载器的心得整理出来分享给大家。
这个烧录器我再6U和6D、6Q上都测试过,都能使用,其他型号和系列的芯片没做试验,有条件的自己做吧,我看NXP官方文档的启动过程都差不多。
一、 i.MXSD卡启动分析
在烧录U-Boot的时候,U-Boot交叉编译生成了u-boot.bin文件,但是这文件直接烧录到SD卡或者eMMC中是启动不了的,需要添加一个启动头信息,头信息中包含IVT、BootData、DCD三部分数据,然后下面才是我们用户编译的bin文件信息。
我参考的是NXP官方提供的IMX6 processor ref manual.pdf这个文件(像老太太的裹脚布一样——又臭又长,而且还是纯英文的,像我这种小本毕业的,读起来真费劲!)。
文件Chapter8:System Boot -> Program image 8.6一节中说明了镜像文件应该包含的内容:
00.png
英文能力好的大神们直接阅读原文吧,这里简单介绍一下各项。
IVT(Image vector table)
这是个镜像启动的向量表,可以参照STM32和8051的中断向量表理解(但这个不是中断向量表),这个向量表一共包含8项内容,每项内容占用4个字节的空间:
01.png
header:IVT的头信息,包含1字节的Tag、2字节的Length、1字节的Version,及其中Tag固定为0XD1,Version为0x40或者0x41,Length表示IVT的大小,采用大端模式存放数据,长度是固定为32字节(两个字节,大端模式表示为0x0020)。
enter:镜像执行第一条指令的绝对地址,就是代码和数据区的起始地址,实际设置为0x87800000。
dcd:镜像DCD段的绝对地址,如果不需要DCD,这一段设置为NULL。
boot data:Boot Data段的绝对地址,
self:本身的绝对起始地址,也就是IVT段的起始地址。
csf:HAB库使用的命令序列文件(CSF)的绝对地址,不执行安全引导时,此字段必须设置为NULL。
另外还有两个预留的空位。
Boot Data
启动数据段,包含了镜像要拷贝到那个地址,拷贝大小是多少等信息。
02.png
镜像文件的其实质:start = entry - 0x1000
镜像文件的大小:length,这个值可以随便给,只要比实际的镜像头文件大就可以了,但最大不能超过0x200000,也就是2Mbyte。
DCD(Device configuration data)
设备配置表,用来初始化系统时钟,DDR等设备信息,总体不能超过1786字节,其中重要的两项内容是header和cmd。
head是DCD头信息,包含1字节的Tag(0xD2)、2字节的Length(大端模式)和1字节的Version(0x41)。
cmd为命令区域支持多种命令,每个CMD也有头部信息。
官方文档中举了Write data 这个命令,在文档中Chapter8:System Boot -> Program image 8.6.2.1章节。
DCD CMD命令格式如下表所示:
03.png
Tag:1字节,固定为0XCC。
Length:2字节,包含header在内的写入命令的总体长度,采用大端模式存储。
Parameter:1字节,bytes表示目标位置宽度,可选1、2、4字节,flags是命令控制标志位。
04.png
DCD就是所有这些命令的一个集合。
二、 .imx文件头分析
因为关于头文件的资料极少,我参考了正点原子关于i.MX6ULL的文档、NXP官方文档和网上大牛写的一些东西,并且找到了i.XM6DL所生成的U-Boot烧录.imx文件进行综合分析,给大家填填坑。
06.png
以上内容是i.MX6DL生成的U-Boot.imx文件的十六进制格式片段。
我还分析了正点原子的i.MX6ULL的.imx文件,启动地址略有不同(这就是为啥一开始我用正点原子提供的下载器下载不启动的原因吧),我们以i.MX6DL这个为例详细解说一下,也当自己回顾了。
前面32个字节是IVT部分大端模式存储,分别是:
[size=12.0000pt]段
数据
解释
header
D1 00 20 40
tag:0xD1,length:0x2000,version:0x40
enter
00 00 80 17
也就是起始地址为0x17800000
保留
00 00 00 00
[size=10.5000pt]
dcd
2C F4 7F 17
实际DCD起始地址为:0x177FF42C,我们镜像地址是0x17800000,IVT + Boot Data + DCD整个大小是3Kbyte,所以load.imx的起始地址就是0x17800000 - 0xC00=0x177FF400。因此,DCD起始地址相对于load.imx起始地址偏移就是0x177FF42C - 177FF400 = 0x2C,就是说从,0x2C这个地址开始就是DCD的所有数据(图中第三行D2 02 F0 40的位置)。
boot data
20 F4 7F 17
Boot Data实际起始地址:0x177FF420,镜像起始地址是0x17800000,IVT + Boot Data + DCD整个大小是3Kbyte,所以load.imx的起始地址就是0x17800000 - 0xC00=0x177FF400。Boot Data段是紧随在IVT之后的,所以0x177FF400 + 32字节就是Boot Data实际起始地址。0x177FF400 + 0x20 = 0x177FF420。
sefl
00 F4 7F 17  
IVT复制到DDR以后的首地址。
csf
00 00 00 00
CSF地址,没用到
保留
00 00 00 00
00 00 00 00
下面紧随的12字节是BootData段:
[size=12.0000pt]段
数据
解释
start
00 F0 7F 17
整个.imx文件的起始地址,包含前面的1Kbyte的偏移地址,entry - 0x1000=0x17800000 - 0x1000 = 0x177FF000
length
00 90 07 00
镜像的大小,按理说不能超过2Mbyte就可以,这里设置的是0x79000,也就是484K,这个值后面我想能定设置为0x00200000。
plugin
00 00 00 00
插件,没用
下面分析DCD段的内容:
前面一段中已经说过,DCD段也是以header开头的,然后紧随其后的是Address表示要初始化寄存器的地址,Value/Mask是相应的寄存器初始化值,这些采用的都是大端模式。
[size=12.0000pt]段
数据
解释
header
D2 02 F0 40
tag:0xD2,version:0x40,length:0x02F0(752字节),这里的长度用的是小段模式的
Write Data Commadn
CC 02 EC 04
tag:0xCC,parameter:0x04,第二三个字节大端模式表示这条指令的长度0x02EC(784字节),这里的长度用的也是小段模式的
Address
02 0E 07 74
0x74070E02,寄存器地址(具体是啥没查,大概也就是CCGR一类的寄存器)
Value
00 0C 00 00
写入寄存器的内容
Address
02 0E 07 54
0x54070E02
Value
00 00 00 00
写入寄存器的内容
……
[size=10.5000pt]
[size=10.5000pt]
基本上后面跟的都是这些指令,DCD段长度是0xF002(61442字节),但实际上后面大部分内容都是空的,一直到0xC00开始,才是真正的U-Boot的.bin文件内容。
三、 编写imxdownload命令
我们编写的imxdownload命令共需要完成两个任务:
        1. 添加头文件信息,生成.imx文件
        2. 将文件烧入到SD卡中
i.MX支持多种设备启动,以下是各种启动方式IVT的偏移。
07.png
表中SD卡、eMMC等设备的偏移地址是1Kbyte,初始化加载区域的的总大小是4Kbyte,根绝这段话可以得出,IVT+Boot的总大小实际为3Kbyte(4Kbyte-3Kbyte),加入SD卡每个扇区为512字节,那么最后我们烧入系统的启动文件应该从第三个扇区开始烧,一共要烧写6个分区,从第九个分区(也就是烧录文件的第3Kbyte)开始才是真正要烧入的.bin文件。
烧录命令在Linux下直接使用dd命令烧写
sudo dd iflag=dsync oflag=dsync if=load.imx of=/dev/sdb bs=512 seek=2
关于dd命令
Linux dd 命令用于读取、转换并输出数据,dd 可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。
参数说明:
l if=文件名:输入文件名,默认为标准输入。即指定源文件
l of=文件名:输出文件名,默认为标准输出。即指定目的文件
l ibs=bytes:一次读入bytes个字节,即指定一个块大小为bytes个字节
l obs=bytes:一次输出bytes个字节,即指定一个块大小为bytes个字节
l bs=bytes:同时设置读入/输出的块大小为bytes个字节
l cbs=bytes:一次转换bytes个字节,即指定转换缓冲区大小
l skip=blocks:从输入文件开头跳过blocks个块后再开始复制
l seek=blocks:从输出文件开头跳过blocks个块后再开始复制
l count=blocks:仅拷贝blocks个块,块大小等于ibs指定的字节数
l conv=<关键字>
n conversion:用指定的参数转换文件
n ascii:转换ebcdic为ascii
n ebcdic:转换ascii为ebcdic
n ibm:转换ascii为alternate ebcdic
n block:把每一行转换为长度为cbs,不足部分用空格填充
n unblock:使每一行的长度都为cbs,不足部分用空格填充
n lcase:把大写字符转换为小写字符
n ucase:把小写字符转换为大写字符
n swap:交换输入的每对字节
n noerror:出错时不停止
n notrunc:不截短输出文件
n sync:将每个输入块填充到ibs个字节,不足部分用空(NUL)字符补齐
l iflag/oflag=<关键字>
n append:追加模式(仅对输出有意义,隐含了conv=notrunc)
n direct:使用直接I/O 存取模式
n directory:除非是目录,否则 directory 失败
n dsync:使用同步I/O 存取模式
n sync:使用同步I/O 存取模式,但同时也对元数据生效
n fullblock:为输入积累完整块(仅iflag)
n nonblock:使用无阻塞I/O 存取模式
n noatime:不更新存取时间
n nocache:丢弃缓存数据
n noctty:不根据文件指派控制终端
n nofollow:不跟随链接文件
l –help:显示帮助信息
l –version:显示版本信息
四、 代码
婚前理论都清楚了,拖鞋上炕吧,开始撸码。
这个下载器我打算分两部分写,一部分是读取官方标准.imx文件头信息的,把这部分头信息转换为.h文件,另外一部分是下载器。这样方便在各个不同类型芯片中移植。
imxdownload.c
  1. /****************************************************************
  2. * i.MX系列芯片裸机程序烧录器
  3. * Copyright (C) 2021 Mars.CN suolong123@126.com
  4. *
  5. * 改程序用于i.MX6系列芯片的程序烧录,
  6. * 只在i.MX6ULL和6DL、6Q的芯片中测试过,i.MX其他型号芯片未经测试,
  7. * 但按照NXP官方文档的描述,只需要修改本IVT、BootData和DCD部分一样可用。
  8. *
  9. * 源代码分为两部分,.c文件包含了原始imx文件头读取和SD卡烧录两个功能,
  10. * 但其中需要用到一个.h文件,这个文件中记录了IMX头信息及相关地址,
  11. * .h文件可以通过调用imxdownload -r u-boot.imx imx6dl.h这样的命令生成
  12. * 经过测试,6U、6D、6Q等芯片的启动地址不一样,并且不同内存大小的DCD部分
  13. * 也有所不同,所以头文件不能通用,最好的办法就是找到官方提供对应原始imx文件,
  14. * 通过上面的命令将头信息反出来。
  15. *
  16. * 无论是U-Boot,还是自己写的裸机程序,生成原始bin文件后,都可以通过:
  17. * imxdownload u-boot.bin /dev/sdb
  18. * 的命令进行SD卡烧写。
  19. *
  20. * 烧录SD代码分为两部分:
  21. * 第一部分是根据头文件生成imx_load.imx文件,这个文件是加入IMX头信息的,
  22. * 包含32字节的IVT、3字节的Boot Data,以及不固定长度的DCD部分。
  23. * 第二部分是将imx_load.imx文件烧录到SD卡中,用的是Linux的dd命令
  24. * sudo dd iflag=dsync oflag=dsync if=%s of=%s bs=512 seek=2
  25. * 根据NXP官方文档中描述,烧写SD卡要偏移1Kbyte,bs=512 seek=2用于偏移
  26. *
  27. * 注意:野火和正点原子的板子用的是TF卡(小卡)启动,
  28. * 飞凌的板子虽然也有个差TF卡的位置,但他用的是SD卡(大卡)启动,
  29. * 所以位置搞错了肯定起不来,在此耗费2天时间,大意了……
  30. *
  31. * PS:英文提示纯属机翻,如有异议请憋回去!
  32. *
  33. * 该下载器参考资料:
  34. * NXP官方,i.MX6DL文档 《IMX6 processor ref manual.pdf》
  35. * 正点原子《I.MX6U嵌入式Linux驱动开发指南V1.5.pdf》
  36. * njcy写的《i.MX6ULL下载工具imxdownload分析》
  37. * https://blog.csdn.net/weixin_39869569/article/details/113390184
  38. *
  39. *
  40. * @file    imxdownload.c
  41. * [url=home.php?mod=space&uid=41770]@brief[/url]   i.MX烧录程序
  42. * @author  Mars.CN
  43. * @email   suolong123@126.com
  44. * @version 1.0.0.1
  45. * @license GNU General Public License (GPL)
  46. *
  47. *---------------------------------------------------------------
  48. * Change History :
  49. * <Date>     | <Version>     | <Author>    | <Description>
  50. *---------------------------------------------------------------
  51. * 2021/02/25 | 1.0.0.1       | Mars.CN     | Create file
  52. *---------------------------------------------------------------
  53. *
  54. ****************************************************************/
  55. #include <stdio.h>
  56. #include <stdlib.h>
  57. #include <string.h>
  58. #include <unistd.h>

  59. #include "imx6dl.h"     // 要生成对应芯片的头文件信息

  60. #define LOG_D(...)      \
  61. do \
  62. { \
  63.     printf(__VA_ARGS__); \
  64.     printf("\r\n"); \
  65. } while(0);

  66. #define IVT_SIZE 32
  67. #define BTD_SIZE 12
  68. #define IMX_FILE "imx_load.imx"

  69. void help();
  70. void make_header(char *imx, char *h);
  71. void bind_imx(char *b);
  72. void write_sd(char *device);

  73. int main( int argc, char *argv[] )
  74. {
  75.     if(argc > 2){
  76.         if(0 == strcmp(argv[1], "-r")){
  77.             // 读取imx头信息,并生成.h文件
  78.             if(4 == argc){
  79.                 make_header(argv[2], argv[3]);
  80.                 goto __exit;
  81.             }
  82.         }else{
  83.             // 判断设备是否存在
  84.             if(0 == access(argv[2], F_OK)){
  85.                 bind_imx(argv[1]);
  86.                 write_sd(argv[2]);
  87.             }else{
  88.                 LOG_D("Can't open sd device : %s!\n", argv[2]);
  89.             }
  90.             goto __exit;
  91.         }
  92.     }
  93.     help();
  94. __exit:
  95.     return 0;
  96. }

  97. /**
  98. * @brief   根据.imx文件生成头文件
  99. * @param   [in] *imx   原始的.imx文件
  100. * @param   [in] *h     要生成的C语言头文件存放地址
  101. *
  102. * @remarks
  103. * 该函数用于辅助工具生成C语言用到的.h头文件,
  104. * 文件中包含了生成.imx文件所用到的IVT、Boot Data和DCD段信息
  105. * 该函数是为了方便开发人员制作针对性的下载器,
  106. * 所以生成的头文件不能单独使用,需要修改imxdownload.c中引用,
  107. * 并重新编译imxdownload.c文件才可使用。
  108. */
  109. void make_header(char *imx, char *h)
  110. {
  111. // 判断.imx文件是否存在
  112.     int i=0;
  113.     FILE *s_fp = NULL;
  114.     FILE *d_fp = NULL;
  115.     unsigned char *r_ivt = NULL;    // 存放读出的IVT数据
  116.     unsigned char *r_btd = NULL;    // 存放读出的BootData数据
  117.     unsigned char *r_dcd = NULL;    // 存放读出的DCD数据
  118.     unsigned int r_dcd_length = 0;
  119.     unsigned int tab_size = 0;      // 头文件需要写入大小(sizeof(int))
  120.     s_fp = fopen(imx, "rb");
  121.     if(NULL != s_fp){
  122.         LOG_D("Start constructing header file...\n");
  123.         // LOG_D("File size : %ld\n", ftell(fp));
  124.         r_ivt = calloc(IVT_SIZE,1);   // IVT大小32字节
  125.         r_btd = calloc(BTD_SIZE,1);   // BootData大小12字节

  126.         LOG_D("Read IMX header file information...\n");
  127.         // printf("大小: %ld , %ld , %d\n", sizeof(r_ivt), sizeof(char), IVT_SIZE);
  128.         // 读出IVT信息
  129.         fgets(r_ivt, IVT_SIZE+1, (FILE*)s_fp);
  130.         // 读出BootData信息
  131.         fgets(r_btd, BTD_SIZE+1, (FILE*)s_fp);

  132.         // 读取DCD数据,先从后面第2,3字节中获得长度,然后创建固定位大小的DCD区域
  133.         // 向后移动一个指针,并读取
  134.         fseek(s_fp,1,SEEK_CUR);
  135.         r_dcd_length = fgetc(s_fp);
  136.         r_dcd_length <<= 8;
  137.         r_dcd_length |= fgetc(s_fp);
  138.         r_dcd = calloc(r_dcd_length, 1);
  139.         fseek(s_fp, -3, SEEK_CUR);
  140.         fgets(r_dcd, r_dcd_length+1, (FILE*)s_fp);
  141.         tab_size = (IVT_SIZE + BTD_SIZE + r_dcd_length)/4;
  142.         // 开始制作头文件
  143.         d_fp = fopen(h, "w");
  144.         // 写入头信息
  145.         fputs("#ifndef __IMX_HEADER_\n", d_fp);
  146.         fputs("#define __IMX_HEADER_\n\n", d_fp);
  147.         
  148.         fputs("#define ADDR_ENTRY\t\t", d_fp);
  149.         fprintf(d_fp, "(0x%02X%02X%02X%02X)\n", r_ivt[7], r_ivt[6], r_ivt[5], r_ivt[4]);
  150.         fputs("#define ADDR_SELF\t\t(ADDR_ENTRY - 3*1024)\n", d_fp);
  151.         fputs("#define ADDR_START\t\t(ADDR_ENTRY - 4*1024)\n", d_fp);
  152.         fputs("#define ADDR_DCD\t\t(ADDR_SELF + 0x2C)\n", d_fp);
  153.         fputs("#define ADDR_BOOT\t\t(ADDR_SELF + 0x20)\n", d_fp);
  154.         fputs("#define IMAGE_SIZE\t\t(0x00200000)\n", d_fp);             // 这个值随便写,比镜像文件大就行,但最大不能超过2Mbyte
  155.         fprintf(d_fp, "#define TAB_SIZE\t\t%d\n\n", tab_size);
  156.         fputs("const int _h_imx6_ivt_dcd_tbl[TAB_SIZE] =\n{\n", d_fp);
  157.         fputs("\t0X402000D1,ADDR_ENTRY,0X00000000,ADDR_DCD,  ADDR_BOOT, ADDR_SELF, 0X00000000,0X00000000,\n", d_fp);
  158.         fputs("\tADDR_START,IMAGE_SIZE,0X00000000,\n\t", d_fp);
  159.         for(i=0; i<r_dcd_length; i+=4){
  160.             fprintf(d_fp, "0x%02X%02X%02X%02X,", r_dcd[i+3], r_dcd[i+2], r_dcd[i+1], r_dcd[i]);
  161.             if(28 == i%32){fputs("\n\t", d_fp);}
  162.         }
  163.         fputs("\n};\n", d_fp);
  164.         
  165.         fputs("\n#endif /* __IMX_HEADER_ */\n", d_fp);
  166.         fclose(d_fp);

  167.         LOG_D("Entry address : 0x%02X%02X%02X%02X\n", r_ivt[7], r_ivt[6], r_ivt[5], r_ivt[4]);
  168.         LOG_D("Header file generation complete!\n\nfile path : %s \n", h);
  169.         // 清理残渣
  170.         free(r_ivt);
  171.         free(r_btd);
  172.         free(r_dcd);
  173.     }else{
  174.         LOG_D("IMX source file does not exist!");
  175.     }
  176.     fclose(s_fp);
  177. }

  178. /**
  179. * @brief   构造用于烧写的.imx文件
  180. * @param   [in] *b     原始的.bin格式文件
  181. *
  182. * @remarks
  183. * 该函数会生成一个供i.MX平台烧写的.imx文件(名称无所谓,强迫症可以修改IMX_FILE),
  184. * 文件中前3Kbyte的内容是IVT + Boot Data + DCD内容,
  185. * 从0xC00开始为正式的bin文件内容,
  186. * 生成后的.imx文件可以直接烧到SD卡或eMMC中,SD卡烧写需要偏移1Kbyte
  187. */
  188. void bind_imx(char *b){
  189.    
  190.     FILE *s_fp;
  191.     FILE *d_fp;
  192.     int s_fle_length = 0;    // bin文件长度
  193.     unsigned int offset = 1024*3;   // bin 文件写入偏移
  194.     unsigned char *buf;
  195.     s_fp = fopen(b, "rb");
  196.     if(NULL != s_fp){
  197.         LOG_D("Read bin file content...\n");
  198.         fseek(s_fp, 0, SEEK_END);
  199.         // 获取文件长度
  200.         s_fle_length = ftell(s_fp);
  201.         LOG_D("Bin file size: %d Bytes\n", s_fle_length);
  202.         // 构建输出
  203.         buf = calloc(s_fle_length + offset,1);
  204.         memset(buf, 0, s_fle_length + offset);
  205.         fseek(s_fp, 0, SEEK_SET);
  206.         fread(&buf[offset], 1, s_fle_length, s_fp);
  207.         // 合并数组
  208.         memcpy(buf, _h_imx6_ivt_dcd_tbl, sizeof(_h_imx6_ivt_dcd_tbl));
  209.         LOG_D("Create new IMX file...\n");
  210.         d_fp = fopen(IMX_FILE, "wb");
  211.         if(NULL != d_fp){
  212.             fwrite(buf, 1, s_fle_length + offset, d_fp);
  213.             fclose(d_fp);
  214.             LOG_D("IMX file generation completed!\n");
  215.             LOG_D("IMX file path : %s!\n", IMX_FILE);
  216.         }else{
  217.             LOG_D("Failed to create file!\n");
  218.         }

  219.         // 清理残渣
  220.         free(buf);
  221.     }else{
  222.         LOG_D("Bin file does not exist!\n");
  223.     }
  224. }

  225. /**
  226. * @brief   将imx文件烧写到SD卡中
  227. * @param   [in] device SD卡的设备文件,一般为/dev/sd*
  228. *
  229. * @remarks
  230. * 该函数用于将生成好的.imx文件烧录到SD卡中,使用Linux的dd命令
  231. * dd命令参数如下:
  232. *      iflag   使用同步I/O模式进行内容读取
  233. *      oflag   使用同步I/O模式进行内容输出
  234. *      if      要读取的内容,这里指.imx文件
  235. *      of      要输出的设备或文件,这里指SD卡
  236. *      bs      输出的块大小,单位是byte
  237. *      seek    偏移块,i.MX6烧写SD卡官方资料提示需要偏移1Kbyte,所以设置为2
  238. */
  239. void write_sd(char *device)
  240. {
  241.     // 调用dd命令写入SD卡
  242.     char * dd;
  243.     sprintf(dd, "sudo dd iflag=dsync oflag=dsync if=%s of=%s bs=512 seek=2", IMX_FILE, device);
  244.     LOG_D("Download %s to %s ...\n", IMX_FILE, device);
  245.     system(dd);
  246.     LOG_D("\nSD card writing completed!\n");
  247. }

  248. /**
  249. * @brief   帮助信息输出
  250. */
  251. void help()
  252. {
  253.     LOG_D("\nimxdownload [-h] [-r] <source_bin> <target>\n");
  254.     LOG_D("\tThis command is used to write the bin file obtained by cross compilation ");
  255.     LOG_D("\tto SD card to support the startup of i.mx6 series chips. Before writing, ");
  256.     LOG_D("\tthe IVT, boot data and DCD information of IMX will be inserted in front of the bin file. ");
  257.     LOG_D("\tThe above information comes from the official IMX header information. ");
  258.     LOG_D("\tThe official IMX file header information can be read through the -r parameter.\n");
  259.     LOG_D("\t-h           View command help information\n");
  260.     LOG_D("\t-r           Read the header information of the official IMX file and generate the header file .\n");
  261.     LOG_D("\t             If the parameter does not exist, <source_ Bin> indicates the IMX file to read the header information .\n");
  262.     LOG_D("\t             If the parameter exists, <source_ Bin> indicates the bin file to be written to the SD card .\n");
  263.     LOG_D("\tsource_bin   To write to the bin file of the SD card, or to read the IMX file of the header information .\n");
  264.     LOG_D("\ttarget       SD card device file to write or C language header file to save IMX header information .\n");
  265. }
复制代码
imx6dl.h
  1. #ifndef __IMX_HEADER_
  2. #define __IMX_HEADER_

  3. #define ADDR_ENTRY                (0x17800000)
  4. #define ADDR_SELF                (ADDR_ENTRY - 3*1024)
  5. #define ADDR_START                (ADDR_ENTRY - 4*1024)
  6. #define ADDR_DCD                (ADDR_SELF + 0x2C)
  7. #define ADDR_BOOT                (ADDR_SELF + 0x20)
  8. #define IMAGE_SIZE                (0x00200000)
  9. #define TAB_SIZE                199

  10. const int _h_imx6_ivt_dcd_tbl[TAB_SIZE] =
  11. {
  12.         0X402000D1,ADDR_ENTRY,0X00000000,ADDR_DCD,  ADDR_BOOT, ADDR_SELF, 0X00000000,0X00000000,
  13.         ADDR_START,IMAGE_SIZE,0X00000000,
  14.         0x40F002D2,0x04EC02CC,0x74070E02,0x00000C00,0x54070E02,0x00000000,0xAC040E02,0x30000000,
  15.         0xB0040E02,0x30000000,0x64040E02,0x30000000,0x90040E02,0x30000000,0x4C070E02,0x30000000,
  16.         0x94040E02,0x30000000,0xA0040E02,0x00000000,0xB4040E02,0x30000000,0xB8040E02,0x30000000,
  17.         0x6C070E02,0x30000000,0x50070E02,0x00000200,0xBC040E02,0x30000000,0xC0040E02,0x30000000,
  18.         0xC4040E02,0x30000000,0xC8040E02,0x30000000,0xCC040E02,0x30000000,0xD0040E02,0x30000000,
  19.         0xD4040E02,0x30000000,0xD8040E02,0x30000000,0x60070E02,0x00000200,0x64070E02,0x30000000,
  20.         0x70070E02,0x30000000,0x78070E02,0x30000000,0x7C070E02,0x30000000,0x80070E02,0x30000000,
  21.         0x84070E02,0x30000000,0x8C070E02,0x30000000,0x48070E02,0x30000000,0x70040E02,0x30000000,
  22.         0x74040E02,0x30000000,0x78040E02,0x30000000,0x7C040E02,0x30000000,0x80040E02,0x30000000,
  23.         0x84040E02,0x30000000,0x88040E02,0x30000000,0x8C040E02,0x30000000,0x00081B02,0x030039A1,
  24.         0x0C081B02,0x78006C00,0x10081B02,0x4A004D00,0x0C481B02,0x40003800,0x10481B02,0x44002F00,
  25.         0x3C081B02,0x28022D42,0x40081B02,0x0B020002,0x3C481B02,0x07020342,0x40481B02,0x5D015801,
  26.         0x48081B02,0x46474543,0x48481B02,0x40474444,0x50081B02,0x31303637,0x50481B02,0x2F343235,
  27.         0x1C081B02,0x33333333,0x20081B02,0x33333333,0x24081B02,0x33333333,0x28081B02,0x33333333,
  28.         0x1C481B02,0x33333333,0x20481B02,0x33333333,0x24481B02,0x33333333,0x28481B02,0x33333333,
  29.         0xB8081B02,0x00080000,0xB8481B02,0x00080000,0x04001B02,0x2D000200,0x08001B02,0x4030331B,
  30.         0x0C001B02,0xB352433F,0x10001B02,0x638B6DB6,0x14001B02,0xDB00FF01,0x18001B02,0x40170100,
  31.         0x1C001B02,0x00800000,0x2C001B02,0xD2260000,0x30001B02,0x23104300,0x40001B02,0x27000000,
  32.         0x00001B02,0x00001A83,0x1C001B02,0x32800004,0x1C001B02,0x33800000,0x1C001B02,0x31800400,
  33.         0x1C001B02,0x30802005,0x1C001B02,0x40800004,0x20001B02,0x00580000,0x18081B02,0x17110100,
  34.         0x18481B02,0x17110100,0x04001B02,0x6D550200,0x04041B02,0x06100100,0x1C001B02,0x00000000,
  35.         0x68400C02,0x3F3FC000,0x6C400C02,0x03FC3000,0x70400C02,0x00C0FF0F,0x74400C02,0x0000F03F,
  36.         0x78400C02,0x00F3FF00,0x7C400C02,0xC300000F,0x80400C02,0xFF030000,0x10000E02,0xCF0000F0,
  37.         0x18000E02,0x7F007F00,0x1C000E02,0x7F007F00,
  38. };

  39. #endif /* __IMX_HEADER_ */
复制代码
imx6ull.h
  1. #ifndef __IMX_HEADER_
  2. #define __IMX_HEADER_

  3. #define ADDR_ENTRY                (0x17800000)
  4. #define ADDR_SELF                (ADDR_ENTRY - 3*1024)
  5. #define ADDR_START                (ADDR_ENTRY - 4*1024)
  6. #define ADDR_DCD                (ADDR_SELF + 0x2C)
  7. #define ADDR_BOOT                (ADDR_SELF + 0x20)
  8. #define IMAGE_SIZE                (0x00200000)
  9. #define TAB_SIZE                199

  10. const int _h_imx6_ivt_dcd_tbl[TAB_SIZE] =
  11. {
  12.         0X402000D1,ADDR_ENTRY,0X00000000,ADDR_DCD,  ADDR_BOOT, ADDR_SELF, 0X00000000,0X00000000,
  13.         ADDR_START,IMAGE_SIZE,0X00000000,
  14.         0x40F002D2,0x04EC02CC,0x74070E02,0x00000C00,0x54070E02,0x00000000,0xAC040E02,0x30000000,
  15.         0xB0040E02,0x30000000,0x64040E02,0x30000000,0x90040E02,0x30000000,0x4C070E02,0x30000000,
  16.         0x94040E02,0x30000000,0xA0040E02,0x00000000,0xB4040E02,0x30000000,0xB8040E02,0x30000000,
  17.         0x6C070E02,0x30000000,0x50070E02,0x00000200,0xBC040E02,0x30000000,0xC0040E02,0x30000000,
  18.         0xC4040E02,0x30000000,0xC8040E02,0x30000000,0xCC040E02,0x30000000,0xD0040E02,0x30000000,
  19.         0xD4040E02,0x30000000,0xD8040E02,0x30000000,0x60070E02,0x00000200,0x64070E02,0x30000000,
  20.         0x70070E02,0x30000000,0x78070E02,0x30000000,0x7C070E02,0x30000000,0x80070E02,0x30000000,
  21.         0x84070E02,0x30000000,0x8C070E02,0x30000000,0x48070E02,0x30000000,0x70040E02,0x30000000,
  22.         0x74040E02,0x30000000,0x78040E02,0x30000000,0x7C040E02,0x30000000,0x80040E02,0x30000000,
  23.         0x84040E02,0x30000000,0x88040E02,0x30000000,0x8C040E02,0x30000000,0x00081B02,0x030039A1,
  24.         0x0C081B02,0x78006C00,0x10081B02,0x4A004D00,0x0C481B02,0x40003800,0x10481B02,0x44002F00,
  25.         0x3C081B02,0x28022D42,0x40081B02,0x0B020002,0x3C481B02,0x07020342,0x40481B02,0x5D015801,
  26.         0x48081B02,0x46474543,0x48481B02,0x40474444,0x50081B02,0x31303637,0x50481B02,0x2F343235,
  27.         0x1C081B02,0x33333333,0x20081B02,0x33333333,0x24081B02,0x33333333,0x28081B02,0x33333333,
  28.         0x1C481B02,0x33333333,0x20481B02,0x33333333,0x24481B02,0x33333333,0x28481B02,0x33333333,
  29.         0xB8081B02,0x00080000,0xB8481B02,0x00080000,0x04001B02,0x2D000200,0x08001B02,0x4030331B,
  30.         0x0C001B02,0xB352433F,0x10001B02,0x638B6DB6,0x14001B02,0xDB00FF01,0x18001B02,0x40170100,
  31.         0x1C001B02,0x00800000,0x2C001B02,0xD2260000,0x30001B02,0x23104300,0x40001B02,0x27000000,
  32.         0x00001B02,0x00001A83,0x1C001B02,0x32800004,0x1C001B02,0x33800000,0x1C001B02,0x31800400,
  33.         0x1C001B02,0x30802005,0x1C001B02,0x40800004,0x20001B02,0x00580000,0x18081B02,0x17110100,
  34.         0x18481B02,0x17110100,0x04001B02,0x6D550200,0x04041B02,0x06100100,0x1C001B02,0x00000000,
  35.         0x68400C02,0x3F3FC000,0x6C400C02,0x03FC3000,0x70400C02,0x00C0FF0F,0x74400C02,0x0000F03F,
  36.         0x78400C02,0x00F3FF00,0x7C400C02,0xC300000F,0x80400C02,0xFF030000,0x10000E02,0xCF0000F0,
  37.         0x18000E02,0x7F007F00,0x1C000E02,0x7F007F00,
  38. };

  39. #endif /* __IMX_HEADER_ */
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-6 06:25 , Processed in 0.066768 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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