2450自动升级

在BSP包中,有两个bootloader文件夹,一个命名为bootloader,另一个命名为bootloader_update。Bootloader文件夹用于USB下载,调试用,bootloader_update用于生产,自动升级用。下面重点介绍bootloader_update文件夹。

Bootloader_update文件夹下有四个文件夹,分别是BLCOMMON,Eboot_boot,FAT_LIB以及IROM_SD_TOOL。BLCOMMON文件夹编译后生成oal_blcommon.lib文件,供Eboot_boot调用。FAT_LIB文件夹里面包含三个静态库文件FAT_LIB.lib,HSMMCEBOOT_LIB.lib以及SDREAD_UPDATE.lib。这些静态库封装了一些用于升级的函数。Eboot_boot文件夹编译后将会产生生产用的Eboot.bin文件,该文件即能够启动系统,也能够通过硬件平台的按键控制,实现自动升级。IROM_SD_TOOL文件夹编译后,会将前面的Eboot.bin文件封装成SD卡识别的程序,最终生成IROM_SD_EBOOT.nb0。通过三星提供的IROM_Fusing_Tool工具,将该文件烧到SD卡后,2450平台就能够实现从SD卡启动了。当然前提是硬件本身要设置跳线成SD卡启动。

主程序中(Eboot_boot文件夹)定义了三个重要的变量:AUTO_UPDATE_FROM_SD;

ERASE_ALL_FLASH_BLOCKS;

SHOW_UPDATE_LOGO。

当AUTO_UPDATE_FROM_SD为真时,Eboot将会进入升级程序,为假时将引导flash中的NK,启动系统。

当ERASE_ALL_FLASH_BLOCKS为真时,Eboot将会格式化flash,然后依次升级block0.nb0,eboot.bin,nk.bin,随后启动系统。

当SHOW_UPDATE_LOGO为真时,LCD上将会出现升级文件的提示,否则显示开机LOGO。

其中AUTO_UPDATE_FROM_SD标志位通过硬件平台的按键判断,当拨动电源键后在两秒之内回拨到LOCK位置,Eboot将识别到该LOCK标志,这时将AUTO_UPDATE_FROM_SD置高,程序进入升级状态。

ERASE_ALL_FLASH_BLOCKS标志位通过从SD卡中的update.txt文件中读取。

AUTO_UPDATE_FROM_SD的相关代码如下:

[cpp]  view plain copy
  1. if(1 == UPDATA_ALL_IMAGE)  
  2.   
  3.       {  
  4.   
  5.                AUTO_UPDATE_FROM_SD =TRUE;           
  6.   
  7.                ERASE_ALL_FLASH_BLOCKS =TRUE;       
  8.   
  9.                SHOW_UPDATE_LOGO = TRUE;  
  10.   
  11.       }  
  12.   
  13. else if( _FAT_Boot_ReadFile(_BOOT_TYPE_SD_BIN, _UPDATE_FILE_DETECT)  ||auto_updatekey_isPressed() )  
  14.   
  15.       {  
  16.   
  17.           //自动升级健按下进行自动升级    
  18.   
  19.                AUTO_UPDATE_FROM_SD=TRUE;            
  20.   
  21.             }  
  22.   
  23.       else  
  24.   
  25.       {  
  26.   
  27.             AUTO_UPDATE_FROM_SD = FALSE;  
  28.   
  29.       }  


    其中_FAT_Boot_ReadFile()函数用于从SD卡中读取_UPDATE_FILE_DETECT文件,该字符串在最前面有如下定义:

#define _UPDATE_FILE_DETECT           "DETECT  BIN"

auto_updatekey_isPressed()函数用于检测拍照键是否按下,从这里可以看出,如果SD卡中存在detect.bin文件,则升级时不用再按住拍照键了。如果没有则必须按住拍照键。

Flash格式化的程序如下:

    

