Eboot的整个实现框架是通过实现BootloaderMain这个函数来实现的.现在通过分析源码分析一下BootloaderMain这个函数,就可以知道Eboot的整个框架是如何实现的.
该函数的地址位于:C:\WINCE600\PLATFORM\COMMON\SRC\COMMON\BOOT\BLCOMMON文件夹下面的Blcommon.c文件中,另外在另外一个文件夹也包含一个BootloaderMain函数,其地址位于:C:\WINCE600\PUBLIC\COMMON\OAK\DRIVERS\ETHDBG\BLCOMMON文件夹下面的Blcommon.c文件中.但是通过串口调试输出跟踪,发现Eboot的main函数中调用的是在PLATFORM这个文件夹下面的BootloaderMain函数.
if (!KernelRelocate (pTOC)) { // spin forever HALT (BLERR_KERNELRELOCATE); }调用KernelRelocate这个函数主要是实现内核中变量的重定位,但为什么要实现变量的重定位呢?原因是:内核的镜像为RAMIMAGE,一般是放在物理RAM 中,但只能读不能写
if (!OEMDebugInit ()) { // spin forever HALT (BLERR_DBGINIT); }OEMDebugInit这个函数主要是初始化串口,以便在内核启动,下载内核时输出调试信息,该函数是在文件夹
KITLOutputDebugString (NKSignon, CURRENT_VERSION_MAJOR, CURRENT_VERSION_MINOR); KITLOutputDebugString ("BootloaderMain!The file locate in Public\r\n");第一个KITLOutputDebugString是输出版本号,其中CURRENT_VERSION_MAJOR,CURRENT_VERSION_MINOR定义为一个常量,其定义如下:
if (!OEMPlatformInit ()) { // spin forever HALT (BLERR_PLATINIT); }OEMPlatformInit这个函数很重要,主要功能是初始化开发板的CPU的时钟,USB,LCD等,在s5pv210中还在该函数中实现下载BootImage.nb0和把BootImage.nb0
switch (dwAction = OEMPreDownload ()) { case BL_DOWNLOAD: // (5) download image if (!DownloadImage (&dwImageStart, &dwImageLength, &dwLaunchAddr)) { // error already reported in DownloadImage SPIN_FOREVER; } bDownloaded = TRUE; // Check for pTOC signature ("CECE") here, after image in place if (*(LPDWORD) OEMMapMemAddr (dwImageStart, dwImageStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE) { dwpToc = *(LPDWORD) OEMMapMemAddr (dwImageStart, dwImageStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG)); // need to map the content again since the pointer is going to be in a fixup address dwpToc = (DWORD) OEMMapMemAddr (dwImageStart, dwpToc + g_dwROMOffset); KITLOutputDebugString ("ROMHDR at Address %Xh\r\n", dwImageStart + ROM_SIGNATURE_OFFSET + sizeof (DWORD)); // right after signature } // fall through case BL_JUMP: // Before jumping to the image, optionally check the image signature. // NOTE: if we haven't downloaded the image by now, we assume that it'll be loaded from local storage in OEMLaunch (or it // already resides in RAM from an earlier download), and in this case, the image start address might be 0. This means // that the image signature routine will need to find the image in storage or in RAM to validate it. Since the OEM"s // OEMLaunch function will need to do this anyways, we trust that it's within their abilities to do it here. // if (g_bBINDownload && g_pOEMCheckSignature) { if (!g_pOEMCheckSignature(dwImageStart, g_dwROMOffset, dwLaunchAddr, bDownloaded)) HALT(BLERR_CAT_SIGNATURE); } // (5) final call to launch the image. never returned OEMLaunch (dwImageStart, dwImageLength, dwLaunchAddr, (const ROMHDR *)dwpToc); // should never return // fall through default: // ERROR! spin forever HALT (BLERR_INVALIDCMD); }
如果OEMPreDownload返回的值为BL_DOWNLOAD,则要调用函数DownloadImage来对镜像进行下载,但s5pv210中Eboot实现并不是在DownloadImage中下载镜像的,而是在OEMPlatformInit下载镜像到ram缓存区中,但是在DownloadImage中来把镜像写入Flash中的。其中这个函数有三个参数,用来获取操作系统镜像的起始地址,镜像的长度,以及Eboot跳转到操作系统的跳转地址。
bDownloaded 这个变量是在函数中BootloaderMain函数中定义的一个局部变量,在此处将它赋值为TRUE,将会在下面的函数g_pOEMCheckSignature使用,但是我用SouceInsight并没有找到该函数的实现,所以在s5pv210的Eboot中可能还没有用到,等下一次我把整个Eboot,OAL代码整个联系在一起的时候,再看一个这个变量的作用。
该函数的位置:C:\WINCE600\PLATFORM\COMMON\SRC\COMMON\BOOT\BLCOMMON文件夹下面的Blcommon.c文件中, 该函数将在以后的博文中分析。
在这里需要注意的一点是:在case BL_DOWNLOAD:的后面并没有break语句,如果是BL_DOWNLOAD类型的话,还会接着执行BL_JUMP的代码来实现从Eboot到操作系统内核的跳转。
g_bBINDownload 是个静态全局变量,其初始值为TRUE,定义在当前文件Blcommon.c文件中。static BOOLEAN g_bBINDownload = TRUE;
当下载Bin 镜像文件时会在函数中DownloadBin 中赋值为TRUE,其中DownloadBin函数是在DownloadImage函数中调用的,以后在分析DownloadImage函数时将会介绍其功能。g_pOEMCheckSignature 并是一个函数指针,但在这个Eboot中并没有实现函数OEMCheckSignature,所以下面这个if 将不会执行。
OEMLaunch是用户需要自己实现的函数,凡是函数带OEM的函数,都是需要由用户实现的。该函数实现的功能是离开Eboot跳转到操作系统中去执行,该函数的四个变量dwImageStart:操作系统镜像的起始地址,dwImageLength:镜像的长度
dwLaunchAddr:Eboot的跳转地址,也就是Wince系统内核开始执行代码的起始地址。
dwpToc:指向ROMHDR的指针,关于这个结构体ROMHDR将会在以后的博文中详细介绍