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

news2024/10/13 0:36:28

文章目录

    • 0. 导读
    • 1. Virtual A/B 的开关
      • 1.1 编译开关
      • 1.2 编译开关的定义位置
      • 1.3 编译开关的作用
    • 2. Virtual A/B 开关检查
      • 方法 1. 从源码判断
        • 示例 1. Broadcom 平台
        • 示例 2. Google 平台
      • 方法 2、从编译输出判断
      • 方法 3、从 image 镜像文件判断
        • 示例 1. 从 super.img 判断
        • 示例 2. 从 super_empty.img 判断
      • 方法 4、从运行设备的系统属性判断
      • 方法 5、从运行设备的 super 分区数据判断
        • 示例 1. 使用 lpdump 查看 super 设备的 header 标识
        • 示例 2. 使用 lpdump 查看 super 设备的 cow 分区
    • 3. 总结
    • 4. 其它

本文为洛奇看世界(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 分区》系列,更新中,文章列表:

  • Android 虚拟 A/B 详解(一) 参考资料推荐
  • Android 虚拟 A/B 详解(二) 虚拟分区布局
  • Android 虚拟 A/B 详解(三) 分区状态变化
  • Android 虚拟 A/B 详解(四) 编译开关
  • Android 虚拟 A/B 详解(五) BootControl 接口的变化
  • Android 虚拟 A/B 详解(六) 升级中的状态数据保存在哪里?
  • Android 虚拟 A/B 详解(七) 升级中用到了哪些标识文件?
  • Android 虚拟 A/B 详解(八) cow 的大小是如何计算的?
  • Android 虚拟 A/B 详解(九) cow 的存储是如何分配的?
  • Android 虚拟 A/B 详解(十) 判断 Virtual A/B 是否打开的 5 种办法

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

  • Linux 快照 (snapshot) 原理与实践(一) 快照基本原理
  • Linux 快照 (snapshot) 原理与实践(二) 快照功能实践

如果您已经订阅了本专栏,请务必加我微信,拉你进“动态分区 & 虚拟分区专栏 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”获取个人微信。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1108652.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

强化学习(reinforcement)

B站链接 https://www.bilibili.com/video/BV13a4y1J7bw?p1&vd_source6f43d02eb274352809b90e8cdf744905 agent----------environment--------goal State 状态 Action 行动 Reward奖励 是一个及时的反馈 目标是一个长远的结果 Core element👇 Policy 策略…

jQuery实现简易购物车

购物车中的商品列表如下: 需求如下: (1)实现如图所示商品列表 (2)单击’移出’按钮可用删除商品 (3)单击’全选’按钮选中所有商品 (4)根据用户的选择&am…

c++学习笔记汇总

[TOC] (C学习笔记汇总) 基础认识、基础语法 类、类与类之间的关系、可调用对象、std::function类模板、c11新标准、资源管理方案RAII、指针、智能指针、引用计数、C的多态 ios、istream、iostream、fstream、sstream 模板编程: 模板编程:主要分为“泛…

uniapp 安装 u-view 组件库

u-view 组件库安装教程:https://uviewui.com/components/install.html 注:以下使用 HBuilderx 安装 u-view 2.0 版本,不适用于其它版本。 1.安装 u-view 组件库 2、注册并登录 HBuilderx 账号,点击下载 u-view 组件库。 3、点击…

[Model.py 02] 地图按比例放大的实现

要求:实现地图按比例放大 分析:考虑到地图放大过程中需要保留河流道路这些物体的相对位置关系,这里选择将河流和道路这些物体的坐标矩阵合并成terrain_matrix并对这个合并后的矩阵进行缩放处理。放大后的矩阵,根据矩阵中标记的物…

如何处理前端响应式图片?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

Jenkins+vue发布项目

在Jenkins 中先创建一个任务名称 然后进行下一步,放一个项目 填写一些参数 参数1: 参数2: 参数3:参数4: 点击保存就行了 配置脚本 // git def git_url http://gitlab.xxxx.git def git_auth_id GITEE_RIVER…

面试题:线程池中线程抛了异常,该如何处理?

文章目录 1. 模拟线程池抛异常2. 如何获取和处理异常方案一:使用 try -catch方案二:使用Thread.setDefaultUncaughtExceptionHandler方法捕获异常方案三:重写afterExecute进行异常处理 1. 模拟线程池抛异常 在实际开发中,我们常常…

2023年【四川省安全员A证】模拟试题及四川省安全员A证作业模拟考试

题库来源:安全生产模拟考试一点通公众号小程序 2023年四川省安全员A证模拟试题为正在备考四川省安全员A证操作证的学员准备的理论考试专题,每个月更新的四川省安全员A证作业模拟考试祝您顺利通过四川省安全员A证考试。 1、【多选题】36V照明适用的场所条…

嵌入式实时操作系统的设计与开发 (中断管理)

中断发生及响应 硬件抽象HAL层响应 中断请求IRQ被中断控制器汇集成中断向量(Interrupt Vector),每个中断向量对应一个中断服务程序ISR,中断向量存放了ISRs的入口地址或ISRs的第一条指令。 系统中通常包含多个中断向量&#xff0…

PyTorch深度学习实战(22)——从零开始实现YOLO目标检测

PyTorch深度学习实战(22)——从零开始实现YOLO目标检测 0. 前言1. YOLO 架构1.1 R-CNN 目标检测模型的局限性1.2 YOLO 目标检测模型原理 2. 实现 YOLO 目标检测2.1 编译 DarkNet2.2 设置数据集格式2.3 配置网络架构2.4 模型训练和测试 小结系列链接 0. 前…

C# 关于托管调试助手 “FatalExecutionEngineError“:“运行时遇到了错误。解决方案

托管调试助手 “FatalExecutionEngineError”:“运行时遇到了错误。此错误的地址为 0x740161f8,在线程 0x1174 上。错误代码为 0xc0000005。此错误可能是 CLR 中的 bug,或者是用户代码的不安全部分或不可验证部分中的 bug。此 bug 的常见来源包括用户对 …

手术麻醉临床信息管理系统源码,客户端可以接入监护仪、麻醉机、呼吸机

一、手术麻醉临床信息管理系统介绍 1、手术麻醉临床信息管理系统是数字化手段应用于手术过程中的重要组成部分,用数字形式获取并存储手术相关信息,既便捷又高效。既然是管理系统,那就是一整套流程,管理患者手术、麻醉的申请、审批…

【C语言】输入一个正整数,判断其是否为素数

1、素数又叫质数。素数&#xff0c;指的是“大于1的整数中&#xff0c;只能被1和这个数本身整除的数”。 2、素数也可以被等价表述成&#xff1a;“在正整数范围内&#xff0c;大于1并且只有1和自身两个约数的数”。 #include<stdio.h>int main() {int i,m;printf("…

如何实现前端社交媒体分享功能?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

如何创建前端自定义主题和样式?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

【API篇】三、Flink转换算子API

文章目录 0、demo数据1、基本转换算子&#xff1a;映射map2、基本转换算子&#xff1a;过滤filter3、基本转换算子&#xff1a;扁平映射flatMap4、聚合算子&#xff1a;按键分区keyBy5、聚合算子&#xff1a;简单聚合sum/min/max/minBy/maxBy6、聚合算子&#xff1a;归约聚合re…

深入理解Java IO流: 包括字节流和字符流的用法、文件读写实践

文章目录 &#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出版社签约作者、产品软文创造者、技术文章评审老师、问卷调查设计师、个人社区创始人、开源项目贡献者。&#x1f30e;跑过十五…

CCF ChinaSoft 2023 论坛巡礼|形式验证@EDA论坛

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;由CCF主办&#xff0c;CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办&#xff0c;将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

【Proteus仿真】【STM32单片机】路灯控制系统

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用LCD1602显示模块、人体红外传感器、光线检测模块、路灯继电器控制等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示时间、工作模…