DSU 的初衷是为了让开发者可以便捷运行不同系统版本的GSI,以便执行应用测试等开发工作。该文章面向有一定刷机基础知识和动脑能力的普通用户,对其两大用途:无损体验新的 Rom、无损提取 boot 镜像——进行尽量高效的指导并总结经验。如有错误敬请评论指出。

基础知识

DSU:动态系统更新,Android10 中引入的一项系统功能,可以在设备上将 GSI 作为来宾操作系统启动,使设备能在不破坏原系统和数据的情况下运行任意 Android 镜像

GSI:通用系统映像,一个zip或gz格式的 Rom 包,像 Windows 可以安装在任何x86平台一样,GSI 可在各种 Android 设备上安装并运行,因此它通常是原生或类原生系统,且指纹,通话等依赖厂商驱动的功能会无法工作。GSI 既能被 DSU 侧载,也能直接刷入设备

注意事项

  • DSU 侧载前要确保设备剩余空间≥40%,否则可能会报错提示安装失败。
  • GSI 启动时会使用原系统的 boot、init_boot 镜像,这意味着如果原系统安装了 Magisk\KSU ,那么 GSI 中直接安装管理器即可使用 Su 权限
  • DSU 并非绝对安全,如果 GSI 在你的设备运行时有明显异常,立即重启并舍弃
  • 做好备份,没有人会为你的数据损失负责

GSI 安装指南

原生方案-快速尝鲜

需求:

支持 DSU 的设备,无需解锁BL

设备剩余空间≥40%

步骤:

  1. 激活开发者选项, 从中找到 DSU Loader
  2. 选择一个 GSI 即可自动下载并安装,带 GMS 即为含 Gapps
  3. 安装完毕后顶部出现通知,点击重启进入安装好的 GSI

进阶方案-任意刷入

需求:

支持 DSU 的设备
如果设备没有解锁 bootloader,GSI 需要开发版公钥签名。
如果设备解锁了 bootloader,GSI 不受限。

设备剩余空间≥40%

自行准备的GSI包

Root或adb权限

步骤:

  1. 下载安装 DSU Sideload 并打开,选择想要刷入的 GSI 包
  2. 授予 Root 或根据提示执行 adb 命令以得到 dsu 的权限
  3. 安装完毕后顶部出现通知,点击重启进入安装好的 GSI

无脑方案-直接覆盖

需求:

无需支持DSU
如果设备没有解锁 bootloader,确保 GSI 带有开发版公钥签名,否则设备将无法启动。
如果设备解锁了 bootloader,GSI 不受限。

自行准备的GSI包

步骤:

  1. 设备重启至 fastboot ,电脑解压 GSI 包,提取出 img 文件
  2. 将所有 img 文件刷入到对应分区
  3. 清除 data 分区数据
  4. 重启设备
fastboot flash system system.img #刷入镜像
fastboot erase userdata #清除数据
fastboot reboot #重启

GSI 获取指南

命名规则

{arm|a64|arm64}_{a|b}{v|g}{N|S}-{vndklite|secure|personal}
|               |    |    |     |
|               |    |    |     vndklite: 给VNDKLite设备
|               |    |    |               或用于常规设备上的可读写/系统
|               |    |    |     secure: 移除了Root并欺骗system props,适合过SafetyNet
|               |    |    |
|               |    |    |     personal: 附有个人mod,供参考
|               |    |    |
|               |    |    N: 没有超级用户
|               |    |    S: 使用 PHH Superuser 构建(需要应用程序)
|               |    |    (Z): 使用 eremitein 的动态超级用户构建(此处未提供)
|               |    |
|               |    v: Vanilla, 不含 Gapps
|               |    g: 含有常规 Gapps
|               |    o: 含有 Android Go GAPPS
|               |    (f): 含有 MicroG 和 FLOSS 替代 GAPPS(此处未提供)
|               |
|               a: "A-only" SAS (Android12起弃用)
|               b: "A/B" SAR
|
arm: ARM 32位CPU (Android12起弃用)
a64: ARM 32位CPU 和 64位 binder
arm64: ARM 64位CPU

如果手机采用 AB/VAB 分区,应选择 A/B类型GSI ;如果手机支持 System as Root ,也应选择 A/B类型GSI 。两者均不支持则选择 A_only类型GSI ——这通常是 Android12 前的机型

VNDK:供应商原生开发套件,支持的设备可以使用比原系统版本更高的 GSI 系统版本,否则只能使用与原系统版本相同的 GSI 。

VNDK lite:有些设备 VNDK 为 lite 模式(与A/B和A_only无关),此时应该选择名称中含 vndklite 字样的 GSI 。

