zoukankan      html  css  js  c++  java
  • DM6437 dsp系列之启动过程全析(2)—AIS文件解析

    本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。

    欢迎和大家交流。qq:1037701636 email: gzzaigcn2009@163.comgzzaigcn2012@gmail.com

    开发工具CCS5.1,Source Insight。

    这篇博客主要和大家分享,AIS文件的制作与使用。什么是AIS,TI对其的定义为Application Image Script,应用镜像脚本,是用来对Image的一种格式定义,从数据源的本质去分析就是一个保存了大量二进制数据的类型存储起来。而AIS中基本的数据大小为一个word 32位bit。包括命令、包括数据等。

    AIS文件核心的是由Second boot和APP的两个镜像打包在一个文件当中去,然后自动添加一些命令行信息,数据存储格式为little Endian。

    A.如下所示是AIS中命令字。称之为Opcode。在前面所说到的RBL中,内部固件会都下面的一系列Opcodes进行解析,然后做进一步处理。

    上诉的命令字使用频率最高,且最为重要的是Section Load,Request CRC,Enable CRC,Jump Close,Function Execute。

    1.Section Load:加载段,Dsp中往往在cmd中生成各种类型的段,包括数据,代码,未初始化数据,自定义段等。这些在AIS文件中都是在Section load命令字的后面存在。如下所示:

    图中的address指定了数据加载到存储空间的地址,SIZE指定数据大小,接着的是有效的raw data。所有单元格都占据一个word的空间。

    2. CRC相关的命令字

    CRC Request和Enable等分别用于对加载的数据进行CRC校验,比如1中的Load Section完成时,会对加载的数据包括SIZE,ADDRESS做CRC校验,最终得到一个数据,而这个crc数据,将会和AIS指定的expected CRC value做比较,查看是否读取的内容完全正确,保证数据的读取无误。

    3.Jump close command.跳转关闭指令

     跳转关闭指令,该指令是意味着AIS文件 结束。用户可以跳入到自己的APP程序去执行,其后的一个字代表跳入的程序空间所在的位置。

    4. Function Execute Command 函数执行命令

    在AIS的解析文件读取到该命令字时,会继续读取,往往这些命令字是在AIS文件的最开头,比Second Boot还要先执行。完成的比如dm6437的包括PLL,DDR,EMIFA三个功能。这些全部在RBL中被执行。为Secnod Boot打好硬件的配置。具体内容将会在后面介绍。

    B .基于SPI24 boot的AIS文件

    在第一篇博文中,说到boot的方式为SPI24 norflash启动。那么如何在AIS文件中体现出来,并反馈给RBL呢?

    上图就是典型的一种SPI AIS文件的数据格式。第一个word代表SPI的位长,即操作的flash的地址位大小,这里24位的需为0x00000003。然后第二个word为固定的幻数,大小固定0x41504954。

    C.AIS文件的制作与生存。

    AIS文件作为一个镜像文件,那他是如何生成的呢。主要包括以下内容:

    1.Second_boot源码。

    该源码开源,下载的网址为http://processors.wiki.ti.com/index.php/DM643x_24-bit_SPI_Secondary_Boot_Loader

    主要包括对norflash的读、写操作以及核心的boot代码。

    2.Second boot代码解析。

    阅读过代码后,初步发现该代码的功能其实也体现出RBL的一些功能。SPI通过32位的包,读取每一个Command命令字,然后对命令字做解析。

    void main(void) {      //RBL加载Second_UBL后,跳入这里执行用于加载APP
    
        /* Enable caching. */
        enable_L1_cache();
    
    	initBoot();
    	performNandBoot();//读取并解析APP的AIS文件,读取相关section到指定区域
    
        /* Disable Caching */
        disable_L1_cache();
    
        /* Jump to application start point */
        TARGET_BOOT_STATUS.applicationStart(); //PC跳入到APP的main入口所在的地址处,开始运行应用程序
    }
     

    TARGET_BOOT_STATUS.aisStreamPtr = (Uint32) SPI_APPLI_IMAGE_ADDRESS;//偏移10Kb,AIS Image APP的地址
    TARGET_BOOT_STATUS.status = parseAisData();//解析并且加载APP AIS Image到指定位置。


    SPI_APPLI_IMAGE_ADDRESS这个地址,指定了APP Image在AIS文件中的存储位置,用户可以根据自己的需求进行修改。这里默认的10KB之前的代码称之为Second boot。即RBL会读取到DDR中执行。Second boot启动后运行上面的main函数,开始对APP部分的镜像做解析。主要是把几个核心的Section加载进来。并对每个数据段都要做CRC的校验,以免数据由误差。

    最后是如何跳入APP的程序入口的呢?我们知道一旦读到Jump close命令,将会把APP的地址传入到函数指针,调用该函数指针后,就会跳入APP所在的程序开始运行(一般也就是main所在的地址空间)。如下:

    TARGET_BOOT_STATUS.applicationStart(); //PC跳入到APP的main入口所在的地址处,开始运行应用程序

    这样就实现了一个完整的RBL+SBT+APP的完整启动过程。而所有的镜像都以AIS文件存在,体现了其的重要性。

    AIS文件的制作命令:

    AIS文件的制作需要用到一直叫perl的脚本命令,一般需要在window上进行手动安装,Linux有专门的命令安装。

    准备好Second boot和APP的2进制镜像文件(需要通过专门的软件将CCS编译出来的out文件),依次按照如下步骤执行:

    a.编写perl的window 批处理文本.bat:

    C:Perlinperl.exe genAIS.pl -otype bin -i led.out -o led.hex -bootmode spimaster -memwidth 8  -datawidth 8 -addrsz 24 -cfg evmdm6437.cfg
    pause
    

    先要写入perl的命令,整个是基于perl的system()函数来执行的。后面的配置内容含义如下所示:

    但是有如下几点要注意:-otype貌似最新版本的genAIS.pl只支持bin不能写成binary ,bootmode后面spi要写成spimaster,不然写成spi是无效的


    上述的配置命令在批处理文件中体现出来,这里不在讲述。

    根据以上内容,genAIS.pl分别最终生成bin格式的Second boot和 APP两个AIS文件。类似如下数据包:

    00000000h: 03 00 00 00 54 49 50 41 0D 59 53 58 00 00 03 00 ; ....TIPA.YSX....
    00000010h: 15 00 00 00 00 00 00 00 00 00 00 00 0D 59 53 58 ; .............YSX
    00000020h: 01 00 05 00 FC FF FF 3F FC FF FF 3F FC FF FF 3F ; ....??????
    00000030h: FC FF FF 3F 00 00 00 00 0D 59 53 58 02 00 09 00 ; ??.....YSX....
    00000040h: 17 00 00 00 01 00 00 00 0B 00 00 00 00 00 00 00 ; ................
    00000050h: 05 64 00 50 22 88 13 00 48 21 49 16 02 C7 0C 00 ; .d.P"?.H!I..?.
    00000060h: EF 04 00 00 03 59 53 58 01 59 53 58 00 00 FF 87 ; ?...YSX.YSX..?
    00000070h: A0 10 00 00 C6 11 47 03 20 41 12 30 58 23 90 01 ; ?..?G. A.0X#?

    可以看到基本的数据结构和上面所述的基本相同,0x00000003表示是SPI24位的操作。只是这里添加啦一部分function函数头,用于配置PLL,DDR2,EMIF等,这部分内容就在-cfg中的文件,这部分内容直接拷贝到生成的AIS文件,而不会对out文件进行解析生成。只是简单的复制到AIS文件的开头。典型的dm6437.cfg如下所示:

    0x5853590D  #Function Execute Command
    0x00030000  #   Selects PLL configuration function, with 3 arguments
    0x00000015  #   PLLM value
    0x00000000  #   PLLDIV 0
    0x00000000  #   Clock source
    0x5853590D  #Function Execute Command
    0x00050001  #   Selects EMIFA configuration, with 5 arguments
    0x3FFFFFFC  #   AB1CR control register mask
    0x3FFFFFFC  #   AB2CR control register mask
    0x3FFFFFFC  #   AB3CR control register mask
    0x3FFFFFFC  #   AB4CR control register mask
    0x00000000  #   NANDFCR control register mask
    0x5853590D  #Function Execute Command
    0x00090002  #   Selects DDR memory configuration, with 9 arguments
    0x00000017  #   DDR PLLM
    0x00000001  #   PLL SRC
    0x0000000B  #   DDR CLLK DIV
    0x00000000  #   VBPE CLK DIV
    0x50006405  #   DDR Control register mask
    0x00138822  #   SDRAM Config register mask
    0x16492148  #   SDRAM Timer 0 register mask
    0x000CC702  #   SDRAM Timer 1 register mask
    0x000004EF  #   SDRAM Refresh control register mask 

    b.使用combineAIS.pl 将两个AIS文件打包成为最终 的一个合成的AIS文件

    perl combineAIS.pl SPI_Secondary_boot.bin myAppAIS.bin finalAIS.bin 10
    

    这里的10表示,APP偏移10kb在AIS文件中。

    到这里整个AIS的文件制作的过程就结束。

    总的来说dm6437基于这种AIS文件的启动方式,简单方便,有利于开发,对其深入理解有好处,可以自由的设置AIS文件。

  • 相关阅读:
    迭代器和生成器
    案例:复制大文件
    案例:使用seek倒查获取日志文件的最后一行
    Leetcode165. Compare Version Numbers比较版本号
    Leetcode137. Single Number II只出现一次的数字2
    Leetcode129. Sum Root to Leaf Numbers求根到叶子节点数字之和
    Leetcode116. Populating Next Right Pointers in Each Node填充同一层的兄弟节点
    Leetcode114. Flatten Binary Tree to Linked List二叉树展开为链表
    Leetcode113. Path Sum II路径总和2
    C++stl中vector的几种常用构造方法
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3167954.html
Copyright © 2011-2022 走看看