Android 虚拟 A/B 详解(十) 判断 Virtual A/B 是否打开的 5 种办法.md

本文为洛奇看世界(guyongqiangx)原创,转载请注明出处。

原文链接:https://blog.csdn.net/guyongqiangx/article/details/133917853

0. 导读

这是一篇临时加入的文章,计划中的第十篇并不是准备分析这个,只不过因为时常会有小伙伴在 OTA 讨论群和专栏答疑群里问如何判断一个设备是否打开了虚拟分区(Virtual A/B)功能。

在这里插入图片描述

图 1. 如何判断设备开启了虚拟 AB 的问题

本文总结我知道的 5 种办法:

  1. 从源码判断
  2. 从编译输出判断
  3. 从 image 镜像文件判断
  4. 从运行设备的系统属性判断
  5. 从运行设备的 super 分区数据判断

Android 虚拟 A/B 分区《Android 虚拟 A/B 分区》系列,更新中,文章列表:

对 linux 快照(snapshot) 的了解可以增加对虚拟 A/B 分区的理解:

如果您已经订阅了本专栏,请务必加我微信,拉你进“动态分区 & 虚拟分区专栏 VIP 答疑群”。

1. Virtual A/B 的开关

《Android 虚拟 A/B 详解(四) 编译开关》一文详细分析过 Virtual A/B 的编译开关,以及这些编译开关是如何起作用的。现在简单总结如下:

1.1 编译开关

对于原生设备:

PRODUCT_VIRTUAL_AB_OTA := true

对于升级改造设备:

PRODUCT_VIRTUAL_AB_OTA := true
PRODUCT_VIRTUAL_AB_OTA_RETROFIT := true

1.2 编译开关的定义位置

对于 Android 11®,上面这些开关位于以下文件中:

build/make/target/product/virtual_ab_ota.mk
build/make/target/product/virtual_ab_ota_retrofit.mk

对于 Android 12(S) 和 Android 13(T),以及 Android 14(U), 上面这些开关位于以下目录中:

build/make/target/product/virtual_ab_ota

1.3 编译开关的作用

基于上面的编译开关,在系统编译时,会设置只读属性:

ro.virtual_ab.enabled=true

同时在生成 super 分区镜像时,会往头部的 metadata 数据的 LpMetadataHeader 结构中写入标记 “LP_HEADER_FLAG_VIRTUAL_AB_DEVICE"

如果对这些开关的设置,编译的作用,以及最终用途的细节感兴趣,请转到《Android 虚拟 A/B 详解(四) 编译开关》查看详细分析。

2. Virtual A/B 开关检查

方法 1. 从源码判断

仔细观察上面 1.1 节以及 1.2 节中开关和位置,不论是哪一个都包含字符串 “VIRTUAL_AB_OTA” 或 “virtual_ab_ota” 的其中一个。而且巧了,这两个字符串刚好是大小写关系。

所以,我们可以使用 grep 工具搜索源码 device 目录下文件中的字符串 “virtual_ab_ota” 来确定是否打开了 Virtual A/B。

示例 1. Broadcom 平台

这里以 Broadcom 某产品的 Android 11® 代码为例,直接使用命令:

grep -rni virtual_ab_ota device/broadcom -C 5

搜索 device/broadcom 目录:

在这里插入图片描述

图 2. 在 Broadcom 平台上查找 virtual_ab_ota 示例

这里看到在文件 device/broadcom/common/headed.mk 第 70 的地方有包含 virtual_ab_ota.mk 文件,到这里有两个办法进行检查:

  1. 检查外层的两个开关 HW_AB_UPDATE_SUPPORTHW_VIRT_AB_UPDATE_SUPPORT 是否打开
  2. 在第 70 行的地方使用 info 或 warnning 指令打印消息或认为制造一个编译错误,看是否走到这里
示例 2. Google 平台

这里以 AOSP 的 android-13.0.0_r41 版本源码为例,使用 grep 搜索 device/google 目录:

