前言

据说咱的kernel在官方系统上出现了无法安装系统更新的问题,为了排查这个问题就得先把测试机从之前新刷的los回退到官方系统,但是似乎没有那么简单

踩坑的思路们

kebab使用的是非常新的动态分区(安卓10+),而且是动态分区中更为新的virtual a/b(安卓11+),对此我完全没有经验,而这也是阻碍我回刷(以及大量人选择去9008)的主要原因

动态分区是指将system、vendor、product、system_ext等分区集中到super分区中统一管理

p1

这些分区由device-mapper解析,并在设备启动时创建虚拟块设备
因此这些分区并不是在设备上真实存在的,super分区被按照某种机制进行了动态划分,存放着各个动态分区的数据
我们无法通过传统的方式对system、vendor等分区进行直接刷写,但是也有一些替代方案
这些替代方案基于的事实是——aosp recovery(及其继承的fastbootd)继承了完整的动态分区支持
以下的操作都是基于这一主要思路

当然,还有一些奇怪的方法,比如自制super分区、从9008包里提取super分区之类的,或者hack系统的updater?
没时间就不试了((

思路1 sideload氢OS

既然刷Lineage采用的是adb sideload(可以理解为用数据线传包,rec接收到就直接刷),那能不能就这样刷回去呢?同样都是payload.bin的打包格式,也许可以?

炸——windows下sideload进度为0,一直为0卡住
炸——Linux下直接失败,rec内提示缓冲区溢出

好家伙,氢太大了啊?

思路2 sideload氧OS

这个小一点了吧?
炸——传完包校验失败->跳过校验->刷一半错误7

好家伙

思路3 fastbootd直刷

动态分区的设备上,aosp要求rec提供用户空间fastboot(fastbootd) (可以理解为一个可以挂载super分区并修改其中动态分区内容的fastboot加强版)

首先解包payload

然后重启进fastbootd

fastboot flash system system.img

FAILED (remote: Value too large for defined data type)

草?这是空间不足?
在刷写Lineage时,其payload中的配置文件已经把动态分区的大小调整过了,变得太小了,氢氧都完全不够用((

糟了,难道真得9008了?

成功的思路

其实是基于上方的思路3的。我们可以先使用fastbootd的一些特有命令对动态分区内容进行调整
https://source.android.google.cn/devices/bootloader/fastbootd?hl=zh-cn

比如
fastboot getvar is-logical:<partition> 来确定某个分区是不是动态分区(逻辑分区)
fastboot create-logical-partition <partition> <size> 创建动态分区
fastboot delete-logical-partition <partition> 删除动态分区
fastboot resize-logical-partition <partition> <size> 调整分区尺寸

其中分区大小的单位是字节,我是直接使用文件大小+1(防止舍入导致溢出...)

我们先对需要刷写的动态分区进行一顿操作,将其调整到适合的大小
比如
fastboot delete-logical-partition odm_b
fastboot create-logical-partition odm_b 35373057
(也许直接resize也行)
之后正常刷入镜像即可
fastboot flash odm odm.img

其实这里也有个坑,那就是fastboot工具链的版本,太低的版本没法认对逻辑分区进行操作的命令(比如ubuntu自带的)

Virtual a/b 和 普通动态分区的区别?

这次偶然注意到的(之前我都没有发现kebab是virtual a/b。。)
和一般的a/b分区一样,virtual a/b也具有system_a system_b这样的下标,但是,super分区内只存在一个system(可能是a也可能是b),因此,在VAB的设备上fastboot set_active <slot>的结果是,开机直接crashdump。。

VAB的更新流程暂时还没有搞清楚,按照谷歌的文档,VAB会在更新的时候为对应分区创建一个overlay(可能在super里也有可能在data里),并在某些时候merge回来创建新分区?

以下瞎猜几种可能,不知道能蒙对多少
- 更新时直接操作对应分区,更改记录作为overlay,此时读取系统分区内容,由不完整的系统分区和overlay共同返回? 更新完后更改分区的ab标识?(ab标识仅仅只是为了配合boot之类的非逻辑分区的?)
- 更新时操作snapshot,更新的内容作为overlay,如果开机成功,再merge老的数据形成完整分区 (??)

不用猜了,秋大说是第二种🤣

p2

有待继续研究