S3C2450自动升级[原创作品,转载请注明出处]

来源:互联网 发布:淘宝i7主机那么便宜 编辑:程序博客网 时间:2024/05/05 21:53

S3C2450自动升级

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

Bootloader_update文件夹下有四个文件夹,分别是BLCOMMONEboot_bootFAT_LIB以及IROM_SD_TOOLBLCOMMON文件夹编译后生成oal_blcommon.lib文件,供Eboot_boot调用。FAT_LIB文件夹里面包含三个静态库文件FAT_LIB.libHSMMCEBOOT_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的相关代码如下:

if(1 == UPDATA_ALL_IMAGE)

      {

               AUTO_UPDATE_FROM_SD =TRUE;        

               ERASE_ALL_FLASH_BLOCKS =TRUE;    

               SHOW_UPDATE_LOGO = TRUE;

      }

else if( _FAT_Boot_ReadFile(_BOOT_TYPE_SD_BIN, _UPDATE_FILE_DETECT)  ||auto_updatekey_isPressed() )

      {

          //自动升级健按下进行自动升级 

               AUTO_UPDATE_FROM_SD=TRUE;         

            }

      else

      {

            AUTO_UPDATE_FROM_SD = FALSE;

      }


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

#define _UPDATE_FILE_DETECT           "DETECT  BIN"

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

Flash格式化的程序如下:

    if(1)// format flash.

               {

                         //ADDED BY ZHOUPENG FOR TEST

                         ReadDeviceSerialNumber(Serial_Block_Number,pBuf8);

                         ReadDeviceSerialNumber(Smit_Device_Serial_Block_Number,pBuf9);       

                         OALMSG(TRUE, (TEXT(" ++Format FIL (Erase All Blocks)/r/n")));

                       if (VFL_Close() != VFL_SUCCESS)

                       {

                                OALMSG(TRUE, (TEXT("[ERR] VFL_Close() Failure/r/n")));

                       }

                       if (WMR_Format_FIL() == FALSE32)

                       {

                                OALMSG(TRUE, (TEXT("[ERR] WMR_Format_FIL() Failure/r/n")));

                       }

                         if (WMR_Format_VFL() == FALSE32)

                         {

                                  OALMSG(TRUE, (TEXT("[ERR] WMR_Format_VFL() Failure/r/n")));

                         }

                         if (WMR_Format_FTL() == FALSE32)

                         {

                                  OALMSG(TRUE, (TEXT("[ERR] WMR_Format_FTL() Failure/r/n")));

                         }

                         OALMSG(TRUE, (TEXT("[INF] You can not use VFL before Format VFL/r/n")));

                         OALMSG(TRUE, (TEXT(" --Format FIL (Erase All Blocks)/r/n")));

                        WriteDeviceSerialNumber(Serial_Block_Number,pBuf8);

                         WriteDeviceSerialNumber(Smit_Device_Serial_Block_Number,pBuf9);                         

               }

     下载映像的函数如下:

 

static BOOL DownloadImage (LPDWORD pdwImageStart, LPDWORD pdwImageLength, LPDWORD pdwLaunchAddr)

