OTA是Over-the-Air的简称,既空中下载的意思,具体指远程无线方式,OTA 技术可以理解为一种远程无线升级技术。
A/B系统升级,顾名思义是有两套系统,一套系统分区,另一套备份分区。这两套系统出厂时一样,此后可能不一样。一个新版本,另一个旧版本,旧版本升级至新版本,不断更新切换。A/B系统更新又称之为无缝更新(Seamless updates),具有以下几个特点:
1. OTA更新在系统后台运行,该过程中用户仍可以正常使用设备。待更新完成后,需重启一次方可进入新系统。
2. OTA更新失败后(OTA更新无法应用或应用后无法启动),设备可重启回滚到旧分区继续使用,并重新尝试更新升级。
3. 可采用流式升级方式,即无需/data或/cache分区留出足够空间用于存储下载的升级包,也可进行OTA升级。
4. 确保在OTA更新期间磁盘上保留一套可以正常启动使用的系统,减少刷机变砖的可能性,减轻售后服务工作量。
普通系统只需要一个boot存储空间和一个system存储空间,但是A/B分区系统需要开辟两个boot存储空间和两个system存储空间。 这是为了保证升级分区不对运行分区产生影响,保证系统OTA不宕机的一个保障。在原有分区名字后面添加_a 和 _b, 在刷机,或者系统启动的时候, 根据bootloader的参数添加后缀,选择正确的系统。misc分区在A/B系统中变成一个可有可无的存在, 因为其功能只是传递恢复出厂设置的参数, 而recovery的功能也只剩下恢复出厂设置, 所以, 本质上没必要再基misc传递参数了。
bootloader为了判断一个系统(slot)是否为可以启动的状态, 需要为其定义对应的属性(状态). 其状态说明如下:
slot a 和 slot b, 只有一个是active, 它们可以同时有 bootable 和 successful 属性.
1. bootloader检测到1个或者2个slot都是bootable的状态。
2. 选择active的slot或者选择successful的slot进行尝试启动。
3. 启动成功的标记是, dm-verity 成功。
4. 由于启动成功, 则该slot被标记为successful和active。
5. 由于启动失败, 则设置该slot为unbootable, 并设置另一个slot为active, 进行下一次尝试。
1.普通场景(Normal case):
系统从当前slot启动(A或B),当前系统所处slot状态为bootable,successful, active。
2.升级中(Update in progress):
slot A检测到升级,在slot B中升级。将slot B标记为unbootable,清除successful标志;slot A仍为bootable, successful和active。
3.升级完成,等待重启(Update applied, reboot pending):
slot A将B升级后,将B标记为bootable,重启前将B标记为active以便重启后从B启动,需重启验证B后才能将其设置为successful;A变为bootable, successful。
4.从新系统升级(System rebooted into new update):
重启后,bootloader将B标记为active,若A能正常启动运行,则将其标记为successful。重新回到普通场景。
% tar -ztvf otapackage-android-V01.00.02.20210201154115.zip
-rw-rw-r-- 0 0 0 569 1 1 2009 META-INF/com/android/metadata
-rw-rw-r-- 0 0 0 555 1 1 2009 care_map.pb
-rw-rw-r-- 0 0 0 660336513 1 1 2009 payload.bin
-rw-rw-r-- 0 0 0 154 1 1 2009 payload_properties.txt
-rw-rw-r-- 0 0 0 1484 1 1 2009 META-INF/com/android/otacert
%
升级流(包)的下载, 分为两个模式:下载zip包到data分区,再执行本地升级和下载升级流,边下边升级。
update_engine_client --payload=file:///data/ota_package/payload.bin --update --headers="
FILE_HASH=qV4pGlSA8RvQHdrcxis5HsJ8THTjF/+8uKONoDyC97Y=
FILE_SIZE=585826548
METADATA_HASH=qBscrjxetcVPTY4unCoI/EopPa66HVar7s3HWF14Eag=
METADATA_SIZE=49341"
update_engine_client --update --payload=file:///data/ota_package/otapackage-V01.00.01.zip --offset=1250 --size=585826916 --headers="
FILE_HASH=X+DdkxF2LBtOdvzYm3udb79FBMQoTTJvhIcWAid30Vs=
FILE_SIZE=585826916
METADATA_HASH=2THW35yZnxZCyb1Gc+8LchTeo3j69siLvnIbGw2fx4o=
METADATA_SIZE=49341"
logcat -s bcm-bootc:v update_engine:v
升级成功后会打印出如下日志:
10-12 16:48:01.749 594 594 I update_engine: [1012/164801.749640:INFO:update_attempter_android.cc(462)] Update successfully applied, waiting to reboot.