LOGCAT.IO | Android 的 v-a/b分区简单理解

基础理解

我们可以直接把v-a/b分区理解成,当你在使用手机,进行系统升级,系统会把升级内容存放在A分区,你继续使用B分区,前面的V就是虚拟的意思(virtual)。在尽量不影响你使用的开机情况下进行升级,取消了在rec分区进行升级的复杂操作

详细理解(我的浅见)

首先说结构。传统结构中,存在recbootsystem分区,在V-ab结构中,抛弃了提到的这三个分区,取而代之的是:boot_a,system_a,boot_b,system_b。这就是v-ab。

首先要介绍Δ(delta,小写δ)文件。Δ文件就是cow(copy-on-write)文件,字面意思,具体可以看wikipedia的解释。然后我们首先打开谷歌的官方文档:https://source.android.com/devices/tech/ota/virtual_ab#device-mapper ,里面请看:这个super分区(超级分区)

这个分区,就是用来储存Δ文件的。那么在进行一些比较大的升级的时候,Δ文件可能比较大,预分的super分区可能存在不足的现象。这个时候,会把多余的文件储存到/data下。这个情况基本只发生在Android11上,因为Android10预留了两倍逻辑分区的空间。Android10的VAB分区本身就不是原生的,是根据动态分区改装而来的。

那么,当你在Android11手机上,开机状态下进行升级时,在哪里查看文件呢?你可以查看下面这个路径:/data/gsi/ota,下面存在一些列的带有cow.img文件。至于存在与哪里,就看系统分配的super分区的逻辑空间大小了。

现在再看官方文档:https://source.android.com/devices/tech/ota/virtual_ab#dm-snapshot-overview ,下面的DM概述。其中:

快照设备是使用snapshot目标创建的。写入快照设备将写入COW设备。从快照设备读取是从基本设备读取还是从COW设备读取,具体取决于快照是否更改了所访问的数据。

这就说明了,为什么在生成完cow文件之后,系统把bootContral.hal的合并状态改为snapshoted了。如果当前你在操作a空间,那么系统会把你当前的系统分区从system_a改为system_a_cow,然后会开始把你切换到B分区,你至此仍然可以正常使用手机,只是切换过程中你使用手机,可能会有一点点卡感觉。

在生成完cow文件之后,系统这时提示我们重启。我们发现,重启依然会有一个时间需要等待,和之前的rec读cmd安装差不多啊。那么到底这个时间系统在做什么呢?

首先我们默认你升级前使用的是a分区。在你关机后,由于之前的hal文件改为了snapshoted,这个时候系统会把对应的旧系统分区和Δ文件进行合并。不过这个时候单纯是加载到内存中,不是合并的二进制文件。如果这个时候重启成功,那么系统会在开机后,偷偷地合并剩余的二进制文件,这个时候系统会把bootContral.hal的合并状态改为merging,合并中。如果存在开机失败的状态,那么系统则直接读取老系统文件进行回滚(其实不是回滚,直接读取就完事了)。直至开机成功,hal文件的合并状态才会被置空,等待下一次升级。

看到这里你会问了,这个逻辑其实和之前的读取刷机脚本进行升级差不多啊。其实这里最大的差别,除了分区升级外,就是一个最厉害的点:在bootContral.hal的状态为合并中(merging)的时候,你可以随意重启手机。而只有在bootContral.hal的状态为合并中的时候,也才算是真正的系统升级状态。接下来解释为什么很多手机看起来依然和之前的手机升级效果差不多?其实很多厂商会估计把这个合并过程加上动画……让你看起来手机没有进入系统,实际上手机是进入系统了,只是没有启动桌面,给你看这个合并进度而已。如果这个时候你重启,在重启后,手机会继续合并剩余的文件,减少了崩溃的情况。即使崩溃,手机也会直接读取旧系统文件,你依然可以重新进行升级!

总结

其实这只是我简单的理解。也看了网上的一些文章。因为谷歌对v-ab的描写基本等于没说… 看了大神们对v-ab的解释之后,我才知道这玩意其实挺糊弄(中间替换系统分区名字那一段…),也挺牛的,减少了你每月一次可能由于升级导致系统崩溃的情况,也开始逐渐抛弃bl……

唯一对不起的就是刷机佬,刷机学习成本再次提高…