S3C2450自动升级

在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的相关代码如下:

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)//读取*.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);

}

}

// 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自动升级[原创作品,转载请注明出处]相关推荐

  1. 李望 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-10000290

    一次汇编分析的经历 关键词(为了搜索引擎优化,为了点击量) 寄存器.ia32.AT&T汇编.intel汇编.x86架构.x64架构 背景 为了想知道为什么i++ ++i不是原子操作 测试方法 ...

  2. 王鸿飞原创作品转载请注明出处《软件工程(C编码实践篇)》MOOC课程http://mooc.study.163.com/course/USTC-10000

    <软件工程>学习心得与感悟             还清楚地记得入学面试时院长问我的问题,"为什么要报考软件学院"?我坚定地回答,"我要来科大学习专业.规范的 ...

  3. ev3 java编程_使用C语言开发EV3程序(原创,转载请注明出处)

    2.安装c4ev3(http://c4ev3.github.io/),双击c4ev3-withGCC-setup.exe进行安装,默认安装即可.如果你下载的是带GCC的安装包,接下来会自动安装Code ...

  4. 查看文件时去除注释说明内容(原创贴-转载请注明出处)

    需求说明:好多软件配置文件中会有许多以#开头的注释说明内容和空行,需求是在查看文件的时候不显示这些内容. 1:过滤掉以#开头的行. 命令格式:cat 文件路径 | grep '^#'举例:cat /u ...

  5. 淘宝网的实习生笔试题以及经历--2011 4 1(转载请注明出处,即原创网址)

      昨天晚上7:00在西北工业大学,参加了淘宝网的实习生笔试(技术类),我应聘的是软件研发类.这一方面的人很多. 愚人节这一天,而且又下起了雨,路上车慢的很,感觉挺不顺利的,心情有点糟.到达笔试现场后 ...

  6. 片上总线Wishbone 学习—— 转载请注明出处:http://blog.csdn.net/ce123

    片上总线Wishbone 学习(零)前言 声明:版权所有,欢迎转载! 转载请注明出处:http://blog.csdn.net/ce123 为了更加升入的理解片上系统,比如S3C2440等,今天开始学 ...

  7. 引用请注明出处和转载请注明出处?我的看法

    很多文章和网站 都有这么一条: 引用请注明出处和转载请注明出处,有的无非多了个什么 保留法律权力 之类的 其实想想看,国外XX 小站 "拿去用了" 怎么办,起诉? BT下载&quo ...

  8. 手写多位数字识别器实现 (转载请注明出处!)

    1.主要功能 ①界面化的输入方式,进行实时数字识别 ②可以识别多位的数字,例如23,234 ③CNN进行数字识别 2.运行环境 Windows10.python3.7+.tensorflow2.x 3 ...

  9. 面试常问的算法题,吐血总结,转载请注明出处,然后不要忘记点赞!

    面试常问的算法题,吐血总结,转载请注明出处,然后不要忘记点赞! 本人是硕士,西北地区一个末流211,投了四十家公司,面试了二十五次左右,公司大概有百度.阿里.腾讯.字节.华为.海康.美团(给我一天打了 ...

最新文章

  1. 如何在ROS中使用PCL—数据格式(1)
  2. IaaS,PaaS和SaaS,又衍生出CaaS,NaaS和MaaS
  3. 每日一道算法题 - LongestWord(easy-1)
  4. 正则 ?= 和 ?= 用法 以及零宽断言等概念
  5. Slack推安全企业加密管理可轻易用密钥控制数据
  6. mysql中以指定字段去重_数据库根据指定字段去重
  7. Spring Boot 入门小目标 3 --- 先来试着热部署
  8. 在阿里巴巴工作是一种怎样的体验?
  9. 1268:【例9.12】完全背包问题
  10. unix 系统已经消亡了吗_世界上一半的语言正在消亡。 我们应该保存它们吗?
  11. linux安装redis和mysql
  12. 从整体上看UML——思维导图
  13. oracle比较日期大小函数输出,oracle 日期比较及惯用函数
  14. UI库colorui的使用————小程序
  15. 股权激励与期权激励的区别是什么?
  16. c语言中puts的作用是,C语言的字符串输出puts()函数
  17. 安卓源码避坑指南10—蓝牙音乐播放状态和歌曲信息不更新
  18. MySQL数据库实操教程(25)——权限管理
  19. MPB:猪胃肠道内容物和黏膜样品采集与微生物组成分析
  20. 游戏后台之内存管理篇

热门文章

  1. 计算机硬盘read,电脑硬盘一直吱吱的响的解决办法
  2. Docker+Ovs构建SDN网络
  3. Vue项目搭建常用配置文件!
  4. JavaPoet的使用指南
  5. 2013年十大免费云空间排行榜-给开发者建站用的免费云主机
  6. 区块链技术十周年—回眸与前瞻
  7. 鸽巢原理 Ramsey数
  8. Goose Goose Duck
  9. 教你小小JAVA爬虫爬到HDU首页(只为学习)
  10. python怎么修改字体_python怎么改字体 | 基础教程