Windows CE嵌入式开发入门——基于Xscale架构(4)

2Main函数代码分析

BLCOMMON的实现代码在/WINCE420/PUBLIC/COMMON/OAK/DRIVERS/ETHDBG/
BLCOMMON
目录下的blcommon.c文件中。

 

void BootloaderMain (void)

{

    ROMHDR *pRomHdr = NULL;  // 镜像文件的PTOC

    DWORD dwAction, dwpToc;  

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

    BOOL bDownloaded = FALSE;

 

    if (!KernelRelocate (pTOC)) {

        HALT (BLERR_KERNELRELOCATE);

    }

 

    //初始化debug支持,然后就可以用OEMWriteDebugString

    if (!OEMDebugInit ()) {

        HALT (BLERR_DBGINIT);

    }

 

    //输出版本

    EdbgOutputDebugString (NKSignon, CURRENT_VERSION_MAJOR, CURRENT_
VERSION_MINOR);

 

    //初始化平台(时钟、驱动等)

    if (!OEMPlatformInit ()) {

        HALT (BLERR_PLATINIT);

    }

 

    //准备下载

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

 

    //调用OEM指定的pre-download函数

    switch (dwAction = OEMPreDownload ()) {

    case BL_DOWNLOAD:

         //下载映像

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

         {

             //报告DownloadImage的错误

             SPIN_FOREVER;

         }

         bDownloaded = TRUE;

         //检查pToc信号("CECE")

        if (*(LPDWORD) OEMMapMemAddr (dwImageStart, dwImageStart +

    ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE) {

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

        }

else

{

EdbgOutputDebugString

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

EdbgOutputDebugString

("!! ERROR: Unable to find a table of contents in the downloaded image. If !!/r/n");

EdbgOutputDebugString

("!! this is a multi-region image, move the chain file region to an address !!/r/n");

EdbgOutputDebugString

("!! following the kernel region.  Aborting.!/r/n");

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

        //如果没有信号,将永远循环下去

            HALT (BLERR_SIGNATURE);

        }

        dwpToc = *(LPDWORD) OEMMapMemAddr (dwImageStart, dwImageStart +

    ROM_SIGNATURE_OFFSET + sizeof(ULONG));

        // 为了修正指针,需要再次映射一次

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

        //注意:必须复制或删除CLEAN_BOOT标志

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

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);

         //失败

    case BL_JUMP:

         //跳到映像之前,可以选择检查映像信号

       //注意:如果现在没有下载的映像,那么在OEMLaunch中将假定从本地存储装载

       //RAM中残留的以前的下载,这种情况下,.映像启动地址必须是0.

       //也就是映像信号程序将需要在存储或者RAM中寻找映像进行验证.

       //因此OEMOEMLaunch函数始终需要这样做.

        //

         if (g_pOEMCheckSignature)

         {

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

                 HALT(BLERR_WHQL_SIGNATURE);

         }

         //最后启动镜像,从不返回

         OEMLaunch (dwImageStart, dwImageLength, dwLaunchAddr, pRomHdr);

         // 从不返回

         default:

         HALT (BLERR_INVALIDCMD);

     }

}

 

3FLASH操作代码分析

由于FLASH操作函数比较多,在此我们分析其中的几个有代表性的函数。

BOOL OEMIsFlashAddr (DWORD dwAddr)

{

    //特殊处理Eboot,Eboot是为RAM创建,但存在于flash

    if (fileType & BOOTLOADER)

    {

       return(TRUE);

    }

    if ((dwAddr & 0xF0000000) == 0x90000000 || (dwAddr & 0xF0000000) == 0xB0000000)

    {

        return(TRUE);

    }

    return(FALSE);

}

 

static UINT16 FlashErase(DWORD dwStartBlock, DWORD dwNumBlocks)

{

   BlockLockInfo BlockLockInfo;

    if (dwStartBlock >= g_FlashInfo.dwNumBlocks || (dwStartBlock + dwNumBlocks - 1) >= g_FlashInfo.dwNumBlocks)

    {

       EdbgOutputDebugString("FlashErase: block number outside valid range./r/n");

       return(-1);

    }

  

    //Unlock全部需要删除的块

    EdbgOutputDebugString("FlashErase: Unlocking flash block(s) [0x%x, 0x%x] (please wait): ", dwStartBlock, (dwStartBlock + dwNumBlocks - 1));

    BlockLockInfo.StartBlock = dwStartBlock;

    BlockLockInfo.NumBlocks  = dwNumBlocks;

    if (!FMD_OEMIoControl(IOCTL_FMD_UNLOCK_BLOCKS, (PBYTE)&BlockLockInfo, sizeof(BlockLockInfo), NULL, 0, NULL))

    {

       EdbgOutputDebugString("/r/nWARNING: Unable to unlock all flash blocks!/r/n");

    }

    else

    {

       EdbgOutputDebugString("Done./r/n");

    }

    EdbgOutputDebugString("Erasing flash block(s) [0x%x, 0x%x] (please wait): ", dwStartBlock, (dwStartBlock + dwNumBlocks - 1));

    while (dwNumBlocks--)

    {

       if (!FMD_EraseBlock(dwStartBlock))

       {

           EdbgOutputDebugString("/r/nFlashErase: unable to erase block (0x%x)./r/n", dwStartBlock);

           return(-1);

       }

       ++dwStartBlock;

       EdbgOutputDebugString(".");

    }

   EdbgOutputDebugString("Done./r/n");

    return(0);

}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值