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 中,但只能读不能写
也就是相当于ROM ,在程序运行的时候,需要对变量实现写的话,就只能把全局变量进行重定位。
if (!OEMDebugInit ())
{
// spin forever
HALT (BLERR_DBGINIT);
}
OEMDebugInit这个函数主要是初始化串口,以便在内核启动,下载内核时输出调试信息,该函数是在文件夹
C:\WINCE600\PLATFORM\QT210\SRC\BOOTLOADER_FMD\EBOOT目录下面的Main.c实现的,关于这个函数的具体实现,将会在下一个博文中讨论
KITLOutputDebugString (NKSignon, CURRENT_VERSION_MAJOR, CURRENT_VERSION_MINOR);
KITLOutputDebugString ("BootloaderMain!The file locate in Public\r\n");
第一个KITLOutputDebugString是输出版本号,其中CURRENT_VERSION_MAJOR,CURRENT_VERSION_MINOR定义为一个常量,其定义如下:
#define CURRENT_VERSION_MAJOR 1
#define CURRENT_VERSION_MINOR 4
这二个常量也是定义在当前文件Blcommon.c中
if (!OEMPlatformInit ())
{
// spin forever
HALT (BLERR_PLATINIT);
}
OEMPlatformInit这个函数很重要,主要功能是初始化开发板的CPU的时钟,USB,LCD等,在s5pv210中还在该函数中实现下载BootImage.nb0和把BootImage.nb0
写入Flash中,实现下载NK.BIN到RAM中,但是并没有实现写NK.BIN到Flash中,在三星公司的Eboot中写NK.bin到Flash是在函数DownloadImage实现的。 该函数的位置: C:\WINCE600\PLATFORM\QT210\SRC\BOOTLOADER_FMD\EBOOT目录下面的Main.c文件中, 这个函数将会在下面的博文中重点分析,这是s5pv210的一个十分重要的函数。
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这个函数一般功能是提供给用户在下载之前做的一些准备,但是在s5pv210中实现却很简单,主要是根据一些变量来决定 返回值的类型为BL_DOWNLOAD,还是BL_JUMP。 该函数的位置:C:\WINCE600\PLATFORM\QT210\SRC\BOOTLOADER_FMD\EBOOT目录下面的Main.c.该函数将会在下面的博文中分析
如果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将会在以后的博文中详细介绍