文章目录

  • 0. 导读
  • 1. Android 官方 VAB 文档
    • 1.1 公开文档
    • 1.2 半公开文档
  • 2. Device Mapper 文档
    • 2.1 device mapper 文档
    • 2.2 dmsetup 工具
    • 2.3 COW 介绍
  • 3. Android 源码
  • 4. 参考资料汇总
  • 5. 后续计划
  • 6. 其它

Android Virtual A/B 系统简称 VAB,我在这一系列里面又将其称为虚拟分区。

0. 导读

我有个 Android OTA 讨论群,群里的大部分朋友都知道一个梗,就是我五一前立下 flag 说要在那个假期完成虚拟分区分析的,但放飞自我远比写东西容易得多,所以这事就搁置了。

从 Android R 开始(2020),各家厂商推出的最新系统就陆续支持 VAB (VAB 或 Virtual A/B),眨眼间两年过去了,Android 陆续又发布了 S 和 T,VAB 也进一步演化成 VABC (Virtual A/B with Compression),增加了压缩功能。

两年过去,好多朋友基于 VAB 已经工作了相当长一段时间,对 VAB 有了深入的理解,坦白说比我深入得多,远离 OTA 的工作让我在这方面比较业余;另外网上陆续有不少分析 VAB 的文章,所以我一度很犹豫,觉得时间过了这么久,没啥必要再写 VAB 了。

不过群里有时候也有朋友抱怨说 VAB 的资料很少,VAB 学习起来有些困难;再加上大环境的因素,太过于关注于外界的消息会让人沉沦,让人看不到希望。面对这一切,自己又做不了什么,为了让自己更聚焦一些,不至于太闲,所以我最终还是决定继续写一写 Android 的虚拟分区系统。

这一篇主要梳理一下我学习 Android 虚拟分区所用到的资料,也顺便推荐给你。

主要有 3 类,Android 官方 VAB 文档,Device Mapper 文档以及 Android 代码。

  • 第 1, 2, 3 部分分别详细介绍了我为什么要推荐这些文档,以及相关文档链接;

  • 如果只对资料汇总列表感兴趣,请跳转到第 4 节,参考资料汇总;

  • 如果对本系列后续计划感兴趣,请跳转到第 5 节,后续计划;

1. Android 官方 VAB 文档

官方文档永远是最重要的参考资料,值得一遍又一遍的阅读

这里我要说的不仅仅是 Android 官方的 VAB 文档,而是你想学习的任何东西的官方文档。因为那是官方开发者的表述,第一手的资料。任何第三方的分析和解释都掺杂了主观解读的成分,通俗来说都算是二手货了,都可能是不准确的,包括我即将写的本系列文章。我建议你把本系列当做官方文档之外的补充,阅读官方文档有不了解的,到我这一系列文章来,看看我是如何分析理解的。

回到官方文档,如果是英文,最明显的一点,不同人的背景不同,英语水平不同,翻译成中文以后意思可能大相径庭。最糟糕的情况就是,翻译出来的东西词不达意,不知所云,类似甚至还不如机翻。

我自己的习惯是,如果一份文档或者标准原来是英文版,那除了阅读中文的参考资料便于快速理解之外,还应该找到原文仔细阅读一下。有时候翻译过来的那些不知所云的词汇,在原文表述中可能相当的浅显易懂。

官方文档的每一段描述都有其用意,你可以试着在阅读后自己向自己解释这段话的作用,如果你解释起来模棱两可,含含糊糊,那就说明还没有真正理解。具体做法参考小黄鸭调试法。

再强调一次:

官方文档永远是最重要的参考资料,值得一遍又一遍的阅读,直到完全弄懂每一段话、每一张图的真正含义。

一开始这一步会很难,因为官方文档通常比较晦涩,或者比较笼统,让人没有去阅读的欲望,但这是成长的必由之路。

说完了废话,该入正题了。

1.1 公开文档

