Eboot之函数BootloaderMain函数分析

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文件中.但是通过串口调试输出跟踪,发现Ebootmain函数中调用的是在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将会在以后的博文中详细介绍


你可能感兴趣的:(Eboot之函数BootloaderMain函数分析)