ChrAlpha's Blog

F2FS ROM 引发的悲剧及其解决方案

2021-08-15·便签格

「便签格」是一个重新开始打理的主题,内容整体类似于少数派的「一日一技」,名字受便利贴使用哲学的启发。这里专注于分享特定技巧、发掘细节功能,篇幅往往不长。「便签格」既不像「技术向」那般关注原理、也不像「笔记本」那般详细记录,「便签格」只聚焦一个动作。

事发突然,就在昨天,我又把我的 Android 设备刷废了。尽管有所防备,在一切开始之前将所有数据都备份了,但次次栽坑总还是有点郁闷。

不过这次算是领教了一个之前从未注意过的教训——部分 ROM 可能会对文件系统有所要求,若不遵循很可能导致无法开机。而搜索引擎前面很多文章介绍的解决的方案基本都高度依赖 TWRP,然而当 Android 12 都快发布了 TWRP 仍未支持 Android 11,所以本文再介绍一种仅依赖 fastboot 便可完成的解决方案(其实就两条很基本的命令罢了)。

不同文件系统:F2FS 与 ext4

从标题可以得知,这次「灾难」的导火索是严格要求 F2FS 文件系统的 Android 类原生 ROM——Dot OS (Droid on Time),而其它 ROM 譬如 Lineage OS、Pixel Experience 等均只要求 ext4 文件系统。

ext4 即为第四代扩展文件系统(Fourth extended filesystem,ext4),2006 年被首次公开、2008 年被当成稳定版本并入 Linux 源代码并成为官方建议的默认文件系统。而 Android 正是基于 Linux 开发,早在 Android 2.3 就已用 ext4 取代 YAFFS,市面上绝大多数 Android ROM 也确实使用的是 ext4 文件系统。

F2FS(Flash-Friendly File System)是一种闪存文件系统,最初就是为了 NAND 闪存存储设备设计的。相比之下,ext4 最初设计是考虑到运行在机械硬盘(磁盘)等区块存储设备上的,而由于其读写性能远不如 SSD 固态硬盘等闪存存储设备,所以现在很多场景都使用固态硬盘。Linux 随后也推出了 MTD 这一硬件抽象层,它能让闪存设备看起来像是一种区块设备,从而使针对区块设备的文件系统直接应用在闪存上。

这两者严格意义上不属于同一领域的文件系统,一个是直接为了闪存设备而设计的,一个是为区块设备设计的。将闪存设备模拟成区块设备运行的 ext4,与直接运行在闪存设备上的 F2FS 对比,这样似乎有点不厚道。这么做我想是由于 2019 年中下旬,OnePlus 7 Pro 与 Galaxy Note 10 几乎同期发布且两者均使用由三星提供的 UFS 3.0 存储,前者由于使用 ext4 而性能不敌使用 F2FS 的后者。

关于更详细的 Benchmarks 跑分对比,可以参考 XDA 帖子 - [Benchmarks] File System Performance: F2FS vs EXT4

如何刷入 F2FS ROM

事实上,即便不将 Data 分区格式化成 F2FS,你依旧是能刷入 ROM 的(期间甚至没有明显的报错),只不过会一直卡在卡机页面,无法进入系统罢了。

其实格式化明明是一件很简单的事情。然而我求助搜索引擎,许多文章却说 TWRP 是不可或缺的,这让我走了不少弯路。显然,我已经更新 Android 11 的设备是用不了 TWRP 的了(甚至 在更新 Android 11 的时候还因为 TWRP 的缘故而翻车),而用 fastboot 只用两行基础的命令,不知道那些文章为什么不提。TWRP 在 Android 12 即将发布之际甚至还未适配 Android 11,这让我有意无意在卡刷的时候会想有没有替代方案,避免在一棵树上吊死。

开始之前:薛定谔的 Cache 分区

如果你的设备在格式化 cache 分区时报错:

# fastboot
FAILED (remote: 'GetVar Variable Not found')
fastboot: error: Command failed

# TWRP
Cache 无效的分区

请不要慌张,有可能是你的设备没有划 cache 分区,Google 的表述 是:

cache 分区用于存储临时数据,如果设备使用 A/B 更新,则可以不要此分区

那么之后所有关于 cache 分区的操作直接跳过就好,别像我还在这里纠结过一会。

Fastboot 解决方案

通过 fastboot --help 可以看到,我们可以借助以下命令很轻松地格式化指定分区:

fastboot format[:FS_TYPE[:SIZE]] PARTITION

其中 FS_TYPE 就是对应文件系统,PARTITION 则是指定分区。对于此次任务而言,我们要将 userdata(也就是 Data 分区)和 cache 分区格式化成 f2fs

  • userdata 分区格式化成 f2fs

    fastboot format:f2fs userdata
  • cache 分区格式化成 f2fs

    fastboot format:f2fs cache

请不要擅自格式化其它分区,这可谈不上什么多多益善,像我第一次连 bootvendor 也顺手格式化了,结果就是卡开机动画。

TWRP 解决方案

首先要在 TWRP 设置里勾选「use rm -rf instead of formatting」,否则再后续刷入过程中 TWRP 会将分区重新格式化成 ext4。

然后使用「Wipe」内「Change File System」将 userdata(也就是 Data 分区)和 cache 分区格式化成 f2fs

  • userdata 分区格式化成 f2fs
    1. 依次进入:Wipe => Advanced Wipe
    2. 勾选 data,以指定格式化的分区
    3. 依次点击:Repair or Change File System => Change File System
    4. 选择 F2FS,以指定需要格式化成的文件系统
    5. Swipe to change,完成修改
  • cache 分区格式化成 f2fs
    1. 依次进入:Wipe => Advanced Wipe
    2. 勾选 cache,以指定格式化的分区
    3. 依次点击:Repair or Change File System => Change File System
    4. 选择 F2FS,以指定需要格式化成的文件系统
    5. Swipe to change,完成修改

后记

很显然,我在 Android 刷机方面实在算不上什么「高玩」,还栽倒在这么无聊的问题上。

不过很多时候,翻阅官方文档都要比搜索来路不明的教程要更高效,对于这次至少我就不会还去找修改版的 TWRP——因为 TWRP 压根就不是必须的,甚至 fastboot 更方便,而绝大多数 Google 排名很靠前的教程却还说「must need」。这算是最大的一个教训吧。

参考资料

我并非此方面专业,许多内容都是从 Wikipedia 学习总结而来,如有纰漏还请评论指教。

F2FS ROM 引发的悲剧及其解决方案
本文作者
ChrAlpha
发布日期
2021-08-15
更新日期
2021-08-15
转载或引用本文时请遵守 CC BY-NC-SA 4.0 许可协议,注明出处、不得用于商业用途!