android-13.0.0_r41$ grep -rni virtual_ab_ota device

以下是我直接搜索 device 目录的结果:

在这里插入图片描述

图 3. 在 Google 平台上查找 virtual_ab_ota 示例

然后再根据你具体的平台查看相应的 makefile 文件。

当然,你也可以搜索 device + build 目录,说不定有意外惊喜。

看到这里你可能有点失望,因为这里给出的只是线索,而不是线程的 ON/OFF 那种设置开关。不过没关系,沿着这个线索,查看外层开关或者编译一把就有答案了。

方法 2、从编译输出判断

由于在系统编译时,会设置只读属性:

ro.virtual_ab.enabled=true

所以,我们就查找编译输出的文本 txt 和属性文件 *.prop 中相关的内容即可。

例如,我基于 android-13.0.0_r41 的 AOSP 源码,编译了 panther 设备,因此使用 grep 搜索 out 目录下的 txt 和 prop 文件:

android-13.0.0_r41$ grep -rni virtual_ab out --include=*.{prop,txt}

结果如下:

在这里插入图片描述

**图 4. 在 out 目录下的 .txt 和 .prop 文件中查找 virtual_ab

这下答案直接明了,在 out/target/product/panther/misc_info.txt 文件中直接写了:

virtual_ab=true

方法 3、从 image 镜像文件判断

要解析虚拟分区镜像,这里会用到 lpdump 工具解析 super 分区镜像,具体用法请参考 《Android OTA 相关工具(五) 使用 lpdump 查看动态分区》

示例 1. 从 super.img 判断

在解析 super.img 前需要将 super.img 从 sparse 格式转换为 raw 格式。

# 查找 out 目录下的 super*.img 文件
android-13.0.0_r41$ find out -type f -iname "super*.img"
out/target/product/panther/super_empty.img
out/target/product/panther/obj/PACKAGING/super.img_intermediates/super.img
out/target/product/panther/obj/PACKAGING/target_files_intermediates/aosp_panther-target_files-eng.rocky/IMAGES/super_empty.img
out/dist/super.img
out/dist/super_empty.img
android-13.0.0_r41$ 

# 将 super.img 从 sparse 格式转换成 raw 格式
android-13.0.0_r41$ simg2img out/dist/super.img out/dist/super_raw.img
android-13.0.0_r41$ 

# 使用 lpdump 查看 raw 格式的 super 文件
android-13.0.0_r41$ lpdump out/dist/super_raw.img 
Slot 0:
Metadata version: 10.2
Metadata size: 1256 bytes
Metadata max size: 65536 bytes
Metadata slot count: 3
Header flags: virtual_ab_device
Partition table:
------------------------
  Name: system_a
  Group: google_dynamic_partitions_a
  Attributes: readonly
  Extents:
    0 .. 1734111 linear super 2048
------------------------
...

看到了吗,lpdump 的结果里面清清楚楚的写了: Header flags: virtual_ab_device,说明这是一个支持 Virtual A/B 的设备。

示例 2. 从 super_empty.img 判断

和解析 super.img 类似,不同的是 super_empty.img 默认就是 raw 格式,不需要转换:

android-13.0.0_r41$ lpdump out/dist/super_empty.img
Metadata version: 10.2
Metadata size: 1088 bytes
Metadata max size: 65536 bytes
Metadata slot count: 3
Header flags: virtual_ab_device
Partition table:
------------------------
  Name: system_a
  Group: google_dynamic_partitions_a
  Attributes: readonly
  Extents:
------------------------
...

解析 super.img 和 super_empty.img 的实质还是读取 super 分区开始的动态分区 header 数据。

如果 lpdump 的版本太老,不支持识别虚拟分区标识的话,这种方式会失败。

方法 4、从运行设备的系统属性判断

在运行的设备上检查是否支持虚拟分区的办法又有 3 种,这里检查系统属性 ro.virtual_ab.enabled 是最确定的一种。

在命令行检查系统的 virtual_ab 属性:

console:/ # getprop | grep -i virtual_ab
[ro.virtual_ab.enabled]: [true]

方法 5、从运行设备的 super 分区数据判断

示例 1. 使用 lpdump 查看 super 设备的 header 标识

和方法 3 检查编译好的 super.img 一样,都是读取动态分区的 metadata 进行判断。

console:/ # lpdump /dev/block/by-name/super
Slot 1:
Metadata version: 10.2
Metadata size: 716 bytes
Metadata max size: 65536 bytes
Metadata slot count: 3
Header flags: virtual_ab_device
Partition table:
------------------------
  Name: system_b
  Group: bcm_ref_b
  Attributes: readonly,updated
  Extents:
    0 .. 2466951 linear super 2048
------------------------

这种方法有两点要求:

  1. 设备上有 lpdump 工具
  2. lpdump 工具的版本不能太老
示例 2. 使用 lpdump 查看 super 设备的 cow 分区

对于升级过的设备,还可以使用 lpdump 查看 super 上是否有 cow 分区来判断是否支持 Virtual A/B。

对于 Virtual A/B 设备,升级时,会优先在 super 上开辟空间用于系统快照 cow。

所以对于升级过的设备,如果 super 上存在名字包含 cow 的分区(system_b-cow),例如:

console:/ # lpdump /dev/block/by-name/super                                
Slot 1:
Metadata version: 10.2
Metadata size: 716 bytes
Metadata max size: 65536 bytes
Metadata slot count: 3
Header flags: virtual_ab_device
Partition table:
------------------------
  Name: system_b
  Group: bcm_ref_b
  Attributes: readonly,updated
  Extents:
    0 .. 2466951 linear super 2048
------------------------
  Name: vendor_b
  Group: bcm_ref_b
  Attributes: readonly,updated
  Extents:
    0 .. 157239 linear super 2469888
------------------------
  Name: system_b-cow
  Group: cow
  Attributes: none
  Extents:
    0 .. 887 linear super 2469000
    888 .. 232767 linear super 2627128
------------------------

显然,这个设备支持 Virtual A/B。

3. 总结

根据 Virtual A/B 的 Makefile 开关,以及开关的使用流程,有很多方法可以用来检查 Virtual A/B 是否打开。

这些方法包括:

  1. 检查平台的 makefile 文件
  2. 检查编译输出的 misc_info.txt 或 build.prop 文件
  3. 检查编译生成的 super.img 后 super_empty.img 文件
  4. 检查设备上系统的 virtual_ab 属性
  5. 检查设备上系统的 super 分区数据

我记得好像还可以通过检查升级的 payload 文件来确定,不过已经有这么多方法,就不打算再深入了。

4. 其它

到目前为止,我写过 Android OTA 升级相关的话题包括:

  • 基础入门:《Android A/B 系统》系列
  • 核心模块:《Android Update Engine 分析》 系列
  • 动态分区:《Android 动态分区》 系列
  • 虚拟 A/B:《Android 虚拟 A/B 分区》系列
  • 升级工具:《Android OTA 相关工具》系列

更多这些关于 Android OTA 升级相关文章的内容,请参考《Android OTA 升级系列专栏文章导读》

如果您已经订阅了动态分区和虚拟分区付费专栏,请务必加我微信,备注订阅账号,拉您进“动态分区 & 虚拟分区专栏 VIP 答疑群”。我会在方便的时候,回答大家关于 A/B 系统、动态分区、虚拟分区、各种 OTA 升级和签名的问题。

除此之外,我有一个 Android OTA 升级讨论群,里面现在有 400+ 朋友,主要讨论手机,车机,电视,机顶盒,平板等各种设备的 OTA 升级话题,如果您从事 OTA 升级工作,欢迎加群一起交流,请在加我微信时注明“Android OTA 讨论组”。此群仅限 Android OTA 开发者参与~

公众号“洛奇看世界”后台回复“wx”获取个人微信。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

洛奇看世界

一分也是爱~

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

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

打赏作者

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

抵扣说明:

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

余额充值