一、背景
Android7.0之前的OTA升级方式,这里称之为传统的OTA方式。
设备上有一个Android主系统和一个Recovery系统,Android主系统运行时检测是否需要升级,如果需要升级,则将升级的数据包下载并存放到cache分区,重启系统后进入Recovery系统,并用cache分区下载好的数据更新Android主系统,更新完成后重新启动进入Android主系统。如果更新失败,设备重启后就不能正常使用了,唯一的办法就是重新升级,直到成功为止。
Android7.0引入了新的OTA升级方式,A/B System Update,这里称之为A/B系统。
A/B系统就是设备上有A和B两套可以工作的系统(用户数据只有一份,为两套系统公用),可以简单理解为一套系统分区,一套备份分区。其系统版本可能是一样的;也可能是不一样的,一个新版本,另一个是旧版本,通过升级,将旧版本更新为新版本。当然,设备出厂时这两套系统肯定是一样的。
但这种方式依然会要求手机有足够的存储空间或临时空间用于下载升级文件,所以Google在Android8.0新增了名为“streaming”的方式,类似于流媒体的边下边播放,OTA会在进行下载新升级文件的同时进行写入到B系统分区,这样不需要额外的存储空间暂存文件,只需约100KB用于放置原数据就可以进行系统升级。由于双分区的存在,用户不必担心系统会因此崩溃,同时在升级过程正常使用手机。
虽然Google这个A/B无缝+串流升级看起来很高级,但Google并没有在Android8.0默认启用这种方式,仅推荐一些新的设备可以选择采用,但与Android7.0上需要OEM厂商特别要求芯片支持不同,高通和MTK接下来的芯片都将对Android8.0这个特性提供支持。
二、A/B系统的特点
A/B系统实现了无缝升级,有以下特点:
- 出厂时设备上有两套可以正常工作的系统,升级时确保设备上始终有一个可以工作的系统,减少设备变砖的可能性。
- OTA升级在Android系统的后台进行,所以更新过程中,用户可以正常使用设备,数据更新完成后,仅需要用户重新启动一次设备进入新系统。
- 如果OTA升级失败,设备可以回退到升级前的旧系统,并且可以尝试再次更新升级。
Android7.0上传统OTA方式和新的A/B系统方式都存在,只是编译时只能选择其中的一种OTA方式。由于A/B系统在分区上与传统OTA的分区设计不一样,二者无法兼容,所以7.0以前的系统无法通过OTA方式升级为A/B系统。
A/B系统主要由运行在Android后台的update_engine和两套分区“slot A”和“slot B”组成。Android系统从其中一套分区启动,在后台运行update_engine检测升级信息并下载升级数据,然后将数据更新到另外一套分区,写入数据完成后从更新的分区期启动。
与传统OTA方式相比,A/B系统的变化主要有:
1、系统的分区设置
1. 传统方式只有一套分区
2. A/B系统有两套分区,slot A 和 slot B
2、和bootloader沟通的方式
1. 传统方式bootloader通过读取misc分区信息来决定是进入Android主系统还是Recovery系统
2. A/B系统的bootloader通过特定的分区信息来决定从slot A还是slot B启动
3、系统的编译过程
1. 传统方式在编译时会生成boot.img和recovery.img分部用于Android主系统和Recovery系统的ramdisk
2. A/B系统只有boot.img,不再生成单独的recovery.img
4、OTA更新包的生成方式
A/B系统生成OTA包的工具和命令跟传统方式一样,但是生成内容的格式不一样了。
三、A/B系统分区
1、A/B
系统的分区
bootloader
存放用于引导linux的bootloaderboot_a
和boot_b
分别用于存放两套系统各自的linux kernel文件和用于挂载system和其他分区的ramdisksystem_a
和system_b
Android主系统分区,分别用于存放两套系统各自的系统应用程序和库文件vendor_a
和vendor_b
Android主系统分区, 分别用于存放两套系统各自的开发厂商定制的一些应用和库文件,很多时候开发厂商也直接将这个分区的内容直接放入system分区userdata
用户数据分区,存放用户数据,包括用户安装的应用程序和使用时生成的数据misc
或其他名字分区
存放Android主系统和Recovery系统跟bootloader通信的数据,由于存放方式和分区名字没有强制要求,所以部分实现上保留了misc
分区(代码中可见Brillo
和Intel
的平台),另外部分实现采用其他分区存放数据(Broadcom
机顶盒平台采用名为eio
的分区)。
2、一张图比较传统分区和A/B
系统分区
主要区别在于A/B
系统:
-
boot
,system
和vendor
系统分区从传统的一套变为两套,叫做slot A
和slot B
; - 不再需要
cache
和recovery
分区 -
misc
分区不是必须
四、A/B系统的状态
1、系统分区属性
对于A/B
系统的slot A
和slot B
分区,其都存在以下三个属性:
active
系统的活动分区标识,这是一个排他属性,系统只能有一个分区设置为active
属性,启动时bootloader
选取设置为active
的分区进行启动。bootable
分区可启动标识,设置为bootable
的分区表明该分区包含了一个完整的可以启动的系统。successful
分区成功运行标识,设置为successful
的分区表明该分区在上一次启动或当前启动中可以正确运行。
2、系统的典型场景
典型的应用场景有以下4个(假定当前从B分区启动):
每个场景详细说明如下:
- 普通场景(
Normal cases
)
最常见的情形,例如设备出厂时,A分区和B分区都可以成功启动并正确运行,所以两个分区都设置为bootable
和successful
,但由于是从B分区启动,所以只有B分区设置为active
。 - 升级中(
Update in progress
)
B分区检测到升级数据,在A分区进行升级,此时将A分区标识为unbootable
,另外清除successful
标识;B分区仍然为active
,bootable
和successful
。 - 更新完成,等待重启(
Update applied, reboot pending
)
B分区将A分区成功更新后,将A分区标识为bootable
。另外,由于重启后需要从A分区启动,所以也需要将A分区设置为active
,但是由于还没有验证过A分区是否能成功运行,所以不设置successful
;B分区的状态变为bootable
和successful
,但没有active
。 - 从新系统成功启动(
System rebooted into new update
)
设备重启后,bootloader
检测到A分区为active
,所以加载A分区系统。进入A系统后如果能正确运行,需要将A分区标识为successful
。对比第1个普通场景,A和B系统都设置为bootable
和successful
,但active
从B分区切换到A分区。至此,B分区成功更新并切换到A分区,设备重新进入普通场景。