android 固件升级/复位实现方法分析

来源:互联网 发布:java中属性和字段区别 编辑:程序博客网 时间:2024/06/04 01:35

<!-- /* Font Definitions */ @font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-alt:SimSun;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 135135232 16 0 262145 0;}@font-face{font-family:"/@宋体";panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;mso-pagination:none;font-size:10.5pt;mso-bidi-font-size:12.0pt;font-family:"Times New Roman";mso-fareast-font-family:宋体;mso-font-kerning:1.0pt;} /* Page Definitions */ @page{mso-page-border-surround-header:no;mso-page-border-surround-footer:no;}@page Section1{size:612.0pt 792.0pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;mso-header-margin:36.0pt;mso-footer-margin:36.0pt;mso-paper-source:0;}div.Section1{page:Section1;}-->

文本框:  多功能的智能化嵌入式设备大量增长的应用对嵌入式设备的系统设计提出了更多挑战,传统的一次成型已经无法适应快速变化的市场,设备供应商在产品设计阶段就必须考虑软件每一部分如何升级。在系统开发阶段,系统设计人员会频繁替换软件进行测试、验证和调试,如固件开发人员对引导区的调试,系统工程师进行系统调试等。产品设计过程中快速方便的升级更新方法是加快开发进度的必要手段;而对于发布到用户手中的最终产品也会存有潜在的可通过软件升级解决的缺陷或系统可完善的部分,供应商需要提供升级包给客户进行自行升级修正以解决成本/性能问题。一般而言,升级设计必须遵循的原则为:1 尽量消除或最大程度减少升级过程对辅助工具特别是专用工具的依赖。如需要特别编程器、需要物理焊接拆除某些部件等。2 符合使用人群的操作习惯和知识体系。针对专业人士则可以开放更多底层接口,而对于普通消费者则要求做到操作简单直接。3 具备防止误操作和自我修复功能。系统不应该由于一次升级误操作而导致需要返厂修理。嵌入式操作系统Android的固件升级方法可以作为类似升级的一个例子。

系统恢复模式启动

 

正常启动

 
基于android系统的设备一般将存储区间逻辑上分为:引导区、内核区、ramdisk区间、recovery区、系统区、cache区间和数据区。其中reocvery区间为系统修复时候使用,其他区间功能如下:引导区为处理器上电固定的加载点,其存储位置依据处理器不同而变化,对于支持从nand加载引导固件的处理器,可以将引导区域直接放置到

图一

                                  nandflash中,一般占据从nandblock0开始的

一些区域。否则必放置到处理器支持的加载点如norflash等。Boot代码负责操作系统的加载和升级,由于boot才能从一些基本的数据源如串口、usb获取升级数据,作为处理器上电即加载和运行的这一区域一旦损坏则系统升级只能凭借处理器内建原生的引导能力,这个过程大都需要专用工具或软件才能完成。该部分的好坏直接涉及是否返厂维修,所以对该区域的改动操作必须十分谨慎;内核区即linux内核保存位置,其和引导区在最终系统中对一般用户都设计为不能进行升级以维护基本系统的安全性。Ramdiskrecovery区间同标准linux中的initrd,引导程序根据启动参数决定加载正常的ramdisk还是recovery作为initrd传递给内核,其中recovery区间为修复系统使用,由于其为修复/升级系统的核心组件,一般也都设计为对用户不可改变。系统区为正常的android应用保存位置,一般设计为对普通用户属只读系统以保护主要系统的安全性,数据区为用户设置信息、优化后的DEX和系统数据库保存位置,清空该区域会清除用户的所有数据以及优化过的DEX文件,导致下一次启动过程很长(需要重新创建data目录中的缺省信息)。Cache区间为升级过程使用的临时存储区。Android系统正常启动和recovery方式启动过程各区间操作使用情况如图一。图中箭头所指区域为操作区域,箭头的源为发起者。android的系统复位过程实际就是清除data/cache区域。

Android升级分为两种,一种是对系统中单个文件升级,一种是对mtd整个分区进行升级,升级包是用zip格式压缩的经过签名的压缩文件。升级过程主要流程描述如下:

1 boot发现用户按住升级按键,将recovery.img作为ramdisk读取到内存。

2 内核根据ramdisk中的init.rc执行recovery脚本。Recovery脚本在sdcard中找到升级文件后调用recovery程序依次做以下操作:

A 检查升级文件的数字签名是否可靠。检查签名使用的本地密钥为/res/keys

B 如果签名合法则执行提取压缩包中META-INF/com/google/android/update-binary文件重命名到/tmp/update_binary并执行该文件。

C update_binary解析压缩文件中的META-INF/com/google/android/updater-script文件并执行。其升级进度通过管道回传给recovery程序。升级/更新可以直接覆盖目标文件,也可采用二进制补丁形式以减少升级文件的容量,采用的工具为bsdiffimgdiff。对于补丁包升级形式,升级数据源可靠性鉴别的依据为sha1校验和数据长度比对。具体要求为:1 级包提供的目标文件的sha1值和目标文件计算值符合,即目标正确。 2 进行补丁后的文件sha1值和长度符合升级包提供的补丁后的目标文件的长度和sha1数值,保证结果正确。两项有一项不符合则升级过程停止。为保证第二项操作不损毁最终目标,打补丁的文件会先临时存储到cache中,等到结果比对正确才进行实际写入/替换目标文件操作。所以此过程要求cache目录必须有足够空间能够保存临时文件。

<!-- /* Font Definitions */ @font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-alt:SimSun;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 135135232 16 0 262145 0;}@font-face{font-family:"/@宋体";panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;mso-pagination:none;font-size:10.5pt;mso-bidi-font-size:12.0pt;font-family:"Times New Roman";mso-fareast-font-family:宋体;mso-font-kerning:1.0pt;} /* Page Definitions */ @page{mso-page-border-surround-header:no;mso-page-border-surround-footer:no;}@page Section1{size:612.0pt 792.0pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;mso-header-margin:36.0pt;mso-footer-margin:36.0pt;mso-paper-source:0;}div.Section1{page:Section1;}-->

理论上recoveryramdisk可以并入ramdisk,由系统传递不同参数给recovery来决定其行为。Android的启动脚本中已经加入对recovery的调用,但是该脚本具体执行的动作留给不同厂家自行补充。这一过程的好处是减少recovery区间,缺点是如果希望更新ramdisk本身,一旦更新失败(如突然断电),则系统的恢复只能依靠引导系统有限的能力,而这个操作一般都需要专业操作/工具才能进行。由于recovery包本身尺寸并不大,单独隔离出一个区间作为recovery,间接的对ramdisk的双备份,所以单独划分一个区间是值得的。

固件的复位可以通过引导程序传递给recovery参数或android系统中用户选择Settings->SD card& phone storage->Factorydata reset两个地方发起。对于开放给用户的后者,该选项仅仅创建文件/cache/recovery/command,里面包含命令参数—wipe_data,当重新启动系统时候,recovery程序缺省会解析该文件内容并执行对应的擦除数据区间的操作。如果厂家希望开发更多更强大的功能给用户,比如可以添加升级菜单,然后修改recovery程序可以让系统重新启动时候不需按键直接进入升级界面。