Android OTA 升级介绍

针对Android系统OTA升级,MTK平台有相关介绍文档:https://online.mediatek.com/apps/faq/detail?faqid=FAQ27117&list=SW

概念一:OTA包的构建

  •  AOSP full build:Android原生提供的全量包的构建,意思就是可以从任何一个比它老的版本通过OTA升级到此版本,因为是全量,所以通常这类包的大小和平时的镜像文件差不多大
  • MTK split build:MTK提供的增量包的构建,即针对两个固定版本之间的差异制作而成的,因此它只能在固定两个版本之间进行OTA升级,因为是差分增量,所以通常这类包的大小和两个版本的差异相关,可以小到几M,在不发达的国家因为网络条件比较差,通常采用此方式进行推送

概念二:AB系统

  • AB系统:AB系统并不是一个系统,Google官方把其描述为A/B无缝系统更新,MTK喜欢把带有此功能的软件配置称为AB系统,即当前软件支持AB系统更新。开启此功能的系统可以实现A/B无缝更新功能,即在不重启或者进入recovery模式下进行OTA更新,即你可以一边正常使用手机,后台守护进程update_engine来进行更新,所以叫做无缝更新。其原理是底层使用了两套分区,详细概念可以参考:A/B(无缝)系统更新  |  Android Open Source Project
  • No-AB系统:MTK吧不支持A/B无缝系统更新的软件版本称为No-AB系统,从Google角度,A/B无缝功能在Android 7就开始有了,但是直到Android 13要求强制支持使能,即现在的系统都是强制开启了此功能。开启此功能的系统,ro.build.ab_update属性被设置为true

概念三:OTA升级的方式

  • Recovery Mode:进入Recovery模式进行升级,此种方式在AB系统和No-AB系统上都可以使用,此方式需要进入recovery模式,因此升级过程中,用户肯定是无法使用的。

Recovery UI可以提供SD卡方式和adb sideload d:\update.zip方式进行升级

三方应用可以通过调用android.os.RecoverySystem$installPackage接口实现

  • Update Engine:它是Google为了实现A/B无缝更新新造了一个守护进程,因此只有在AB系统上才能使用此方式,此方式不需要进入recovery或者重启,升级过程中你可以继续使用手机,update_engine升级完毕之后会设置标记位,在下一次重启之后就会进入对应的分区槽启动系统

三方应用可以通过调用android.osUpdateEngine$applyPayload接口实现

注意一:AB系统通过Recovery方式升级,升级包放在/data目录无法被挂载

注意二:AB系统不建议使用Recovery方式进行升级,参考MTK案例

1、Recovery OTA流程

Android OTA 升级 之 Recovery-CSDN博客

2、UpdateEngine OTA流程

Android OTA 升级 之 UpdateEngine-CSDN博客

3、AB系统 VS 传统系统

在阅读UpdateEngine流程之前一定要先了解AB系统和传统系统到底有哪些差异,如果这个不了解,可能有些懵逼。

参考网上大佬:https://blog.csdn.net/guyongqiangx/article/details/71334889

3.1 分区槽的引入

3.1.1 分区槽的概念

A/B系统就是设备上有AB两套可以工作的系统(用户数据只有一份,为两套系统共用),简单来讲,可以理解为一套系统分区,另外一套为备份分区。其系统版本可能一样;也可能不一样,其中一个是新版本,另外一个旧版本,通过升级,将旧版本也更新为新版本。当然,设备出厂时这两套系统肯定是一样的。

PS:我们对这两套系统的感知通常表现为分区,即烧录镜像的时候会存在两份类似命名的img,例如system_a.img和system_b.img,有可能烧录镜像的时候并不会向ROM中写入两份img,但肯定会在分区中预留其空间。

