• WINCE6.0+S3C2443的启动过程eboot5


    2.3.5 SD卡控制器的相关初始化

    一个相关的帖子http://topic.csdn.net/u/20100812/16/d0d5108b-dce1-4535-9e15-6f87bad57e43.html?r=67649425

     

    GPG8---nCD_SD,这个引脚用于判断是否有SD卡存在。

    GPH8---WP_SD,这个引脚用于判断SD卡是否lock

    GPE5---SD_CLK

    GPE6---SD_CMD

    GPE7---SD_DATA0

    GPE8---SD_DATA1

    GPE9---SD_DATA2

    GPE10---SD_DATA3

    GPG8GPH8设置为输入,以便判断SD卡是否存在?SD卡是否lock?并且把GPE5GPE10配置为SD卡的功能脚。

     

     

    初始化SD卡控制器并且初始化并且通过调用函数f_mountdrv来安装文件系统,

    SD_card_init()即是初始化SD卡控制器的,在这里就不详细描述这两个函数了。

     

    解析FAT/FAT32格式,找到NK.BIN,并能将其读取到内存中,再假设NK.BIN如下载一般到内存中,将其烧写到nand flash中。

     

    2.3.6显示bootloader更新NK的进度条

     

     

    2.4 OEMPreDownload (),对于SD卡的更新方式,这里只是根据之前的条件判断当前的动作是正常启动还是要更新NK,在这里应该也可以对bootloaderOS之间共享的数据进行设置。

     

     

    2.5 DownloadImage()

    下图是BootloaderMain函数的主要函数体,也即更新NK并且跳到特定地址启动OS的主要实现部分

     

    这里我们看看DownloadImage函数,主要内容如下:

    通过调用函数dwImageType = GetImageType()来获取

     

    调用函数OEMReadData来得到SD卡中映像文件,并且取出这个文件的前面7个字符保存在g_hdr数组中,接下来便判断当前的映像文件是什么类型的。我们要

    更新的是NK.bin,我们来看看NK.bin的格式

     

    可以知道NK.bin的头7个字符是B000FF,所以GetImageType函数返回BL_IMAGE_TYPE_SIGNED_BIN值来为后面的更新动作做好准备,我们在这里来看看OEMReadData函数功能:

    接下来会调用函数SdMmcReadData

     

    SdMmcReadData函数中的

    volatile U32 readLenIndex = SDBUFFER

    #define SDBUFFER 0x32200000

    这里SDBUFFERSDRAM地址,从SD卡从读取到NK就放在以这个地址为开始地址的内存中。

     

    DownloadSignedBin函数,就是download NK的函数。

    根据前面得到的image typeBL_IMAGE_TYPE_BIN来执行DownloadImage函数中下面的语句

    case BL_IMAGE_TYPE_BIN:

        rval &= DownloadBin( pdwImageStart, pdwImageLength, pdwLaunchAddr );

    break;

    下面来详细学习DownloadBin这个函数的函数体:

    通过调用OEMReadData函数来获取NK.bin的起始地址和长度。

    图中串口输出的信息如下

    DownloadBin image dwImageStart = 0x80200000, dwImageLength = 0xE82498

     

    目前我们的bootloaderdownloade单个bin

     

    g_DownloadManifest 的定义如下:

    static DownloadManifest g_DownloadManifest;

    在这之前bootloader没有对g_DownloadManifest变量的初始化,所以g_DownloadManifest.dwNumRegions的初始值是0.

    接着看看DownloadManifest结构体的定义:

     

    从上面的定义可知

    dwNumRegions:表示当前要downloade的映像个数,在这里知识download NK.bin,所以dwNumRegions=1.

    Region:用来描述某个映像文件的其实地址,长度和这个映像文件的名字,这里描述的

     

    调用OEMMultiBINNotify函数来提供download的信息给OEM,也即给bootloader

     

    OEMMultiBINNotify的主要函数体如下

     

    上图中第1798行就是把downloadNK.bin的信息赋值给bootloader中定义的全局变量g_BINRegionInfo

     

    通过调用OEMVerifyMemory函数来判断当前downloadNK.bin(也可以downloader eboot.bin)

     

     

    下图中第1730和第1731行的宏的定义如下:

    //

    // Nk Memory reigions defined in config.bib...

    //

    #define ROM_RAMIMAGE_START          0x80200000

    #define ROM_RAMIMAGE_SIZE           0x02300000

    这些值是要和files/config.bib下指定的值一直,是用来判断当前要downloadNK.bin是否在0x802000000x825000000的范围之内,在这里我们这次downloadNK.bin信息是dwImageStart = 0x80200000, dwImageLength = 0xE82498

     

     

    从而可以知道当前的image typeIMAGE_TYPE_RAMIMAGE

     

     

    调用函数OEMReadData来读取NK.bin的内容到SDRAM内存中

    每次的读取是以一个record为单位,分别读取这个record的开始地址,长度和校验码,上图的第1128行用于判断当前读取的record是否是最后的一个record,如果是,就退出while循环,也即把整个NK.bin读取到SDBUFFER指向的内存中,所以要保证有足够的内存来保存NK.binNK.bin的格式如下:

     

    ……………………

     

    NK.bin文件的最开端,会放置一个BinFile结构,imageStartImageLength分别对应镜像展开后在内存中存放的首地址和长度。该结构中的RecordNum为不确定的,通常在最后一个记录之后增加一个addressChksum都为0的纪录表示结束,而这个表示结束的结构中的Length则标示其实际入口点。

     

    调用函数OEMMapMemAddrFLASH地址映射到RAM地址中。

     

    如果目标系统的需求是要能支持把操作系统的镜像文件下载到FLASH中去,就必须调用本函数。由于FLASH操作速度比RAM慢,在片擦除的时候甚至会使读写操作停滞,这样在每次下载操作系统镜像文件时,由于FLASH的擦写都会使下载停滞。而OEMMapMemAddr使用了RAM缓冲操作系统镜像文件的方式,使得用户在下载操作系统镜像文件时感觉不到停滞,这个函数将FLASH地址映射到RAM地址,这样向FLASH写的数据实际上先被缓冲到RAM中,然后再写到FLASH中。下面是相关帖子的链接:http://topic.csdn.net/u/20091218/11/e56acdfd-23a0-4542-bfac-2364a97fe2e7.html

    有必要看看OEMMapMemAddr函数体:

     

    #define CACHED_TO_UNCACHED_OFFSET   0x20000000

    #define FILE_CACHE_START   (0x80200000 | CACHED_TO_UNCACHED_OFFSET)        // Start of file cache (temporary store for flash images).

    得到这个cache地址后,就把读出出来的数据块放在这个cache地址处,这个地址就是上面函数注释中提到的file cache location

     

    读出当前的record的数据块并且校验

     

    读取到的数据块就保存在FLASH地址映射的RAM地址lpDest上。

     

    通过查找ROMHDR的地址来计算ROM的偏移量

     

     

    #define ROM_SIGNATURE_OFFSET 64   //0x40

    #define ROM_SIGNATURE 0x43454345    //cece 4byte    =>ROMHDR 0x44偏移处,每个bin 都有个pToc指向ROMHDR开头的地址,看下面的bin 文件结构,0x44offset处地址里面放的是ROMHDR地址,开始是-1,romimage.exe来设置的

    上图的第1154行主要用于判断当前的NK.bin是否为CE的映像文件。

    1169的串口输出信息是:rom_offset=0x0.

     

     

    判断当前下载的bin文件是否包含TOC和内核(nk.exe)

     

    1188行用于判断NK.bin文件中地址为0x80200000+0x40=0x80200040地址处保存的内容是cece,也即是否是WINCENK.bin,通过IsKernelRegion函数来判断NK.bin中是否包含有NK.exe,因为有包含,所以通过11941196行返回NK.bin的起始地址,长度和跳转地址给DownloadImage函数,下面看IsKernelRegion函数体:

     

    这个函数的串口输出信息如下:

    kandi IsKernelRegion dwCacheAddress =0x81080628

    TOC的指针地址是0x80200044处,这个地址保存的值就是TOC记录的地址,也即从0x80200044处获取其值(0x81080628),也就知道TOC存放在哪个record上了,在本NK.bin中,是第161record,可从下面的图片看出来

    kandi IsKernelRegion toc copy number =191

    kandi IsKernelRegion pROMHeader =0x81080628

    kandi IsKernelRegion testTet =0x20

    kandi IsKernelRegion plTOC =0x8108067C

    0x8108067C-0x81080628=0x54(84),也就是ROMHDR结构体占用的字节数,通过下图的Length=0x00000054也可得知。

     

    1458行为什么还要加上ROM_SIGNATURE_OFFSET(0x40)呢?因为这从0x80200000x8020003F是用于记录NK.bin的开始地址和长度,而加上sizeof(ULONG)是表示0x802000400x80200043是用于记录WINCE的“cece”恰好是4个字节,public/common/oal/inc/romldr.h下面的定义可以让我们更清晰去理解:

     

    这里的physfirst address=image start=0x80200000

    1471行的while用于查询NK.bin中是否包含NK.exe,如果没有就表示此NK.bin没有包含内核,这样的NK.bin就不是所需要的。

    上图第1463行的dwNumModules=191,表示NK.bin中包含的模块的数量,包括exedll文件,下图是通过viewbin –t nk.bin >aoutput.txt中关于module的内容:

     

    ……………………………………………

    从上图也可以看出NK.bin中包含的modules236-46+1,正好是191个,而第一个就是NK.exe

     

    NK.bin解压到SDRAM中后,接着就计算NK.bin的检验码,并且判读是否马上在DownloadImage函数中把解压后的映像写到flash中。

     

    ComputeChecksum函数计算校验码的原理很简单,就不介绍了,下面看WriteImageToFlash的函数体

     

    串口输出信息如下(换了个NK.bin,所以大小不同啊,哈哈)

    Completed file(s):

    -----------------------------------

    [0]: Address=0x80200000  Length=0xE50694  Name="" Target=RAM

    这个函数也很简单,就不介绍了,到此DownloadImage函数的工作就完成了,接着回到BootloaderMain函数中,后面将继续。

  • 相关阅读:
    (React 框架)React技术
    React 项目
    JS语法之--模块化
    JS 语法之-- 解构,Promise(异步)
    JS 语法之--对象类型(构造器,class,this),高阶对象(高阶类,Minix模式)
    javascript:console对象与控制台
    javascript:错误处理
    javascript:基本数据类型转换
    javascript:数据结构-数组
    javascript:数据结构-对象
  • 原文地址:https://www.cnblogs.com/LoongEmbedded/p/5298862.html
Copyright © 2020-2023  润新知