WinCE6.0 BootloaderMain源码分析之OEMLaunch

    在下载了内核镜像之后,进入到最后一个阶段 OEMLaunch ,在这里将完成 eboot 的最后一部分任务,并将跳转到 OAL.exe 开始启动内核。还是先给出该函数的源码如下:
先来看看这几个参数,都是从 DownloadImage 函数获得的, dwImageStart 是镜像的起始位置, dwImageLength 是镜像的大小, dwLaunchAddr 是内核的启动地址, pRomHdr 指向 TOC 数据。
1273 行判断是否需要将镜像文件写入到 nand flash 中,当前镜像只是下载到了 RAM 中,一般都会写入 flash 中,否则掉电重启后, RAM 中的镜像就不存在了,又需要重新下载镜像实现启动。
1278 1342 行根据镜像的类型是 stepldr bootloader 还是 nk 分别写入对应的 nand flash 位置。如果镜像类型是 stepldr 或者 bootloader ,通过函数 WriteRawImageToBootMedia 完成实现的 flash 写操作,主要是完成 nand Flash 的坏块检测、块擦除、写块、读块、设置 TOC 等操作,有兴趣的可以查看源码,该函数位于文件 WINCEROOT\SMDK6410\SRC\BOOTLOADER\EBOOT\Nand.cpp 中。如果镜像类型是 nk ,则通过函数 WriteOSImageToBootMedia nand 中,该函数放到后面详细解析。由于 TOC 记录的数据与 bootloader NK 都有关系,所以如果是这两种镜像类型,在写入 nand flash 以后还需要更新 TOC 中的数据信息,如 TOC_Write 函数的调用。而 stepldr 则与 TOC 无关,无需更新。
1343 1360 行则是判断为不需要将镜像写入 nand flash 时的处理情况,从代码中可以看出,如果镜像是 stepldr bootloader ,则必须写入 flash 中,否则提示无法从 RAM 中启动。
1366 1391 行是当采用网卡下载镜像时的处理,还包含了关于 KITL 的处理,由于本平台是从 USB 下载,这部分不会执行,所以不作详细的分析。
1396 1404 行是将内核的启动地址记录到 TOC 数据中,这样在下一次跳转到内核镜像的时候就不需要重新获取跳转地址,而是直接按 TOC 记录的进行跳转。
1408 1413 行中, dwPhysLaunchAddr 便是启动内核的物理地址,作为 Launch 函数的输入参数完成跳转到内核启动。 Launch 函数是汇编实现的,在介绍 startup.s 的博文中提到过。
到这里 eboot 的全部任务就完成了。
下面解析一下 WriteOSImageToBootMedia 函数的源码,该函数位于文件 WINCEROOT\SMDK6410\SRC\BOOTLOADER\EBOOT\Nand.cpp 中,下面给出源码:
364 372 行是判断 TOC 数据是否有效,这种代码在 eboot 的经常会用到。
377 414 行用来检测当前下载的镜像中是否包含 nk.exe ,并返回其扩展指针。主要通过 GetKernelExtPointer 函数来完成此任务。
418 445 行负责检查用来的创建 BINFS 分区的空间是否足够。
451 461 行通过函数 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 表示如果不存在这个分区则创建,如果存在则打开。最后返回该分区的句柄。
465 524 行将 OSImage 写入到 BINFS 分区当中。由于只是单个的 NK.BIN 文件,所以 g_BINRegionInfo.dwNumRegions = 1 for 循环只进行一遍。
476 480 行调用函数 BP_SetDataPointer 设置该分区的数据指针实际上数据指针是指在该分区中下一次被读或写的位置。该函数位于文件 WINCEROOT\SMDK6410\SRC\BOOTLOADER\EBOOT\Bootpart1.cpp 中。第一个参数 hPartition 为被创建分区的句柄,第二个参数 dwAddress 为数据指针的新位置。一般会配合 BP_ReadData() BP_WriteData() 两个函数来用。
484 488 行调用函数 BP_WriteData 向该分区写入数据,即将 OSImage 写入 BINFS 分区中。该函数位于 WINCEROOT\SMDK6410\SRC\BOOTLOADER\EBOOT\Bootpart1.cpp 文件中。第一个参数 hPartition 为被创建的分区的句柄,第二个参数 pbBuffer 为要写入数据的 Buffer ,第三个参数 dwLength 为要写入数据的长度。
492 524 行完成更新 TOC 并把内核拷贝到 SDRAM 中,为下一步的跳转执行做准备。
528 537 行用来将剩余的 nand flash 空间创建扩展分区,仍然调用 BP_OpenPartition 来完成,分区类型变为了 PART_DOS32 表明是创建 FAT32 文件系统。

你可能感兴趣的:(职场,休闲,WinCE6.0,OEMLaunch函数)