Android ota升级

一、升级包制作流程
1.1、编译一个完整刷机包

1.2、制作OTA包

在android目录下执行 make otapackage –j8 编译OTA包。以450平台为例,编译后会在

out\target\product\**\ 目录下生成一个升级整包 msm8953_64-ota-*.zip

out\target\product\**\obj\PACKAGING\target_files_intermediates目录下生成一个基础包

整包:是可以直接用于OTA升级使用,相当于整个替换机器image。优点是操作简单,不容易出问题。缺点是内存很大。

基础包:是用于制作差分包。里面包含所有支持升级的image文件。将新旧两个基础包,使用系统自带脚本进行对比差分操作后,就会按照新旧的差异点生成一个差分包。

差分包:是只有包含差点点信息和差异patch的。所以使用差分包升级,一定要保证机器里面当前的image和制作差分的基础包里面的image完全一致。否则肯定升级失败。

二、Recovery 升级模式
Recovery升级是原生默认的升级方式,后面某些高端平台可能会默认废弃这种方式。升级基于recovery分区进行,对image进行升级操作。这种升级方式,优点是节省ROM,缺点是如果发生意外导致系统image损坏,机器就可能变砖了。

debug模式下调试OTA方法
执行如下 adb 指令进行升级操作

adb root
 
adb remount
 
adb push update.zip /data/update.zip
 
adb shell
 
uncrypt /data/update.zip /cache/recovery/block.map
 
echo "--update_package=@/cache/recovery/block.map" > /cache/recovery/command
 
adb reboot recovery
注:7.0之前系统没有uncrypt,将升级包push到/cache/update.zip,再执行如下指令

adb root
 
adb remount
 
adb push update.zip / cache /update.zip
 
adb shell
 
echo " --update_package=/cache/update.zip " > /cache/recovery/command
 
adb reboot recovery
user版本需要可以使用系统API接口
方法一:使用系统自带API相关接口文件叫 android.os.RecoverySystem,调用其 installPackage 等方法即可。注意权限需要是系统APP才可以。

方法二:adb reboot recovery 进入到 recovery 界面,有如下两项

Apply update from ADB

Apply update from SD Card

这两种都可以升级,选择后根据界面提示操作即可。

备注:可能有些平台没有这个界面功能。

三、A/B分区模式升级
AB升级模式应该是后续主要升级模式。原理就是在ROM中分了两个区域,各自有一套image。优点是更安全,即使是一套分区出问题了,仍然有一套可以使用,机器不会变砖。缺点就是多一套分区导致ROM占用更多。

debug模式下调试
adb root
 
adb remount
 
adb push update.zip data/ota_package/update.zip
 
adb shell
 
update_engine_client --update --follow --payload=file:///data/ota_package/update.zip --offset=7919 --size=724346 --headers="FILE_HASH=1RilNlJjIRfwwd8t86YucEhJV67msLzETHprS+HcWyg=
FILE_SIZE=724346
METADATA_HASH=vQsISDOuPUCkczn6FizKVHV8mkF8YqNYnNi21l6Du9o=
METADATA_SIZE=440778
"
update_engine_client后面的参数根据OTA包生成。表示OTA包的参数。新建ota.py,将下面代码复制过去,再执行python脚本 python ota.py update.zip 即会生成。

#!/usr/bin/env python
 
import sys
import zipfile
 
def main():
         if len(sys.argv) != 2:
                   sys.stderr.write('Use: %s <ota_file.zip>\n' % sys.arv[0])
                   return 1
 
         otazip = zipfile.ZipFile(sys.argv[1], 'r')
         payload_info = otazip.getinfo('payload.bin')
         payload_offset = payload_info.header_offset + len(payload_info.FileHeader())
         payload_size = payload_info.file_size
         payload_location = '/data/ota_package/update.zip'
         headers = otazip.read('payload_properties.txt')
         print (
         'update_engine_client --update --follow --payload=file://{payload_location}'
         ' --offset={payload_offset} --size={payload_size}'
         ' --headers="{headers}"').format(**locals())
         return 0
 
if __name__ == '__main__':
         sys.exit(main())
执行update_engine_client指令后,等待升级完成,窗口有如下相关提示,表示升级成功。

[INFO:update_engine_client_android.cc(90)] onStatusUpdate(UPDATE_STATUS_UPDATED_NEED_REBOOT (6), 0)
 
[INFO:update_engine_client_android.cc(98)] onPayloadApplicationComplete(ErrorCode::kSuccess (0))
user版本调试
需要使用系统相关接口,android.os.UpdateEngine android.os.UpdateEngineCallback。

UpdateEngine.applyPayload  升级接口

UpdateEngineCallback是升级监听,如下:

    class MyUpdateEngineCallback extends UpdateEngineCallback {
        @Override
        public void onStatusUpdate(int status, float percent) {
            Log.i(TAG, "percent:" + percent);
            if (percent > 0)
                mInfoTextView.setText("升级进度:" + percent);
        }
 
        @Override
        public void onPayloadApplicationComplete(int errorCode) {
            Log.i(TAG, "errorCode:" + errorCode);
            if (errorCode == 0) {
                handler.sendEmptyMessage(UPDATE_SUCCESS);
            } else {
                Message msg = new Message();
                msg.what = UPDATE_ERROR;
                Bundle bundle = new Bundle();
                bundle.putInt("errorCode", errorCode);
                msg.setData(bundle);
                handler.sendMessage(msg);
            }
            if (mUpdateEngine != null) {
                mUpdateEngine.unbind();
            }
        }
    }
常见调试问题
a、如何确认AB升级当前分区
通过查看 ro.boot.slot_suffix 属性值的方式,这个属性值显示当前使用分区名

b、如何手动切换分区
通过进入bootloader 模式,指定启动槽值来选择下次启动的分区,按照如下指令即可

adb reboot bootloader

fastboot --set-active=a

fastboot reboot

c、如何判断失败原因
升级结束时,可以看到有个错误码,常见错误码如下,按照错误码去查找可能原因

ErrorCode::kSuccess (0) 升级成功

ErrorCode::kSuccess (1) 升级失败

ErrorCode::kFilesystemCopierError (4) 未知,暂时未使用的错误码

ErrorCode::kPostinstallRunnerError (5) 升级安装结束,设置启动分区失败

ErrorCode::kPayloadMismatchedType (6) 升级包的升级类型不匹配或升级包minor version不兼容

ErrorCode::kInstallDeviceOpenError (7) 无法启动升级。可能是原因:分区错误,设备支持升级的分区和升级包内的不匹配;设备处于disable-verity状态;

ErrorCode::kKernelDeviceOpenError (8) 未知,暂时未使用的错误码

ErrorCode::kDownloadTransferError (9) w,找不到升级包

ErrorCode::kPayloadHashMismatchError (10) FILE_HASH值不匹配

ErrorCode::kPayloadSizeMismatchError (11) 数据size不匹配

ErrorCode::kDownloadPayloadVerificationError (12) 签名验证失败

ErrorCode::kDownloadStateInitializationError (20) 升级包写入时失败  一般都是发生在差分包升级时,检测boot、system、vendor的hash值不匹配。

ErrorCode::kDownloadInvalidMetadataMagicString (21)  未找到正确bin文件,一般是offset不对导致

ErrorCode::kDownloadInvalidMetadataSize (32) METADATA_SIZE值不匹配

ErrorCode::kPayloadTimestampError (51) 升级包的date比机器当前版本早

system/update_engine/update_engine_client_android.cc

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值