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

时间:2021-07-16 18:03:35

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卡的功能脚。

 

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

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

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

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

 

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

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

2.3.6显示bootloader更新NK的进度条

 

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

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

 

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

2.5 DownloadImage()

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

 

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

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

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

 

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

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

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

 

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

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

 

接下来会调用函数SdMmcReadData

 

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

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的起始地址和长度。

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

图中串口输出的信息如下

DownloadBin image dwImageStart = 0x80200000, dwImageLength = 0xE82498

 

目前我们的bootloaderdownloade单个bin

 

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

g_DownloadManifest 的定义如下:

static DownloadManifest g_DownloadManifest;

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

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

 

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

从上面的定义可知

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

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

 

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

 

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

OEMMultiBINNotify的主要函数体如下

 

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

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

 

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

 

 

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

下图中第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

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

 

从而可以知道当前的image typeIMAGE_TYPE_RAMIMAGE

 

 

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

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

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

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

 

……………………

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

 

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

 

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

 

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

如果目标系统的需求是要能支持把操作系统的镜像文件下载到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函数体:

 

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

#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的数据块并且校验

 

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

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

 

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

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

 

#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.

 

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

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

 

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

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

 

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

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

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也可得知。

 

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

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

 

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

这里的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的内容:

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

 

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

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

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

 

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

 

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

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

 

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

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

Completed file(s):

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

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

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