WinCE6.0 BootloaderMain源码分析之OEMLaunch

来源:互联网 发布:阿里妈妈淘宝联盟提现 编辑:程序博客网 时间:2024/05/08 09:07
本文转自:http://jazka.blog.51cto.com/809003/612722在下载了内核镜像之后,进入到最后一个阶段OEMLaunch,在这里将完成eboot的最后一部分任务,并将跳转到OAL.exe开始启动内核。还是先给出该函数的源码如下:
先来看看这几个参数,都是从DownloadImage函数获得的,dwImageStart是镜像的起始位置,dwImageLength是镜像的大小,dwLaunchAddr是内核的启动地址,pRomHdr指向TOC数据。
1273行判断是否需要将镜像文件写入到nand flash中,当前镜像只是下载到了RAM中,一般都会写入flash中,否则掉电重启后,RAM中的镜像就不存在了,又需要重新下载镜像实现启动。
12781342行根据镜像的类型是stepldrbootloader还是nk分别写入对应的nand flash位置。如果镜像类型是stepldr或者bootloader,通过函数WriteRawImageToBootMedia完成实现的flash写操作,主要是完成nand Flash的坏块检测、块擦除、写块、读块、设置TOC等操作,有兴趣的可以查看源码,该函数位于文件WINCEROOT\SMDK6410\SRC\BOOTLOADER\EBOOT\Nand.cpp中。如果镜像类型是nk,则通过函数WriteOSImageToBootMedianand中,该函数放到后面详细解析。由于TOC记录的数据与bootloaderNK都有关系,所以如果是这两种镜像类型,在写入nand flash以后还需要更新TOC中的数据信息,如TOC_Write函数的调用。而stepldr则与TOC无关,无需更新。
13431360行则是判断为不需要将镜像写入nand flash时的处理情况,从代码中可以看出,如果镜像是stepldrbootloader,则必须写入flash中,否则提示无法从RAM中启动。
13661391行是当采用网卡下载镜像时的处理,还包含了关于KITL的处理,由于本平台是从USB下载,这部分不会执行,所以不作详细的分析。
13961404行是将内核的启动地址记录到TOC数据中,这样在下一次跳转到内核镜像的时候就不需要重新获取跳转地址,而是直接按TOC记录的进行跳转。
14081413行中,dwPhysLaunchAddr便是启动内核的物理地址,作为Launch函数的输入参数完成跳转到内核启动。Launch函数是汇编实现的,在介绍startup.s的博文中提到过。
到这里eboot的全部任务就完成了。
下面解析一下WriteOSImageToBootMedia函数的源码,该函数位于文件WINCEROOT\SMDK6410\SRC\BOOTLOADER\EBOOT\Nand.cpp中,下面给出源码:
364372行是判断TOC数据是否有效,这种代码在eboot的经常会用到。
377414行用来检测当前下载的镜像中是否包含nk.exe,并返回其扩展指针。主要通过GetKernelExtPointer函数来完成此任务。
418445行负责检查用来的创建BINFS分区的空间是否足够。
451461行通过函数BP_OpenPartition来在nand flash设备上创建分区。该函数在文件WINCEROOT\SMDK6410\SRC\BOOTLOADER\EBOOT\Bootpart1.cpp中。第一个参数dwStartSector为起始逻辑扇区,(IMAGE_START_BLOCK+1)*PAGES_PER_BLOCK即使OSImage所在的Block,加1是因为MBR保存在IMAGE_START_BLOCK开始的第一个block中;第二个参数dwNumSectors为该分区包含多少个扇区,根据下载的NK.BIN需要的page数来计算;第三个参数dwPartType表示分区的类型,PART_BINFS表示要创建BINFS格式的文件系统;第四个参数fActive为是否激活该分区,TRUE表明激活;第五个参数dwCreationFlags标识是创建分区还是打开分区,PART_OPEN_ALWAYS表示如果不存在这个分区则创建,如果存在则打开。最后返回该分区的句柄。
465524行将OSImage写入到BINFS分区当中。由于只是单个的NK.BIN文件,所以g_BINRegionInfo.dwNumRegions = 1for循环只进行一遍。
476480行调用函数BP_SetDataPointer设置该分区的数据指针实际上数据指针是指在该分区中下一次被读或写的位置。该函数位于文件WINCEROOT\SMDK6410\SRC\BOOTLOADER\EBOOT\Bootpart1.cpp中。第一个参数hPartition为被创建分区的句柄,第二个参数dwAddress为数据指针的新位置。一般会配合BP_ReadData()BP_WriteData()两个函数来用。
484488行调用函数BP_WriteData向该分区写入数据,即将OSImage写入BINFS分区中。该函数位于WINCEROOT\SMDK6410\SRC\BOOTLOADER\EBOOT\Bootpart1.cpp文件中。第一个参数hPartition为被创建的分区的句柄,第二个参数pbBuffer为要写入数据的Buffer,第三个参数dwLength为要写入数据的长度。
492524行完成更新TOC并把内核拷贝到SDRAM中,为下一步的跳转执行做准备。
528537行用来将剩余的nand flash空间创建扩展分区,仍然调用BP_OpenPartition来完成,分区类型变为了PART_DOS32表明是创建FAT32文件系统。