[cpp]  view plain copy
  1. if(1)// format flash.  
  2.   
  3.                {  
  4.   
  5.                          //ADDED BY ZHOUPENG FOR TEST  
  6.   
  7.                          ReadDeviceSerialNumber(Serial_Block_Number,pBuf8);  
  8.   
  9.                          ReadDeviceSerialNumber(Smit_Device_Serial_Block_Number,pBuf9);          
  10.   
  11.                          OALMSG(TRUE, (TEXT(" ++Format FIL (Erase All Blocks)/r/n")));  
  12.   
  13.                        if (VFL_Close() != VFL_SUCCESS)  
  14.   
  15.                        {  
  16.   
  17.                                 OALMSG(TRUE, (TEXT("[ERR] VFL_Close() Failure/r/n")));  
  18.   
  19.                        }  
  20.   
  21.                        if (WMR_Format_FIL() == FALSE32)  
  22.   
  23.                        {  
  24.   
  25.                                 OALMSG(TRUE, (TEXT("[ERR] WMR_Format_FIL() Failure/r/n")));  
  26.   
  27.                        }  
  28.   
  29.                          if (WMR_Format_VFL() == FALSE32)  
  30.   
  31.                          {  
  32.   
  33.                                   OALMSG(TRUE, (TEXT("[ERR] WMR_Format_VFL() Failure/r/n")));  
  34.   
  35.                          }  
  36.   
  37.                          if (WMR_Format_FTL() == FALSE32)  
  38.   
  39.                          {  
  40.   
  41.                                   OALMSG(TRUE, (TEXT("[ERR] WMR_Format_FTL() Failure/r/n")));  
  42.   
  43.                          }  
  44.   
  45.                          OALMSG(TRUE, (TEXT("[INF] You can not use VFL before Format VFL/r/n")));  
  46.   
  47.                          OALMSG(TRUE, (TEXT(" --Format FIL (Erase All Blocks)/r/n")));  
  48.   
  49.                         WriteDeviceSerialNumber(Serial_Block_Number,pBuf8);  
  50.   
  51.                          WriteDeviceSerialNumber(Smit_Device_Serial_Block_Number,pBuf9);                            
  52.   
  53.                }  
      下载映像的函数如下:

 