{

         BYTE hdr[BL_HDRSIG_SIZE];

         DWORD dwRecLen, dwRecChk, dwRecAddr;

         BOOL fIsFlash = FALSE;

         LPBYTE lpDest = NULL;

         int nPkgNum = 0;

         BYTE nNumDownloadFiles = 1;

         DWORD dwImageStart = 0;

         DWORD dwImageLength = 0;

         RegionInfo *pCurDownloadFile;

         int i;

         *pdwImageStart = *pdwImageLength = *pdwLaunchAddr = 0;

 

         g_DownloadManifest.dwNumRegions = 0 ;

         for( i = 0 ; i < BL_MAX_BIN_REGIONS ; i++)

         {

                   g_DownloadManifest.Region[i].dwRegionStart = 0;

                   g_DownloadManifest.Region[i].dwRegionLength = 0;

                   g_DownloadManifest.Region[i].szFileName[0] = '/0';       

         }

         do

         {

                   // *.bin文件的前7个字节数据读入hdr(header)数组

                   if (!OEMReadData (BL_HDRSIG_SIZE, hdr))

                   {

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

                            HALT (BLERR_MAGIC);

                            return (FALSE);

                   }

                   // An N000FF packet is manufactured by Platform Builder when we're

                   // downloading multiple files or when we're downloading a .nb0 file.

                   if (!memcmp (hdr, "N000FF/x0A", BL_HDRSIG_SIZE))//比较数据相等时memcmp返回0

                   {

                            // read the packet checksum.

                            //

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

                            {

                                     EdbgOutputDebugString("/r/nUnable to read download manifest checksum./r/n");

                                     HALT (BLERR_MAGIC);

                                     return (FALSE);

                            }

 

                            // read BIN region descriptions (start address and length).

                            //

                            if (!OEMReadData (sizeof (DWORD), (LPBYTE) &g_DownloadManifest.dwNumRegions) ||

                            !OEMReadData ((g_DownloadManifest.dwNumRegions * sizeof(RegionInfo)), (LPBYTE) &g_DownloadManifest.Region[0]))

                            {

                                     EdbgOutputDebugString("/r/nUnable to read download manifest information./r/n");

                                     HALT (BLERR_MAGIC);

                                     return (FALSE);

                            }

                            // verify the packet checksum.

                            if (!VerifyChecksum((g_DownloadManifest.dwNumRegions * sizeof(RegionInfo)), (LPBYTE) &g_DownloadManifest.Region[0], dwRecChk))

                            {

                                     EdbgOutputDebugString ("/r/nDownload manifest packet failed checksum verification./r/n");

                                     HALT (BLERR_CHECKSUM);

                                     return (FALSE);

                            }

                            if (g_pOEMMultiBINNotify)

                            {

                                     g_pOEMMultiBINNotify((PDownloadManifest)&g_DownloadManifest);

                            }

                            // look for next download...

                            nNumDownloadFiles = (BYTE)(g_DownloadManifest.dwNumRegions + 1);      // +1 to account for this packet.

                            continue;

                   }

                   // Is this an old X000FF multi-bin packet header?  It's no longer supported.

                   else if (!memcmp (hdr, "X000FF/x0A", BL_HDRSIG_SIZE))

                   {

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

                            HALT (BLERR_MAGIC);

                            return (FALSE);

                   }

                   // Is this a standard bin image?  Check for the usual bin file signature.

                   else if (!memcmp (hdr, "B000FF/x0A", BL_HDRSIG_SIZE))//lqm:下载xip.bin,nk.bin,eboot.bin时在这里执行

                   {

                            g_bBINDownload = TRUE;

 

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

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

                            {

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

                                     HALT (BLERR_MAGIC);

                                     return (FALSE);

                            }

                   }

                   // If the header signature isn't recognized, we'll assume the

                   // download file is a raw .nb0 file.

                   //

                   else

                   {

                            g_bBINDownload = FALSE;

                   }

                   if (!g_DownloadManifest.dwNumRegions)

                   {

                            g_DownloadManifest.dwNumRegions             = 1;                           //声明*.bin有一条记录

                            g_DownloadManifest.Region[0].dwRegionStart  = dwImageStart;     //声明这条记录的起始地址

                            g_DownloadManifest.Region[0].dwRegionLength = dwImageLength;//声明这条记录的映像长度

                            // Provide the download manifest to the OEM.

                            if (g_pOEMMultiBINNotify)

                            {

                                     g_pOEMMultiBINNotify((PDownloadManifest)&g_DownloadManifest);

                            }

                   }

                   // Locate the current download manifest entry (current download file).

                   pCurDownloadFile = &g_DownloadManifest.Region[g_DownloadManifest.dwNumRegions - nNumDownloadFiles];//当前下载文件指向*.bin开始

                   // give the OEM a chance to verify memory.内存校验

                   if (g_pOEMVerifyMemory && !g_pOEMVerifyMemory (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))

                   {

                            EdbgOutputDebugString ("!OEMVERIFYMEMORY: Invalid image/r/n");//lqm:很多情况下都会执行到这里!映像不能获得?

                            HALT (BLERR_OEMVERIFY);

                            return (FALSE);

                   }

                   // check for flash image. Start erasing if it is.

                   if ( (fIsFlash = OEMIsFlashAddr(pCurDownloadFile->dwRegionStart))//lqm:校验起始地址是否在Flash相应地址区域,如果是则擦除相应下载区域

                   && !OEMStartEraseFlash (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))

                   {

                            EdbgOutputDebugString ("Invalid Flash Address/Length/r/n");

                            HALT (BLERR_FLASHADDR);

                            return (FALSE);

                   }

                   // if we're downloading a binary file, we've already downloaded part of the image when searching

                   // for a file header.  copy what we've read so far to the destination buffer, then finish downloading.

                   if (!g_bBINDownload)

                   {

                            lpDest = OEMMapMemAddr (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart);

                            memcpy(lpDest, hdr, BL_HDRSIG_SIZE);

                            // complete the file download...

                            // read data block

                            if (!OEMReadData ((pCurDownloadFile->dwRegionLength - BL_HDRSIG_SIZE), (lpDest + BL_HDRSIG_SIZE)))

                            {

                                     EdbgOutputDebugString ("ERROR: failed when reading raw binary file./r/n");

                                     HALT (BLERR_CORRUPTED_DATA);

                                     return (FALSE);

                            }

                   }

                   // we're downloading a .bin file - download each .bin record in turn...

                   else//开始下载*.bin文件到DRAM中。

                   {

                            while (OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecAddr) &&   //读取*.bin的第n条记录的地址.

                            OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecLen)  && //读取*.bin的第n条记录的长度.

                            OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecChk))    //读取*.bin的第n条记录的校验和.

                            {

                                     // last record of .bin file uses sentinel values for address and checksum.

                                     // 最后一条记录表示结束.其地址和校验和均为0.

                                     if (!dwRecAddr && !dwRecChk)

                                     {

                                               break;//读到最后一条记录时跳出循环

                                     }

                                     // map the record address (FLASH data is cached, for example)

                                     // 将存入的记录地址映射到指针地址lpDest

                                     lpDest = OEMMapMemAddr (pCurDownloadFile->dwRegionStart, dwRecAddr);

                                     // read data block

                                     if (!OEMReadData (dwRecLen, lpDest))//读取*.bin的第n条记录的内容到lpDest.这里先把*.bin的数据读到DRAM中。

  • S3C2450自动升级[原创作品,转载请注明出处]
  • S3C2450自动升级[原创作品,转载请注明出处]
  • 尊重原创,转载请注明出处
  • sas proc sql 基础入门 (原创作品,转载请注明出处 )
  • 转载请注明出处
  • 李望 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-10000290
  • 关于原始输入--XP新技术(原创,转载请注明出处)
  • [原创]WCF入门级使用教程(转载请注明出处)
  • Discuz的安装 (原创帖,转载请注明出处)
  • LAMP环境搭建 (原创帖,转载请注明出处)
  • 查看/关闭SElinux (原创帖,转载请注明出处)
  • Apache2.4权限配置(原创帖-转载请注明出处)
  • 文章为原创,转载请注明出处,欢迎评论。
  • Vista中应用程序需要Administrator权限,自动提示用户需要管理员权限的方法 (原创,转载请注明出处)
  • 【原创,转载注明出处】Android SD卡排错
  • PAGE_ALIGN 详解 纯属原创 转载注明出处
  • Vista中服务运行与NT5的差别(原创,转载请注明出处)
  • Core Aduio API--Vista中音量控制的新特点(原创,转载请注明出处)
  • SUSE Linux 启动顺序
  • OpenCV 编程简介(矩阵/图像/视频的基本读写操作)
  • uboot试验记录-添加自己的命令
  • 支付宝年会用户体验成焦点:马云痛骂,邵晓峰痛哭
  • [转]线程间操作无效: 从不是创建控件“...”的线程访问它。
  • S3C2450自动升级[原创作品,转载请注明出处]
  • 我的留学生活[8]- 与DPSS LASER 约会!哈哈~~
  • AIX系统性能监控命令
  • 更换Windows XP下的默认记事本程序
  • 木马是个什么东西
  • 想建个网站
  • JAVA调用外部进程最佳实践版组件
  • January, 26
  • 窗口关闭过程
  • 原创粉丝点击