注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

男儿当自强的博客

每天进步一点

 
 
 

日志

 
 
 
 

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

2010-10-23 10:22:24|  分类: wince的bootloade |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

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

⑴把GPG8和GPH8设置为输入,以便判断SD卡是否存在?SD卡是否lock?并且把GPE5到GPE10配置为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,在这里应该也可以对bootloader和OS之间共享的数据进行设置。

 

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

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

 

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

根据前面得到的image type是BL_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

 

②目前我们的bootloader是downloade单个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行就是把download的NK.bin的信息赋值给bootloader中定义的全局变量g_BINRegionInfo。

 

④通过调用OEMVerifyMemory函数来判断当前download的NK.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下指定的值一直,是用来判断当前要download的NK.bin是否在0x80200000到0x825000000的范围之内,在这里我们这次download的NK.bin信息是:dwImageStart = 0x80200000, dwImageLength = 0xE82498

 

从而可以知道当前的image type是IMAGE_TYPE_RAWBIN。

 

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

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

……………………

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

 

⑥ 调用函数OEMMapMemAddr将FLASH地址映射到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,也即是否是WINCE的NK.bin,通过IsKernelRegion函数来判断NK.bin中是否包含有NK.exe,因为有包含,所以通过1194到1196行返回NK.bin的起始地址,长度和跳转地址给DownloadImage函数,下面看IsKernelRegion函数体:

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

kandi IsKernelRegion dwCacheAddress =0x81080628

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

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)呢?因为这从0x8020000到0x8020003F是用于记录NK.bin的开始地址和长度,而加上sizeof(ULONG)是表示0x80200040到0x80200043是用于记录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中包含的模块的数量,包括exe和dll文件,下图是通过viewbin –t nk.bin >aoutput.txt中关于module的内容:

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

从上图也可以看出NK.bin中包含的modules是236-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函数中,后面将继续。

  评论这张
 
阅读(922)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017