如果 GSI 包有 silm,vanilla,bvN 这种命名,就是不含 GAPPS 的包,基础套件来自 AOSP。其它的命名如 bgN,GMS 即为含 Gapps,包的体积更大。

CPU架构:通常分ARM32位与ARM64位,依据情况选择

一些下载站点

Andy Yan’s personal builds // GSI - Browse Files at SourceForge.net

Andy Yan的lineage非官方GSI下载站

小米红米SGSI|GSI镜像下载 - FiimeROM

收集了众多移植的类原生和国产Rom

DSU 尝鲜 Rom

众多的类原生 Rom 可谓琳琅满目,如果你希望尽快找到自己喜欢的 Rom ,或在新 Rom 出现时尝尝咸淡,且不希望反复清数据刷机,DSU 是最好的解决方案。

有时你能找到的类原生官方的 GSI 包,有时还是需要下载适合自己设备的刷机包后手动做一个 GSI 包。只需从中拿出下面五个 img 镜像,压缩为 zip 即可得到一个简单的 GSI 包。

  • odm.img - 制造厂商的设备硬件微调
  • product.img - 芯片供应商的专有底层驱动
  • system.img - Android 系统的核心骨架
  • system_ext.img - AOSP 核心之外的,厂商定制的系统功能
  • vendor.img - 针对特定机型的软件定制层

通常下载的刷机包有三种,获取上述img文件方法为:

  1. Fastboot 脚本刷机包 —— 解压即得
  2. 普通 zip 更新包 —— 使用MT管理器或 payload_dumper 解压 payload.bin 取得
  3. 含 super.img 的更新包 —— 使用MIO-KITCHEN-SOURCE解包 super 到 img 取得

不建议将MIUI等设备厂商高度魔改的ROM按此方法制作启动,因为这可能导致系统出现严重问题,如设备每次重启都会回到GSI(未受粘滞模式影响且禁用粘滞模式命令不起作用),这种情况下重刷初始系统也不会解决问题,唯一的解决方案就是清除设备全部数据。

DSU 提取原厂系统镜像

任何支持 sideload 的设备都可以启动一个 userdebug 版的 gsi 。仅需在开发者选项开启开关即可获得 adb 的 Root 权限,并提取原系统的 boot、init_boot 等关键镜像。

条件:
如果设备没有解锁 bootloader,GSI 需要开发版公钥签名。
如果设备解锁了 bootloader,GSI 不受限。
少数安全防护更强的手机无法实现(三星貌似是)。

刷入GSI后,使用adb连接设备并进入shell,取得su权限

adb shell
su

eMMC 闪存设备提取 boot 示例

find /dev/block/platform/ -name 'by-name' -type d #确定分区路径
cd "上句命令取得的分区路径" #打开到分区所在位置
ls -l boot #找到boot分区位置
dd if="分区所在路径" of=/sdcard/boot.img #提取分区并保存到/sdcard/boot.img

UFS 闪存设备提取 boot 示例

#UFS设备分区位置通常是确定的
cd /dev/block/by-name/ #打开到分区所在位置
ls -l boot #找到boot分区位置
dd if="分区所在路径" of=/sdcard/boot.img#提取分区并保存到/sdcard/boot.img

根据你的设备的槽位类型和要使用的 Root 方案,提取对应的分区镜像(以 boot 为例):

  • 设备采取 A_only 分区,提取 boot
  • 设备采取 AB/VAB 分区,根据原系统状态提取 boot_a/b
  • 若安装 Magisk 且设备出厂 Android13 以上,提取 init_boot_(a/b)

提取完成后做你想做的的操作,再使用命令把所有镜像刷回对应分区(确保解锁了BL)。

dd if="修补后boot.img位置" of="boot分区位置" #adb下刷入boot镜像
reboot #重启设备

DSU相关命令

启用粘滞模式,每次重启默认进入GSI系统

adb shell gsi_tool enable

禁用粘滞模式,GSI启动失败系统会自动执行

adb shell gsi_tool disable

检查设备是否支持Treble

adb shell getprop ro.treble.enabled

检查设备是否支持跨版本安装。需在输出的[vendor]部分中查找namespace.default.isolated

adb shell cat /system/etc/ld.config.version_identifier.txt \
| grep -A 20 "\[vendor\]"

使用adb启用DSU,文件名system_raw.gz,用户空间设置为8GB

adb shell am start-activity \
-n com.android.dynsystem/com.android.dynsystem.VerificationActivity  \
-a android.os.image.action.START_INSTALL  \
-d file:///storage/emulated/0/Download/system_raw.gz  \
--el KEY_SYSTEM_SIZE $(du -b system_raw.img|cut -f1)  \
--el KEY_USERDATA_SIZE 8589934592

尾注

即使问题几率再低,也务必做好备份

没有人会为你的数据损失或机子变砖负责