Android 官方 VAB 文档主要包括:

  • Virtual A/B Overview

    • https://source.android.com/docs/core/ota/virtual_ab

    从比较宏观的层面综述 Virtual A/B 的功能。

    无梯子版本:https://source.android.google.cn/docs/core/ota/virtual_ab?hl=zh_cn

  • Implementing Virtual A/B

    • https://source.android.com/docs/core/ota/virtual_ab/implement

    着重讲了 Virtual A/B 的编译开关,在各个组件(包括 BootCtl,fstab,Bootloader,kernel)中涉及的修改。

    无梯子版本:https://source.android.google.cn/docs/core/ota/virtual_ab/implement?hl=zh_cn

  • Implementing Virtual A/B - Patches

    • https://source.android.com/docs/core/ota/virtual_ab/implement-patches

    讲了针对 Virtual A/B 推出以后发现问题提供的一些修复补丁(fix patch)。

    无梯子版本:https://source.android.google.cn/docs/core/ota/virtual_ab/implement-patches?hl=zh_cn

总体来说,这三个页面先从宏观层面综述,再下到模块开关和特性,再到具体问题和补丁,依次从高到低介绍 Virtual A/B,虽然有些简单,但仍然值得反复阅读。因为刚开始阅读,总容易漏掉一些东西。

举个例子,前段时间对 merge 的状态不是很肯定,在群里求证:

但这个问题的答案就在官方文档中,只不过没留意,被我遗漏了,直到多次阅读后才发现:

另外,在 Android S(12) 推出以后,又添加了 VABC 的内容,所以如果你只想学 VAB,所有 VABC 相关的内容都可以忽略。不过还是建议进行略读,以免遗漏像上面这样重要的内容。

官方网站始终保持着最新内容,无法查看历史版本。如果你有保存刚推出 VAB 时的页面,欢迎分享。因为那时候的页面更便于集中学习 VAB。

1.2 半公开文档

这里所说的半公开文档是指:Android_VirtualAB_Design_Performance_Caveats.pdf

所谓半公开,是因为它属于 partner 文档。只有当你的公司成为 Google 的 partner,Google 才会给你开放 partner 账号,通过 partner 账号才能访问的内容。

这是我目前见过最详细的介绍 Android VAB 的文档,除了没有展示代码细节外,几乎涉及了 VAB 的方方面面。

以下是几个官文这个文档的截图:

  • 首页

  • 分区布局

  • 升级过程的分区映射

  • 升级过程描述

上面这张示例截图只包含了升级过程描述的部分。

OTA 讨论群里也分享很多讲述 VAB 的文章或文档,包括一些原厂的资料,基本上都离不开这篇文档,其中用于描述的图片和更新流程的介绍,也都出自这篇文档。

所以,如果你手上有这份文档,目前网络上所有介绍的 VAB 操作的资料都不需要再看了,你所需要做的,就是反复阅读这份文档。

另外,特别备注感谢当初分享这份文档的朋友,老朋友们应该知道我说的谁~

2. Device Mapper 文档

安卓虚拟分区 VAB 最难的地方在于加入了 snapshot, COW 和 merge 等一系列 Device Mapper 的行为和特性,让系统分区不再拥有静态的布局。升级过程中分区动态的变化让初次接触的人觉得错综复杂,难以理解数据到底流向了哪里,不明白某个时刻系统中的镜像到底是什么状态。虽然从 Android Q 开始的动态分区就已经不再是完全静态了,但相比于后面 Android R 的 VAB 来说,还是简单很多。

所以,如果能清晰的理解 Device Mapper 的行为,学习起 VAB 来就更容易。

Device Mapper 支持的设备种类很多,VAB 中涉及的主要是 dm-verity, dm-linear 和 dm-snapshot,尤其 dm-snapshot。

2.1 device mapper 文档

我在《Android 动态分区详解(一) 5 张图让你搞懂动态分区原理》有提到一篇从比较高层次介绍 device mapper 机制的文章:

  • Linux 内核中的 Device Mapper 机制

    • https://blog4jimmy.com/2018/03/457.html

作为 linux 的驱动模块,自然建议参考 linux 的官方文档,位于 Documentation/device-mapper 目录下。