[cpp]  view plain copy
  1. static BOOL DownloadImage (LPDWORD pdwImageStart, LPDWORD pdwImageLength, LPDWORD pdwLaunchAddr)  
  2.   
  3. {  
  4.   
  5.          BYTE hdr[BL_HDRSIG_SIZE];  
  6.   
  7.          DWORD dwRecLen, dwRecChk, dwRecAddr;  
  8.   
  9.          BOOL fIsFlash = FALSE;  
  10.   
  11.          LPBYTE lpDest = NULL;  
  12.   
  13.          int nPkgNum = 0;  
  14.   
  15.          BYTE nNumDownloadFiles = 1;  
  16.   
  17.          DWORD dwImageStart = 0;  
  18.   
  19.          DWORD dwImageLength = 0;  
  20.   
  21.          RegionInfo *pCurDownloadFile;  
  22.   
  23.          int i;  
  24.   
  25.          *pdwImageStart = *pdwImageLength = *pdwLaunchAddr = 0;  
  26.   
  27.    
  28.   
  29.          g_DownloadManifest.dwNumRegions = 0 ;  
  30.   
  31.          for( i = 0 ; i < BL_MAX_BIN_REGIONS ; i++)  
  32.   
  33.          {  
  34.   
  35.                    g_DownloadManifest.Region[i].dwRegionStart = 0;  
  36.   
  37.                    g_DownloadManifest.Region[i].dwRegionLength = 0;  
  38.   
  39.                    g_DownloadManifest.Region[i].szFileName[0] = '/0';          
  40.   
  41.          }  
  42.   
  43.          do  
  44.   
  45.          {  
  46.   
  47.                    // 将*.bin文件的前7个字节数据读入hdr(header)数组  
  48.   
  49.                    if (!OEMReadData (BL_HDRSIG_SIZE, hdr))  
  50.   
  51.                    {  
  52.   
  53.                             EdbgOutputDebugString ("/r/nUnable to read image signature./r/n");  
  54.   
  55.                             HALT (BLERR_MAGIC);  
  56.   
  57.                             return (FALSE);  
  58.   
  59.                    }  
  60.   
  61.                    // An N000FF packet is manufactured by Platform Builder when we're  
  62.   
  63.                    // downloading multiple files or when we're downloading a .nb0 file.  
  64.   
  65.                    if (!memcmp (hdr, "N000FF/x0A", BL_HDRSIG_SIZE))//比较数据相等时memcmp返回0  
  66.   
  67.                    {  
  68.   
  69.                             // read the packet checksum.  
  70.   
  71.                             //  
  72.   
  73.                             if (!OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecChk))  
  74.   
  75.                             {  
  76.   
  77.                                      EdbgOutputDebugString("/r/nUnable to read download manifest checksum./r/n");  
  78.   
  79.                                      HALT (BLERR_MAGIC);  
  80.   
  81.                                      return (FALSE);  
  82.   
  83.                             }  
  84.   
  85.    
  86.   
  87.                             // read BIN region descriptions (start address and length).  
  88.   
  89.                             //  
  90.   
  91.                             if (!OEMReadData (sizeof (DWORD), (LPBYTE) &g_DownloadManifest.dwNumRegions) ||  
  92.   
  93.                             !OEMReadData ((g_DownloadManifest.dwNumRegions * sizeof(RegionInfo)), (LPBYTE) &g_DownloadManifest.Region[0]))  
  94.   
  95.                             {  
  96.   
  97.                                      EdbgOutputDebugString("/r/nUnable to read download manifest information./r/n");  
  98.   
  99.                                      HALT (BLERR_MAGIC);  
  100.   
  101.                                      return (FALSE);  
  102.   
  103.                             }  
  104.   
  105.                             // verify the packet checksum.  
  106.   
  107.                             if (!VerifyChecksum((g_DownloadManifest.dwNumRegions * sizeof(RegionInfo)), (LPBYTE) &g_DownloadManifest.Region[0], dwRecChk))  
  108.   
  109.                             {  
  110.   
  111.                                      EdbgOutputDebugString ("/r/nDownload manifest packet failed checksum verification./r/n");  
  112.   
  113.                                      HALT (BLERR_CHECKSUM);  
  114.   
  115.                                      return (FALSE);  
  116.   
  117.                             }  
  118.   
  119.                             if (g_pOEMMultiBINNotify)  
  120.   
  121.                             {  
  122.   
  123.                                      g_pOEMMultiBINNotify((PDownloadManifest)&g_DownloadManifest);  
  124.   
  125.                             }  
  126.   
  127.                             // look for next download...  
  128.   
  129.                             nNumDownloadFiles = (BYTE)(g_DownloadManifest.dwNumRegions + 1);      // +1 to account for this packet.  
  130.   
  131.                             continue;  
  132.   
  133.                    }  
  134.   
  135.                    // Is this an old X000FF multi-bin packet header?  It's no longer supported.  
  136.   
  137.                    else if (!memcmp (hdr, "X000FF/x0A", BL_HDRSIG_SIZE))  
  138.   
  139.                    {  
  140.   
  141.                             EdbgOutputDebugString ("ERROR: The X000FF packet is an old-style multi-bin download manifest and it's no longer supported. /r/nPlease update your Platform Builder installation in you want to download multiple files./r/n");  
  142.   
  143.                             HALT (BLERR_MAGIC);  
  144.   
  145.                             return (FALSE);  
  146.   
  147.                    }  
  148.   
  149.                    // Is this a standard bin image?  Check for the usual bin file signature.  
  150.   
  151.                    else if (!memcmp (hdr, "B000FF/x0A", BL_HDRSIG_SIZE))//lqm:下载xip.bin,nk.bin,eboot.bin时在这里执行  
  152.   
  153.                    {  
  154.   
  155.                             g_bBINDownload = TRUE;  
  156.   
  157.    
  158.   
  159.                             if (!OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageStart)//读取*.bin前7个头字节后的一个DWORD到dwImageStart。*.bin记录了其映像起始地址  
  160.   
  161.                                      || !OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageLength))//读取上面接着的一个DWORD到dwImageLength。*.bin记录了其映像长度  
  162.   
  163.                             {  
  164.   
  165.                                      EdbgOutputDebugString ("Unable to read image start/length/r/n");  
  166.   
  167.                                      HALT (BLERR_MAGIC);  
  168.   
  169.                                      return (FALSE);  
  170.   
  171.                             }  
  172.   
  173.                    }  
  174.   
  175.                    // If the header signature isn't recognized, we'll assume the  
  176.   
  177.                    // download file is a raw .nb0 file.  
  178.   
  179.                    //  
  180.   
  181.                    else  
  182.   
  183.                    {  
  184.   
  185.                             g_bBINDownload = FALSE;  
  186.   
  187.                    }  
  188.   
  189.                    if (!g_DownloadManifest.dwNumRegions)  
  190.   
  191.                    {  
  192.   
  193.                             g_DownloadManifest.dwNumRegions             = 1;                           //声明*.bin有一条记录  
  194.   
  195.                             g_DownloadManifest.Region[0].dwRegionStart  = dwImageStart;     //声明这条记录的起始地址  
  196.   
  197.                             g_DownloadManifest.Region[0].dwRegionLength = dwImageLength;//声明这条记录的映像长度  
  198.   
  199.                             // Provide the download manifest to the OEM.  
  200.   
  201.                             if (g_pOEMMultiBINNotify)  
  202.   
  203.                             {  
  204.   
  205.                                      g_pOEMMultiBINNotify((PDownloadManifest)&g_DownloadManifest);  
  206.   
  207.                             }  
  208.   
  209.                    }  
  210.   
  211.                    // Locate the current download manifest entry (current download file).  
  212.   
  213.                    pCurDownloadFile = &g_DownloadManifest.Region[g_DownloadManifest.dwNumRegions - nNumDownloadFiles];//当前下载文件指向*.bin开始  
  214.   
  215.                    // give the OEM a chance to verify memory.内存校验  
  216.   
  217.                    if (g_pOEMVerifyMemory && !g_pOEMVerifyMemory (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))  
  218.   
  219.                    {  
  220.   
  221.                             EdbgOutputDebugString ("!OEMVERIFYMEMORY: Invalid image/r/n");//lqm:很多情况下都会执行到这里!映像不能获得?  
  222.   
  223.                             HALT (BLERR_OEMVERIFY);  
  224.   
  225.                             return (FALSE);  
  226.   
  227.                    }  
  228.   
  229.                    // check for flash image. Start erasing if it is.  
  230.   
  231.                    if ( (fIsFlash = OEMIsFlashAddr(pCurDownloadFile->dwRegionStart))//lqm:校验起始地址是否在Flash相应地址区域,如果是则擦除相应下载区域  
  232.   
  233.                    && !OEMStartEraseFlash (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))  
  234.   
  235.                    {  
  236.   
  237.                             EdbgOutputDebugString ("Invalid Flash Address/Length/r/n");  
  238.   
  239.                             HALT (BLERR_FLASHADDR);  
  240.   
  241.                             return (FALSE);  
  242.   
  243.                    }  
  244.   
  245.                    // if we're downloading a binary file, we've already downloaded part of the image when searching  
  246.   
  247.                    // for a file header.  copy what we've read so far to the destination buffer, then finish downloading.  
  248.   
  249.                    if (!g_bBINDownload)  
  250.   
  251.                    {  
  252.   
  253.                             lpDest = OEMMapMemAddr (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart);  
  254.   
  255.                             memcpy(lpDest, hdr, BL_HDRSIG_SIZE);  
  256.   
  257.                             // complete the file download...  
  258.   
  259.                             // read data block  
  260.   
  261.                             if (!OEMReadData ((pCurDownloadFile->dwRegionLength - BL_HDRSIG_SIZE), (lpDest + BL_HDRSIG_SIZE)))  
  262.   
  263.                             {  
  264.   
  265.                                      EdbgOutputDebugString ("ERROR: failed when reading raw binary file./r/n");  
  266.   
  267.                                      HALT (BLERR_CORRUPTED_DATA);  
  268.   
  269.                                      return (FALSE);  
  270.   
  271.                             }  
  272.   
  273.                    }  
  274.   
  275.                    // we're downloading a .bin file - download each .bin record in turn...  
  276.   
  277.                    else//开始下载*.bin文件到DRAM中。  
  278.   
  279.                    {  
  280.   
  281.                             while (OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecAddr) &&   //读取*.bin的第n条记录的地址.  
  282.   
  283.                             OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecLen)  && //读取*.bin的第n条记录的长度.  
  284.   
  285.                             OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecChk))    //读取*.bin的第n条记录的校验和.  
  286.   
  287.                             {  
  288.   
  289.                                      // last record of .bin file uses sentinel values for address and checksum.  
  290.   
  291.                                      // 最后一条记录表示结束.其地址和校验和均为0.  
  292.   
  293.                                      if (!dwRecAddr && !dwRecChk)  
  294.   
  295.                                      {  
  296.   
  297.                                                break;//读到最后一条记录时跳出循环  
  298.   
  299.                                      }  
  300.   
  301.                                      // map the record address (FLASH data is cached, for example)  
  302.   
  303.                                      // 将存入的记录地址映射到指针地址lpDest  
  304.   
  305.                                      lpDest = OEMMapMemAddr (pCurDownloadFile->dwRegionStart, dwRecAddr);  
  306.   
  307.                                      // read data block  
  308.   
  309.                                      if (!OEMReadData (dwRecLen, lpDest))//读取*.bin的第n条记录的内容到lpDest.这里先把*.bin的数据读到DRAM中。  
  310.   
  311.                                      {  
  312.   
  313.                                                EdbgOutputDebugString ("****** Data record %d corrupted, ABORT!!! ******/r/n", nPkgNum);  
  314.   
  315.                                                HALT (BLERR_CORRUPTED_DATA);  
  316.   
  317.                                                return (FALSE);  
  318.   
  319.                                      }  
  320.   
  321.                                      if (!VerifyChecksum (dwRecLen, lpDest, dwRecChk))//每读取一条记录则校验一次数据  
  322.   
  323.                                      {  
  324.   
  325.                                                EdbgOutputDebugString ("****** Checksum failure on record %d, ABORT!!! ******/r/n", nPkgNum);  
  326.   
  327.                                                HALT (BLERR_CHECKSUM);  
  328.   
  329.                                                return (FALSE);  
  330.   
  331.                                      }  
  332.   
  333.                                      // Look for ROMHDR to compute ROM offset.  NOTE: romimage guarantees that the record containing  
  334.   
  335.                                      // the TOC signature and pointer will always come before the record that contains the ROMHDR contents.  
  336.   
  337.                                      //  
  338.   
  339.                                      if (dwRecLen == sizeof(ROMHDR) && (*(LPDWORD) OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE))  
  340.   
  341.                                      {  
  342.   
  343.                                                DWORD dwTempOffset = (dwRecAddr - *(LPDWORD)OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG)));  
  344.   
  345.                                                ROMHDR *pROMHdr = (ROMHDR *)lpDest;  
  346.   
  347.                                                // Check to make sure this record really contains the ROMHDR.  
  348.   
  349.                                                //  
  350.   
  351.                                                if ((pROMHdr->physfirst == (pCurDownloadFile->dwRegionStart - dwTempOffset)) &&  
  352.   
  353.                                                         (pROMHdr->physlast  == (pCurDownloadFile->dwRegionStart - dwTempOffset + pCurDownloadFile->dwRegionLength)) &&  
  354.   
  355.                                                         (DWORD)(HIWORD(pROMHdr->dllfirst << 16) <= pROMHdr->dlllast) &&  
  356.   
  357.                                                         (DWORD)(LOWORD(pROMHdr->dllfirst << 16) <= pROMHdr->dlllast))  
  358.   
  359.                                                {  
  360.   
  361.                                                         g_dwROMOffset = dwTempOffset;  
  362.   
  363.                                                         EdbgOutputDebugString("rom_offset=0x%x./r/n", g_dwROMOffset);   
  364.   
  365.                                                }  
  366.   
  367.                                      }  
  368.   
  369.                                      // verify partial checksum  
  370.   
  371.                                      OEMShowProgress (nPkgNum ++);  
  372.   
  373.                                      // lqm added Progress in LCD.10-01-22  
  374.   
  375.                                      while( nPkgNum>=8 )  
  376.   
  377.                                      {  
  378.   
  379.                                                nPkgNum = 0;  
  380.   
  381.                                                LcdDrawString(">");  
  382.   
  383.                                      }  
  384.   
  385.                                      // end added.  
  386.   
  387.                             }  
  388.   
  389.                    }  
  390.   
  391.                    if (g_bBINDownload)  
  392.   
  393.                    {  
  394.   
  395.                             // Does this .bin file contain a TOC?  
  396.   
  397.                             if (*(LPDWORD) OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE)    //+ ksk 20051219  
  398.   
  399.                             {  
  400.   
  401.                                      // Contain the kernel?  
  402.   
  403.                                      if (IsKernelRegion(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))  
  404.   
  405.                                      {  
  406.   
  407.                                                *pdwImageStart  = pCurDownloadFile->dwRegionStart;  
  408.   
  409.                                                *pdwImageLength = pCurDownloadFile->dwRegionLength;  
  410.   
  411.                                                *pdwLaunchAddr  = dwRecLen;  
  412.   
  413.                                      }  
  414.   
  415.                             }  
  416.   
  417.                             // No TOC - not made by romimage.  However, if we're downloading more than one  
  418.   
  419.                             // .bin file, it's probably chain.bin which doesn't have a TOC (and which isn't  
  420.   
  421.                             // going to be downloaded on its own) and we should ignore it.  
  422.   
  423.                             //  
  424.   
  425.                             else if (g_DownloadManifest.dwNumRegions == 1)  
  426.   
  427.                             {  
  428.   
  429.                                      *pdwImageStart  = pCurDownloadFile->dwRegionStart;  
  430.   
  431.                                      *pdwImageLength = pCurDownloadFile->dwRegionLength;  
  432.   
  433.                                      *pdwLaunchAddr  = dwRecLen;  
  434.   
  435.                             }  
  436.   
  437.                    }  
  438.   
  439.                    else    // Raw binary file.  
  440.   
  441.                    {  
  442.   
  443.                             *pdwImageStart  = pCurDownloadFile->dwRegionStart;  
  444.   
  445.                             *pdwLaunchAddr  = pCurDownloadFile->dwRegionStart;  
  446.   
  447.                             *pdwImageLength = pCurDownloadFile->dwRegionLength;  
  448.   
  449.                    }  
  450.   
  451.                    // write to flash if it's flash image  
  452.   
  453.                    if (fIsFlash)  
  454.   
  455.                    {  
  456.   
  457.                             // finish the flash erase  
  458.   
  459.                             if (!OEMFinishEraseFlash ())  
  460.   
  461.                             {  
  462.   
  463.                                      HALT (BLERR_FLASH_ERASE);  
  464.   
  465.                                      return (FALSE);  
  466.   
  467.                             }  
  468.   
  469.                             // Before writing the image to flash, optionally check the image signature.  
  470.   
  471.                             if (g_bBINDownload && g_pOEMCheckSignature)  
  472.   
  473.                             {  
  474.   
  475.                                      if (!g_pOEMCheckSignature(pCurDownloadFile->dwRegionStart, g_dwROMOffset, *pdwLaunchAddr, TRUE))  
  476.   
  477.                                      HALT(BLERR_CAT_SIGNATURE);  
  478.   
  479.                             }  
  480.   
  481.                    }  
  482.   
  483.          }  
  484.   
  485.          while (--nNumDownloadFiles);  
  486.   
  487.    
  488.   
  489.          if (fIsFlash)  
  490.   
  491.          {  
  492.   
  493.                    nNumDownloadFiles = (BYTE)g_DownloadManifest.dwNumRegions;  
  494.   
  495.                    while (nNumDownloadFiles--)  
  496.   
  497.                    {  
  498.   
  499.                             if (!OEMWriteFlash (g_DownloadManifest.Region[nNumDownloadFiles].dwRegionStart, g_DownloadManifest.Region[nNumDownloadFiles].dwRegionLength))  
  500.   
  501.                             {  
  502.   
  503.                                      HALT (BLERR_FLASH_WRITE);  
  504.   
  505.                                      return (FALSE);  
  506.   
  507.                             }  
  508.   
  509.                    }  
  510.   
  511.          }  
  512.   
  513.          return (TRUE);  
  514.   
  515. }  
  