分区名传统系统AB系统
bootloader存放用于引导linux的bootloader存放用于引导linux的bootloader
recovery存放Recovery系统的linux kernel文件和ramdisk并不是简单的被删掉了
boot存放Android主系统的linux kernel文件和用于挂载system和其他分区的ramdisk 
boot_a/b 分别用于存放两套系统各自的linux kernel文件和用于挂载system和其他分区的ramdisk
systemAndroid主系统分区,包括Android的系统应用程序和库文件 
system_a/b Android主系统分区,分别用于存放两套系统各自的系统应用程序和库文件
userdata用户数据分区,存放用户数据,包括用户安装的应用程序和使用时生成的数据用户数据分区,存放用户数据,包括用户安装的应用程序和使用时生成的数据
cache临时存放数据的分区,通常用于存放OTA的升级包被删掉了,这就是为什么AB系统不支持吧ota包存放在此目录
misc存放Android主系统和Recovery系统跟bootloader通信的数据存放Android主系统和Recovery系统跟bootloader通信的数据,由于存放方式和分区名字没有强制要求,所以部分实现上保留了misc分区

PS:AB分区对应两套分区,我们把他称为分区槽,每个槽都对应一套boot和super。启动过程中,bootloader会根据条件来决定启动哪一个槽之后,例如这次启动选择slot A,bootloader加载启动boot_a里面的kernel,然后加载启动system_a中的init进程,然后init进程启动update_engine相关联的进程

3.1.2 分区编译的差异

传统系统和AB系统,针对各个分区的编译也发生了比较大的整改,针对这块我也没有主要去研究它,从大佬的文章可以做出如下总结:

  • AB系统相关宏控必现按照如下方式定义
# A/B系统必须定义的变量
AB_OTA_UPDATER := true
AB_OTA_PARTITIONS := boot system vendor
BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
TARGET_NO_RECOVERY := true
BOARD_USES_RECOVERY_AS_BOOT := true
PRODUCT_PACKAGES += update_engine update_verifier
# A/B系统可选定义的变量
PRODUCT_PACKAGES_DEBUG += update_engine_client
# A/B系统不能定义的变量
# BOARD_RECOVERYIMAGE_PARTITION_SIZE
# BOARD_CACHEIMAGE_PARTITION_SIZE
# BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
  • AB系统的recovery.img文件编译不再单独生成,传统方式的recovery.img现在叫做boot.img

  • AB系统的boot.img文件,编译的时候包含kernel和recovery模式的ramdisk

  • AB系统的system.img文件,传统方式下system.img由$(PRODUCT_OUT)/system文件夹打包而成,A/B系统下,制作时将$(PRODUCT_OUT)/root和$(PRODUCT_OUT)/system合并到一起,生成一个完整的带有rootfs的system.img

  • AB系统的userdata.img文件,跟原来一样,打包$(PRODUCT_OUT)/data文件夹而成

  • AB系统的cache.img文件不再单独生成cache.img,因此AB系统不再支持把压缩包通过放到/data或者/cache目录传递给recovery小系统进行升级,因为recovery小系统无法成功挂载。虽然没有cache分区,但是不代表根目录没有cache文件夹,因为odm厂商可能还是会在主系统文件系统创建这个目录

  • vendor.img,文件的生成跟是否A/B系统无关,主要有厂家决定

3.1.3 分区表的差异

3.2 升级原理

3.2.1 传统系统

  • 传统系统有一个Android主系统和一个Recovery小系统。他们是同等级的平行世界,即他们分别对应于拥有自己的一套文件系统,init进程等,区别就是Android主系统更强大拥有了android虚拟机和整个framework以上的世界,而Recovery系统只拥有很小的一部分进程,他只能做恢复出厂设置、升级等一些工作,因此又把它叫做小系统。
  • Android主系统运行时检测到需要升级,就讲升级的数据包下载并存放到cache分区,并通过向misc分区写入一些命令来通知bootloader下次启动进入recovery小系统(即传统系统通过misc来向bootloader或者recovery小系统来进行通信),做好这些事情后就主动重启系统。
  • 重启系统过程中,bootloader通过misc分区的命令来决定是启动Android主系统还是启动Recovery小系统。PS:Android主系统有自己一套kernel,kernel启动init,init启动zygote,zygote启动安卓世界,recovery小系统有自己一套min-kernel,min-kernel启动init,init启动recovery进程
  • Recovery小系统被启动后,可以通过misc分区的命令来决定接下来干那些事情,例如升级分区、恢复出厂设置、进入Android主系统。如果更新分区失败,设备重启就不能正常使用,唯一的办法就是重新升级,直到成功为止