这个文档也有在线版本,推荐必看 dm-snapshot 文档:

  • Device-mapper snapshot support

    • https://docs.kernel.org/admin-guide/device-mapper/snapshot.html

2.2 dmsetup 工具

说到 Device Mapper,就不得不提到调试工具 dmsetup,如果单纯看文档不好理解 device mapper 如何工作,则可以通过 dmsetup 工具来进行实践,加深理解。只有动手做了,才会有更深刻的印象。

我在 《Android 动态分区详解(二) 核心模块和相关工具介绍》 一文中有介绍过如何使用 dmsetup 来映射动态分区。实际上主要参考了下面这个网页,它详细演示如何使用 dmsetup 来进行各种 dm 设备的操作:

  • Device-mapper (强烈推荐)

    • https://wiki.gentoo.org/wiki/Device-mapper

类似的参考文档还有 RedHat 官方的 Logical Volume Manager Administration 的附录A

  • Appendix A. The Device Mapper

    • https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html-single/logical_volume_manager_administration/index#device_mapper

这篇可以和前面介绍 dmsetup 操作的交叉阅读,如果只推荐一篇的话,推荐参考前一篇。

当然,如果有兴趣的话,也可以读一读 dmsetup 工具的命令行帮助文档,这里就不再详细说明了。

2.3 COW 介绍

为了能比较好理解 snapshot 是如何工作的,也建议了解下 snapshot 的基本原理,推荐阅读下面这篇文章:

  • COW、ROW 快照技术原理

    • https://support.huawei.com/enterprise/zh/doc/EDOC1100196336/

还有这一篇,主要介绍了 IBM 存储设备系统上使用的 Redirect-on-Write (ROW):

  • IBM Redirect-on-Write (ROW)

    • https://www.ibm.com/docs/en/xiv-storage-system?topic=snapshots-redirect-write-row

需要特别说明的是,IBM 的知识库文章经常更新,所以上面这个链接可能过一段时间就不能访问了。

这里有一篇简单介绍存储设备 NetApp 厂家的 snapshot 实现的,知识量小,比较浅显:

  • Snapshot基础知识

    • https://blog.51cto.com/xiahongyuan/929806

为了避免你关于 snapshot 的原理看多了走火入魔,导致 COW(Copy-On-Write) 和 ROW(Redirect-On-Write) 傻傻分不清,以下特别做一个简单总结,后面会单独开一篇介绍 Android 中我对 COW 的理解。

从快照( snapshot) 原理的角度来讲,一共分 3 种:

  • Full Volume Copy,顾名思义,就是对整个存储卷的内容完全进行 copy,这种方式相当于一个完全备份。
  • COW (Copy-On-Write),创建快照写入新数据块时,将原来设备中的数据 Copy 到快照设备中,然后将新数据写入到原来数据块的地方。
  • ROW (Redirect-On-Write),创建快照写入新数据时,原来设备中的数据不变,新数据写入到快照设备中。

实际使用中,跟上面提到的快照原理有些不同:

  • 没有人使用 Full Volume Copy 的方式进行快照,那是备份。
  • 在 linux 驱动中,概念上不再明确区分 COW 和 ROW,把 COW 和 ROW 统一叫做 COW。

而且实际使用中,基于 linux 的系统,快照基本上都是使用 ROW 的方式,即新数据写入到快照设备中,旧数据在原始设备中维持不变,然后再通过一个叫做 merge 的操作,将快照设备中的新数据写入覆盖原始设备中的数据。

所以,Android 文档中提到的 COW 设备,对应于快照原理的 ROW 操作(创建快照写入新数据时,原来设备中的数据不变,新数据写入到快照设备中,再通过 merge 操作改写原始设备中的数据)。如果这一点没搞清楚,估计就会非常迷糊。

3. Android 源码

可能是做了太久技术支持的缘故,为了找到 bug 的原因,已经习惯了基于最小化差异的方式进行工作。凡事都尽可能隔离其他因素的影响,使用单一变量进行跟踪。

例如,研究虚拟分区,我推荐这样学习源码:

Android Q(10) 支持动态分区,Android R(11) 在动态分区的基础上引入虚拟分区 VAB,我会选取动态分区 Android 的最后一个版本(android-10.0.0_r41),和支持虚拟分区 VAB 的第一个版本(android-11.0.0_r1),然后对比这两个版本的代码来研究虚拟分区到底引入了哪些代码上的改变。

我学习动态分区时也是使用这种方式。

关于如何查看 Android 个版本支持的设备,请参考:

  • Source code tags and builds

    • https://source.android.com/docs/setup/about/build-numbers#source-code-tags-and-builds

无梯子版本:

  • 源代码标签和构建

    • https://source.android.google.cn/docs/setup/about/build-numbers?hl=zh-cn#source-code-tags-and-builds

4. 参考资料汇总

参考资料(点击链接直达):

  • Android 官方网站关于 Virtual A/B 相关的网页

    • Virtual A/B Overview
    • Implementing Virtual A/B
    • Implementing Virtual A/B - Patches

    以上网页需要梯子,以下是无障碍版本:

    • 虚拟 A/B 概览
    • 实现虚拟 A/B
    • 实现虚拟 A/B - 补丁
  • Android Partner 文档 (强烈推荐,反复学习)

    • Android_VirtualAB_Design_Performance_Caveats.pdf
  • Device Mapper 文档

    • Linux 内核中的 Device Mapper 机制

    • Linux 内核文档: Device-mapper snapshot support

    • Device-mapper 中 dmsetup 工具的使用

  • snapshot 原理和 COW 介绍

    • COW、ROW 快照技术原理
    • IBM Redirect-on-Write (ROW)
    • Snapshot基础知识
  • Android 源码,推荐对照以下两个版本学习

    • android-10.0.0_r41
    • android-11.0.0_r1

这些资料部分来自群友分享和推荐,部分是我学习查找的资料,希望对你有用。

如果你有更好的资料也欢迎推荐,一起学习。

5. 后续计划

既然 Android_VirtualAB_Design_Performance_Caveats.pdf 是最详细的文档,后续文章将围绕这个文档的分析展开。主要包括以下内容:

  • 虚拟分区布局

  • 虚拟分区原理和状态变化

  • OTA 更新流程介绍

  • OTA 更新流程主要步骤的代码分析

    • 动态分区数据 metadata 更新
    • COW 设备的创建
    • update 完成后第一次第一次重启,merge 状态的变化及处理
    • merge 完成后第一次重启,系统状态的变化及处理
    • COW 设备的销毁

以上只是初步设想的文章内容,具体可能会有些变化。

除了上面列举的话题外,也可能会增加一些其他感兴趣的话题。

6. 其它

洛奇工作中常常会遇到自己不熟悉的问题,这些问题可能并不难,但因为不了解,找不到人帮忙而瞎折腾,往往导致浪费几天甚至更久的时间。

所以我组建了几个微信讨论群(记得微信我说加哪个群,如何加微信见后面),欢迎一起讨论:

  • 一个密码编码学讨论组,主要讨论各种加解密,签名校验等算法,请说明加密码学讨论群。
  • 一个Android OTA的讨论组,请说明加Android OTA群。
  • 一个git和repo的讨论组,请说明加git和repo群。

在工作之余,洛奇尽量写一些对大家有用的东西,如果洛奇的这篇文章让您有所收获,解决了您一直以来未能解决的问题,不妨赞赏一下洛奇,这也是对洛奇付出的最大鼓励。扫下面的二维码赞赏洛奇,金额随意:

洛奇自己维护了一个公众号“洛奇看世界”,一个很佛系的公众号,不定期瞎逼逼。公号也提供个人联系方式,一些资源,说不定会有意外的收获,详细内容见公号提示。扫下方二维码关注公众号:

Android 虚拟分区详解(一) 参考资料推荐相关推荐

  1. Android 虚拟分区详解(三) 分区状态变化

    Android Virtual A/B 系统简称 VAB,我将其称为虚拟分区. 本系列文章基于 Android R(11) 进行分析,如果没有特别说明,均基于代码版本 android-11.0.0_r ...

  2. Android 虚拟分区详解(二) 虚拟分区布局

    文章目录 0. 导读 1. Android 传统 A/B 分区和动态分区布局 2. Android 虚拟分区布局 3. 虚拟分区的思考 2.1 分区只有一套,如何实现 A/B 系统特性? 2.2 部分 ...

  3. Android 动态分区详解(一) 5 张图让你搞懂动态分区原理

    文章目录 0. 导读 1. 动态分区详解的背景 1.1 背景 1.2 动态分区的本质 2. Linux device mapper 驱动 3. Android 动态分区布局 3.1 动态分区布局 3. ...

  4. Android 动态分区详解(七) overlayfs 与 adb remount 操作

    0. 导读 最开始学习 Android 动态分区源码的时候,比较代码发现 system/core/fs_mgr 目录下多了一个名为 fs_mgr_overlayfs.cpp 的文件,一直不知道什么时候 ...

  5. Android 动态分区详解(六) 动态分区的底层机制

    文章目录 1. Android 动态分区的两重含义 2. device mapper 的原理 3. linear 映射的原理 3.1 多个设备映射示例 3.2 `dmsetup create` 命令参 ...

  6. android各个分区详解

    1. bootloader   当我们拿到一款手机,第一件事应该就是按下电源键开机,那么从开机到进入到桌面程序这中间发生了些什么呢,我们从下面这张简化了的手机结构图开始: 注意:该结构图并不反映手机的 ...

  7. Android eMMC 分区详解(转载)

    原文链接:http://blog.csdn.net/firefox_1980/article/details/38824143 1. fastboot flash boot boot.img 当使用上 ...

  8. android emmc重新分区,Android eMMC 分区详解

    1. fastboot flash boot boot.img 当使用上述命令写入编译的Image时,fastboot做了些什么?基于那些信息把Image写到哪里呢? Android的每一款产品,都有 ...

  9. Android Studio 插件开发详解一:入门练手

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78112003 本文出自[赵彦军的博客] 系列目录 Android Gradle使用 ...

最新文章

  1. CentOS7.4到Elasticsearch一路坑(五)
  2. 缅怀袁隆平院士:一颗稻谷里的爱国情怀
  3. java基础第十一篇之Date、Math、自动装箱和拆箱
  4. c转义字符以及常见问题和解决方法||c中的注释
  5. python3.7安装numpy库_python2.7/3.7安装NumPy函数库的一种方法及小心得
  6. 坯子库安装不上_柜式七氟丙烷的安装调试方法
  7. crawlspider
  8. OD使用教程7(上)- 调试篇07|解密系列
  9. ssl charles 参数看不到_偷偷告诉你Charles的秘密
  10. 将文件中的单词及翻译导入数据库
  11. 背包问题(Knapsack Problem)—— 完全背包问题 —— (1)背包价值最大
  12. Graphene(石墨烯)区块传播技术能够实现10倍的更高效率
  13. 如何缓解眼睛疲劳酸痛?
  14. postgres关键字、常量和数据类型
  15. 关于阿里云服务器安全组规则
  16. 算法解析—同向双指针 字节笔试 万万没想到抓捕孔联顺,列表最大间隔不超过D
  17. php中file_get_contents与curl性能比较分析
  18. 百度java面试应届,秋招 百度二轮面试---血淋淋的经历写实
  19. html5小游戏跑,HTML5 Speedster 小游戏(高速跑跳过关)
  20. mac版Mysql可视化工具 - Sequel Pro

热门文章

  1. vultr所有服务器ping测试
  2. 简单几步教你搞定LIS,LCS,LICS问题
  3. struts 2 国际化乱码问题解决方案
  4. 华为和荣耀手机升级鸿蒙系统之后与matebook无法多屏协同的问题
  5. python 模块包裹
  6. 【愚公系列】2022年01月 MinIO文件存储服务器-对象操作(Python版)
  7. 西门子plc程序代写代写西门子plc程序包括200smart,1200plc和1500plc和上位机系统
  8. html5上传图片限制大小
  9. 初中计算机使用在线,初中信息技术考试模拟试题(flash+网站基础知识)
  10. py文件如何加密为pyc文件