上面程序中有如下代码:

OEMShowProgress (nPkgNum ++);

while( nPkgNum>=8 )

{

           nPkgNum = 0;

           LcdDrawString(">");

}

该程序放在反复从SD卡中读取xip.bin的一条条记录的while循环中,这里是为了在升级界面上显示升级的进度。LcdDrawString(“>”)函数是调用了LcdDraw.c中的函数,用于在LCD上绘图。

这里一定要了解xip.bin的文件格式,否则很难理解整个数据流的流程。

Xip.bin以及NK.bin的组成:

组成:标记(7)+Image开始地址(1)+Image长度(1)  
             记录0地址+记录0长+记录0校验和+记录0内容(文件内容)
            记录1地址+记录1长+记录1校验和+记录1内容(文件内容)
             ......

      结束符号

从上面的程序可以看出,

if (!OEMReadData (BL_HDRSIG_SIZE, hdr))

           {

                    EdbgOutputDebugString ("/r/nUnable to read image signature./r/n");

                    HALT (BLERR_MAGIC);

                    return (FALSE);

           }

即是将xip.bin的前7个字节的数据读到数组hdr,供后面分析所读的文件的类型。

if (!OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageStart)//读取*.bin前7个头字节后的一个DWORD到dwImageStart。*.bin记录了其映像起始地址

                             || !OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageLength))//读取上面接着的一个DWORD到dwImageLength。*.bin记录了其映像长度

                    {

                             EdbgOutputDebugString ("Unable to read image start/length/r/n");

                             HALT (BLERR_MAGIC);

                             return (FALSE);

                    }

