bootload启动流程(二)----Eboot的主要流程

 当跳转到main()函数之后,开始执行下面的c函数。

void main (void)

{

    BootloaderMain ();

 

    SPIN_FOREVER;

}

我们不难发现,实际上main()函数里面只有一个函数执行。而这个BootloaderMain ()是由微软提供的,一般放在public下面:

void BootloaderMain (void)

{

    ROMHDR *pRomHdr = NULL;  // pTOC for NK image. MUST COPY IT OR CLEANBOOT may erase it

    DWORD dwAction, dwpToc;

    DWORD dwImageStart = 0, dwImageLength = 0, dwLaunchAddr = 0;

    BOOL bDownloaded = FALSE;

#ifndef SIMULATOR

    // relocate globals to RAM

    if (!KernelRelocate (pTOC)) {

        // spin forever

        HALT (BLERR_KERNELRELOCATE);

    }

#endif

//这段是内核重定位

    // (1) Init debug support. We can use OEMWriteDebugString afterward.

if (!OEMDebugInit ()) {

//调试端口初始化

        // spin forever

        HALT (BLERR_DBGINIT);

    }

 

    // output banner

    EdbgOutputDebugString (NKSignon, CURRENT_VERSION_MAJOR, CURRENT_VERSION_MINOR);

 

    // (3) initialize platform (clock, drivers, transports, etc)

if (!OEMPlatformInit ()) {

//平台初始化

        // spin forever

        HALT (BLERR_PLATINIT);

    }

 

    // system ready, preparing for download

    EdbgOutputDebugString ("System ready!/r/nPreparing for download.../r/n");

 

    // (4) call OEM specific pre-download function

switch (dwAction = OEMPreDownload ()) {

//内核预下载

    case BL_DOWNLOAD:

        // (5) download image

      

        if (!DownloadImage (&dwImageStart, &dwImageLength, &dwLaunchAddr)) {

//下载内核到RAM

            // error already reported in DownloadImage

            SPIN_FOREVER;

        }

        bDownloaded = TRUE;

 

                   if (dwImageStart) {

                            // Check for pTOC signature ("CECE") here, after image in place

                            if (*(LPDWORD) OEMMapMemAddr (dwImageStart, dwImageStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE) {

//检测内核的签名,这个我在另外一篇关于bin文件分析中有详细的介绍,主要是签名在binoffset 00x40

                                     EdbgOutputDebugString("Found pTOC signature./n");

                            } else {

                                     EdbgOutputDebugString ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!/r/n");

                                     EdbgOutputDebugString ("! ERROR: Did not find pTOC signature.  ABORTING. !/r/n");

                                     EdbgOutputDebugString ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!/r/n");

 

                                     // If no signature, we're going to fail anyway, so loop forever

                                     HALT (BLERR_SIGNATURE);

                            }

 

                            dwpToc = *(LPDWORD) OEMMapMemAddr (dwImageStart, dwImageStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG));

//找到TOC指针,toc的二级指针在recorf2 第二个字节处,offset 0x44

                            // need to map the content again since the pointer is going to be in a fixup address

                            dwpToc = (DWORD) OEMMapMemAddr (dwImageStart, dwpToc);

                            // NOTE: MUST COPY or a CLEAN_BOOT flag will erase it

                            memcpy (pRomHdr = &romhdr, (LPVOID) dwpToc, sizeof(ROMHDR));

//TOC的内容拷贝到pRomHdr指向的地址里面

 

                            EdbgOutputDebugString ("ROMHDR at Address %Xh/r/n", dwImageStart + ROM_SIGNATURE_OFFSET + sizeof (DWORD)); // right after signature

                            EdbgOutputDebugString ("RomHdr.ulRAMStart=%Xh RomHdr.physfirst=%Xh./r/n", romhdr.ulRAMStart, romhdr.physfirst);

                   }

 

        // fall through

    case BL_JUMP:

        // Before jumping to the image, optionally check the image signature.

        if (g_pOEMCheckSignature && dwImageStart)

        {

            if (!g_pOEMCheckSignature(dwImageStart, g_dwROMOffset, dwLaunchAddr, bDownloaded))

                HALT(BLERR_WHQL_SIGNATURE);

        }

        // (5) final call to launch the image. never returned

        OEMLaunch (dwImageStart, dwImageLength, dwLaunchAddr, pRomHdr);

跳转到内核地址并且执行,同时把内核拷贝到flash

        // should never return

        // fall through

    default:

        // ERROR! spin forever

        HALT (BLERR_INVALIDCMD);

    }

}

这块实际上也就是eboot的主要启动过程了,流程其实也很简单,主要是初始化一些必要的硬件并且把内核代码拷贝到内存并且开始启动系统。

其中相关的编译配置文件在boot.bib里面,如下面所示:

;  Ethernet Boot Loader Source Module

;******************************************************************************

 

MEMORY

;   Name     Start     Size      Type

;   -------  --------  --------  ----

    DRV_GLB  8c020000  00001000  RESERVED

    BIN_FS   8c021000  00005000  RESERVED

    RAM      8c026000  00006000  RAM

    STACK    8c02c000  00004000  RESERVED

    EBOOT    8c038000  00020000  RAMIMAGE

;    EBOOT    8c038000  00040000  RAMIMAGE

 

    ; 16 MB area used to cache nk.bin while programming boot media.

    ; TBD: we may need to adjust to 01400000 (20 MB) to cache PPC 2003.

    FLSCACHE 8D000000  01000000  RESERVED

 

CONFIG

COMPRESSION=OFF

PROFILE=OFF

KERNELFIXUPS=ON

SRE=ON

ROMSTART=8c038000

ROMWIDTH=32

 

; N.B: boot media block size aligned

ROMSIZE=16000

 

MODULES

;   Name            Path                                            Memory Type

;   --------------  ----------------------------------------------  -----------

    nk.exe $(_TARGETPLATROOT)/target/$(_TGTCPU)/$(WINCEDEBUG)/EBOOT.exe EBOOT

上面对其它的东西比较简单,也就是eboot的生成内存分配,下面主要对MODULES中的东西进行详细的解释。这里涉及一些环境变量的运行,前面nk.exe是运行中需要连接的名字,中间是生成这个文件的路径。最后一个是文件连接的区域,这里是EBOOT(EBOOT    8c038000  00020000  RAMIMAGE)。中间那个路径中有许多环境变量,其中可在PB中打开build os->open release directory,然后输入set后将显示所用到的所有环境变量,其中可以看到_TARGETPLATROOT D:/WINCE500/PLATFORM/SMDK2440_TGTCPU ARMV4IWINCEDEBUG = retail。所以以上的路径$(_TARGETPLATROOT)/target/$(_TGTCPU)/$(WINCEDEBUG)/EBOOT.exe 就可以翻译为D:/WINCE500/PLATFORM/SMDK2440/target/ARMV4I/retail/eboot.exe。其中$()的意思查询环境变量的意思。其实设置环境变量的好处很多,主要就是代码的通用和移植的方便,这里就不再多说。  (待续。。。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值