3.2.2 AB系统

  • AB系统有两套分区slot A和slot B。按照系统启动的时候,bootloader从其中一套分区启动,另外一套分区被留着备份,通过几个标记来管理他们的状态。
  • Android主系统运行的时候,通过update_engine后台服务进程来接收应用端的升级指令接口。当update_engine对升级数据包下载校验都准备好之后,就会通过boot_control HAL层服务来和bootloader设置标记状态。做好这些事情后就主动重启系统。
  • 重启系统过程中,bootloader通过前一步标记的一些状态来决定激活进入哪一个分区槽,即slot A还是slot B。如果需要升级的槽进入激活失败者会回到之前的槽(根据经验可以判断此现象会导致黑屏一次),无论成功还是失败都会设置相应的状态,详情参考后文。
  • bootloader无论上一步激活了哪一个槽,如果能进一步启动对应槽的kernel,然后通过init启动update_verifier进程来标记设置分区槽的状态
  • 下一步还会通过init启动的update_engine进程来判断当前槽和升级信息来决定此次升级是否成功。

3.3 AB系统分区槽如何切换?

这里借鉴一下大佬的文章:https://blog.csdn.net/guyongqiangx/article/details/140759462

3.3.1 分区槽的标记

对于A/B系统的slot Aslot B分区,其都存在以下三个属性:

  • active:系统的活动分区标识,这是一个排他属性,系统只能有一个分区设置为active属性,启动时bootloader选取设置为active的分区进行启动。
  • bootable:分区可启动标识,设置为bootable的分区表明该分区包含了一个完整的可以启动的系统。
  • successful:分区成功运行标识,设置为successful的分区表明该分区在上一次启动或当前启动中可以正确运行。

3.3.2 分区槽的状态切换

典型的应用场景有以下4个(假定当前从B分区启动):

说明1:当前运行的系统(current)用绿色方框表示,当前没有用的系统(unused)用灰色方框表示
说明2:属性标识为红色,表示该状态下相应属性被设置,标识为灰色标识该状态下属性没有设置或设置为相反属性,如:

  • active表示已经设置active属性当前为活动分区;active 表示没有设置active属性
  • bootable表示已经设置bootable属性;bootable表示设置为没有设置bootable属性
  • successful表示已经设置successful属性,successful表示没有设置successful属性

状态1:普通场景

最常见的情形,例如设备出厂时,A分区和B分区都可以成功启动并正确运行,所以两个分区都设置为bootable和successful,但由于是从B分区启动,所以只有B分区设置为active。

状态2:升级中

B分区检测到升级数据,在A分区进行升级,此时将A分区标识为unbootable,另外清除successful标识;B分区仍然为active,bootable和successful。

状态3:更新完成等待重启

B分区将A分区成功更新后,将A分区标识为bootable。另外,由于重启后需要从A分区启动,所以也需要将A分区设置为active,但是由于还没有验证过A分区是否能成功运行,所以不设置successful;B分区的状态变为bootable和successful,但没有active。

状态4:从新系统成功启

设备重启后,bootloader检测到A分区为active,所以加载A分区系统。进入A系统后如果能正确运行,需要将A分区标识为successful。对比第1个普通场景,A和B系统都设置为bootable和successful,但active从B分区切换到A分区。至此,B分区成功更新并切换到A分区,设备重新进入普通场景。

3.4 bootloader交互的方式

3.4.1 传统系统

请参考链接:https://blog.csdn.net/qq_27672101/article/details/144148071

3.4.2 AB系统

请参考链接:https://blog.csdn.net/qq_27672101/article/details/144148002

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诸神黄昏EX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值