则是将紧接着前7个字节的两个WORD数据读到dwImageStart和dwImageLength。随后的

while (OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecAddr) &&   

//读取*.bin的第n条记录的地址.

                    OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecLen)  &&

 //读取*.bin的第n条记录的长度.

                    OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecChk))  

 //读取*.bin的第n条记录的校验和.

则开始一条条的解析xip.bin的记录。

if (!OEMReadData (dwRecLen, lpDest))

{

           EdbgOutputDebugString ("****** Data record %d corrupted, ABORT!!! ******/r/n", nPkgNum);

                                       HALT (BLERR_CORRUPTED_DATA);

           return (FALSE);

}

用于将读取到的第N条记录存放到lpDest.

分析要下载的文件并写入flash的代码如下:

[cpp]  view plain copy
  1. void OEMLaunch( DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr )  
  2.   
  3. {  
  4.   
  5. DWORD dwPhysLaunchAddr;   
  6.   
  7.          OALMSG(1, (TEXT("+OEMLaunch./r/n")));  
  8.   
  9. // If the user requested that a disk image (stored in RAM now) be written to the SmartMedia card, so it now.   
  10.   
  11. if (g_bDownloadImage) // && (g_pBootCfg->ConfigFlags & TARGET_TYPE_NAND))  
  12.   
  13. {  
  14.   
  15.            // Since this platform only supports RAM images, the image cache address is the same as the image RAM address.   
  16.   
  17.            switch (g_ImageType)  
  18.   
  19.            {  
  20.   
  21.            case IMAGE_TYPE_STEPLDR://stepldr.bin  
  22.   
  23.                     if (!WriteRawImageToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr))  
  24.   
  25.                     {  
  26.   
  27.                              OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media./r/n")));  
  28.   
  29.                              goto CleanUp;  
  30.   
  31.                     }  
  32.   
  33.                     OALMSG(TRUE, (TEXT("INFO: Step loader image stored to Smart Media.  Please Reboot.  Halting.../r/n")));  
  34.   
  35.             if (g_bAutoDownload == TRUE)  
  36.   
  37.             {  
  38.   
  39.                              return ;  
  40.   
  41.             }  
  42.   
  43.                     while(1);  
  44.   
  45.                     break;  
  46.   
  47.    
  48.   
  49.            case IMAGE_TYPE_LOADER://eboot.bin  
  50.   
  51.                     g_pTOC->id[0].dwLoadAddress = dwImageStart;  
  52.   
  53.                     g_pTOC->id[0].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength);  
  54.   
  55.                     if (!WriteRawImageToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr))  
  56.   
  57.                     {  
  58.   
  59.                              OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media./r/n")));  
  60.   
  61.                              goto CleanUp;  
  62.   
  63.                     }  
  64.   
  65.                     if (dwLaunchAddr && (g_pTOC->id[0].dwJumpAddress != dwLaunchAddr))  
  66.   
  67.                     {  
  68.   
  69.                              g_pTOC->id[0].dwJumpAddress = dwLaunchAddr;  
  70.   
  71.                            #if 0 // don't write TOC after download Eboot  
  72.   
  73.                              if ( !TOC_Write() ) {  
  74.   
  75.                                        EdbgOutputDebugString("*** OEMLaunch ERROR: TOC_Write failed! Next boot may not load from disk *** /r/n");  
  76.   
  77.                              }  
  78.   
  79.                              TOC_Print();  
  80.   
  81.                            #endif   // by hmseo - 061123  
  82.   
  83.                     }  
  84.   
  85.                     OALMSG(TRUE, (TEXT("INFO: Eboot image stored to Smart Media.  Please Reboot.  Halting.../r/n")));  
  86.   
  87.                     if (g_bAutoDownload == TRUE)  
  88.   
  89.                     {  
  90.   
  91.                              return ;  
  92.   
  93.                     }  
  94.   
  95.                     while(1);  
  96.   
  97.                     break;         
  98.   
  99.            case IMAGE_TYPE_RAMIMAGE://NK.bin  
  100.   
  101.                     OALMSG(1, (TEXT("+IMAGE_TYPE_RAMIMAGE dwImageStart:%08x.,dwLaunchAddr : %08x/r/n"),dwImageStart,dwLaunchAddr));  
  102.   
  103.                     g_pTOC->id[g_dwTocEntry].dwLoadAddress = dwImageStart;  
  104.   
  105.                     g_pTOC->id[g_dwTocEntry].dwTtlSectors = FILE_TO_SECTOR_SIZE(dwImageLength);  
  106.   
  107.                     // 将NK.bin写到flash.  
  108.   
  109.                     if (!WriteOSImageToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr))  
  110.   
  111.                     {  
  112.   
  113.                              OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media./r/n")));  
  114.   
  115.                              goto CleanUp;  
  116.   
  117.                     }  
  118.   
  119.                     EdbgOutputDebugString("INFO1:dwLaunchAdd : %08x  g_pTOC->id[0].dwJumpAddress :%08x, g_pTOC->id[1].dwJumpAddress :%08x/r /r/n", dwLaunchAddr, g_pTOC->id[0].dwJumpAddress,g_pTOC->id[1].dwJumpAddress);  
  120.   
  121.                     if (dwLaunchAddr && (g_pTOC->id[g_dwTocEntry].dwJumpAddress != dwLaunchAddr))  
  122.   
  123.                     {  
  124.   
  125.                              g_pTOC->id[g_dwTocEntry].dwJumpAddress = dwLaunchAddr;  
  126.   
  127.                              if ( !TOC_Write() ) //写TOC文件  
  128.   
  129.                              {  
  130.   
  131.                                        EdbgOutputDebugString("*** OEMLaunch ERROR: TOC_Write failed! Next boot may not load from disk *** /r/n");  
  132.   
  133.                              }  
  134.   
  135.                              //masked by denis_wei for test 2009-02-05   TOC_Print();  
  136.   
  137.                     }  
  138.   
  139.                     else  
  140.   
  141.                     {  
  142.   
  143.                              dwLaunchAddr= g_pTOC->id[g_dwTocEntry].dwJumpAddress;  
  144.   
  145.                              EdbgOutputDebugString("INFO2: using TOC[%d] dwJumpAddress: 0x%x/r/n", g_dwTocEntry, dwLaunchAddr);  
  146.   
  147.                     }  
  148.   
  149.                     break;  
  150.   
  151.            }  
  152.   
  153.            if(ERASE_ALL_FLASH_BLOCKS)//lqm added.10-01-22  
  154.   
  155.            {  
  156.   
  157.                     LcdSetStringPosition(1,15);// lqm added.10-01-22  
  158.   
  159.                     LcdDrawString("Starting WINCE,Please Wait......");// lqm added.10-01-22  
  160.   
  161.                     //LcdSetStringPosition(1,16);// lqm added.10-01-22  
  162.   
  163.            }  
  164.   
  165.            if ( !ReadOSImageFromBootMedia( ) )//从FLASH读取映像到DRAM.  
  166.   
  167.            {  
  168.   
  169.                     OALMSG(OAL_ERROR, (TEXT("OEMPlatformInit ERROR: Failed to load kernel region into RAM./r/n")));  
  170.   
  171.                     SpinForever();  
  172.   
  173.            }  
  174.   
  175. }  
  176.   
  177.          OALMSG(1, (TEXT("waitforconnect/r/n")));  
  178.   
  179.          if (dwLaunchAddr && (g_pTOC->id[g_dwTocEntry].dwJumpAddress != dwLaunchAddr))  
  180.   
  181. {  
  182.   
  183.            g_pTOC->id[g_dwTocEntry].dwJumpAddress = dwLaunchAddr;  
  184.   
  185. }  
  186.   
  187. else  
  188.   
  189. {  
  190.   
  191.            dwLaunchAddr= g_pTOC->id[g_dwTocEntry].dwJumpAddress;  
  192.   
  193.            OALMSG(OAL_INFO, (TEXT("INFO: using TOC[%d] dwJumpAddress: 0x%x/r/n"), g_dwTocEntry, dwLaunchAddr));  
  194.   
  195. }  
  196.   
  197.    
  198.   
  199. // Jump to downloaded image (use the physical address since we'll be turning the MMU off)...  
  200.   
  201. //  
  202.   
  203. dwPhysLaunchAddr = (DWORD)OALVAtoPA((void *)dwLaunchAddr);  
  204.   
  205. OALMSG(TRUE, (TEXT("INFO: OEMLaunch: Jumping to Physical Address 0x%Xh (Virtual Address 0x%Xh).../r/n/r/n/r/n"), dwPhysLaunchAddr, dwLaunchAddr));  
  206.   
  207. // Jump...  
  208.   
  209. if( g_bAutoDownload == TRUE )  
  210.   
  211. {  
  212.   
  213. OALMSG(TRUE, (TEXT("INFO: auto update (BLOCK0IMAGE  EBOOT  NK) SUCCESS!/r/n")));}  
  214.   
  215. Launch(dwPhysLaunchAddr);//跳到指定物理地址运行程序.  
  216.   
  217.   
  218. CleanUp:  
  219.   
  220.    
  221.   
  222. OALMSG(TRUE, (TEXT("ERROR: OEMLaunch: Halting.../r/n")));  
  223.   
  224. SpinForever();  
  225.   
  226. }  
  227.   
  228. 在上面代码中,如下代码用于将已经读入DRAM的数据烧写到flash.  
  229.   
  230. if (!WriteOSImageToBootMedia(dwImageStart, dwImageLength, dwLaunchAddr))  
  231.   
  232. {  
  233.   
  234.            OALMSG(OAL_ERROR, (TEXT("ERROR: OEMLaunch: Failed to store image to Smart Media./r/n")));  
  235.   
  236.            goto CleanUp;  
  237.   
  238. }  
整个bootloader代码量大,但是细下心来慢慢分析,其实不难理解。这里就不一一分析了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值