现在的位置: 首页 > 综合 > 正文

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

2013年08月13日 ⁄ 综合 ⁄ 共 4459字 ⁄ 字号 评论关闭


<!--
/* 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

中,一般占据从
nand

block0
开始的

一些区域。否则必放置到处理器支持的加载点如
norflash
等。
Boot
代码负责操作系统的加载和升级,由于
boot
才能从一些基本的数据源如串口、
usb
获取升级数据,作为处理器上电即加载和运行的这一区域一旦损坏则系统升级只能凭借处理器内建原生的引导能力,这个过程大都需要专用工具或软件才能完成。该部分的好坏直接涉及是否返厂维修,所以对该区域的改动操作必须十分谨慎;内核区即
linux
内核保存位置,其和引导区在最终系统中对一般用户都设计为不能进行升级以维护基本系统的安全性。
Ramdisk

recovery
区间同标准
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
程序。升级
/
更新可以直接覆盖目标文件,也可采用二进制补丁形式以减少升级文件的容量,采用的工具为
bsdiff

imgdiff
。对于补丁包升级形式,升级数据源可靠性鉴别的依据为
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;}
-->

理论上
recovery

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

固件的复位可以通过引导程序传递给
recovery
参数或
android
系统中用户选择
Settings->SD card& phone storage->Factory
data reset

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

抱歉!评论已关闭.