常规系统映像 (GSI)

常规系统映像 (GSI) 是包含已针对 Android 设备调整配置的系统映像。这种映像被视为所有 Android 设备应该都能顺利运行且包含未经修改的 Android 开源项目 (AOSP) 代码的“纯 Android”实现。

GSI 中的内容不依赖于供应商映像。为了验证 GSI 的独立性,Android 设备的系统映像会被替换为 GSI,然后通过供应商测试套件 (VTS)兼容性测试套件 (CTS) 进行全面测试。同样,您可以使用 GSI 替换自己的系统映像,以验证 Android 设备能够正确实现供应商接口。

GSI 配置和差异

GSI 的目标是为所有 Android 设备提供特定的通用配置,同时允许不同的供应商设备之间存在差异。当前的 GSI 基于 Android 9。

当前的 GSI 具有以下配置:

  • Treble。GSI 完全支持 Android 8.0 中引入的基于 HIDL 的架构更改(也称为“Treble”),其中包括对 HIDL 接口的支持。您可以在任何使用 HIDL 供应商接口的 Android 设备上使用 GSI(如需了解详情,请参阅关于架构的资源)。
  • 验证启动。 GSI 不包含验证启动解决方案(vboot 1.0AVB 等)。要将 GSI 刷写到 Android 设备上,此设备必须具有停用验证启动的方法。
  • 编译变体。GSI 始终凭借 userdebug 编译变体来支持运行 VTS 和 CTS。将系统映像替换为 GSI 后,您可以对设备进行 Root 操作,然后使用 user 版本的供应商映像和 userdebug 版本的系统映像进行测试。
  • 文件系统和映像格式。GSI 使用具有稀疏映像格式的 ext4 文件系统。

当前的 GSI 包含以下主要差异:

  • 版本。支持 Android 8.0、Android 8.1 和 Android 9。
  • CPU 架构。支持不同的 CPU 指令(ARM、x86 等)和 CPU 位数(32 位或 64 位)。
  • 分区布局。可以使用 system-as-root 或非 system-as-root 分区布局。
  • 支持 binder 接口位数。

GSI 类型

GSI 类型取决于设备搭载的 Android 版本。Android 9 支持以下 GSI:

GSI 名称 说明 产品名称
Android GSI 适用于搭载 Android 9 的设备 aosp_$arch
旧版 GSI 适用于搭载 Android 8.0 或 Android 8.1 的设备 aosp_$arch_a(b)

所有 GSI 都是从 Android 9 代码库编译的。是否支持旧版 GSI 取决于设备的供应商接口实现,并非所有搭载 Android 8.0 或 Android 8.1 的设备都能使用旧版 GSI。有关详情,请参阅供应商二进制文件和 VNDK 依赖项

Android 9 GSI 变更

搭载 Android 9 的设备必须使用 Android 9 GSI,Android 9 GSI 与早期 GSI 相比存在以下主要变化:

  • 合并 GSI 和模拟器。GSI 是根据模拟器产品(例如,aosp_arm64aosp_x86 等)的系统映像编译的。
  • System-as-root。在以前的 Android 版本中,不支持 A/B 更新的设备可以在 /system 目录下装载系统映像。在 Android 9 中,系统映像的 root 作为设备的 root 装载。
  • 64 位 binder 接口。在 Android 8.x 中,32 位 GSI 使用 32 位 binder 接口。Android 9 不支持 32 位 binder 接口,因此 32 位 GSI 和 64 位 GSI 都使用 64 位 binder 接口。
  • 强制执行 VNDK。在 Android 8.1 中,VNDK 是可选的。在 Android 9 中,VNDK 是强制性的,这意味着 BOARD_VNDK_RUNTIME_DISABLE 不可设置 (BOARD_VNDK_RUNTIME_DISABLE := # must not be set)。
  • 兼容的系统属性。Android 9 支持对兼容的系统属性进行访问检查:PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE := true

要通过 cts-on-gsi 测试搭载 Android 9 的设备,请使用 Android 9 GSI 的编译目标

Android 9 旧版 GSI 变更

升级到 Android 9 的设备可以使用名称带后缀 _ab_a 的旧版 GSI 产品(例如,aosp_arm64_abaosp_x86_a)。此 GSI 支持以下升级用例:

  • 具有 Android 8.1 供应商接口实现的设备
  • 更新到 Android 9 供应商接口实现的设备

旧版 GSI 是从 Android 9 源代码树编译的,但包含以下针对升级设备的向后兼容配置:

  • 非 system-as-root。不支持系统作为 root 的设备可以继续使用 _a 产品(例如 aosp_arm_a)。
  • 32 位用户空间 + 32 位 binder 接口。32 位 GSI 可以继续使用 32 位 binder 接口。
  • 8.1 VNDK。设备可以使用随附的 8.1 VNDK。
  • 装载目录。一些旧版设备使用目录作为装载指针(例如,/bluetooth/firmware/radio/persist 等)。

要通过 cts-on-gsi 测试升级到 Android 9 的设备,请使用旧版 GSI 的编译目标

Android 9 Keymaster 变更

在早期版本的 Android 中,实现 Keymaster 3 或更早版本的设备需要验证并确保运行系统报告的版本信息(ro.build.version.releasero.build.version.security_patch)与引导加载程序报告的版本信息匹配。此类信息通常可以从引导映像标头中获取。

在 Android 9 中,为了让供应商引导 GSI,已经更改了此要求:具体来说,Keymaster 不应该执行验证,因为 GSI 报告的版本信息可能与供应商的引导加载程序报告的版本信息不匹配。对于实现 Keymaster 3 或更低版本的设备,供应商必须修改 Keymaster 实现以跳过验证(或升级到 Keymaster 4)。有关 Keymaster 的详细信息,请参阅由硬件支持的 Keystore

供应商二进制文件和 VNDK 依赖项

升级到 Android 9 的设备具有不同的升级路径,具体取决于设备上使用的供应商二进制文件的版本以及用于编译设备的 VNDK 相关配置。下表总结了针对升级设备的旧版 GSI 支持情况:

用例 供应商二进制文件版本 BOARD_VNDK_VERSION BOARD_VNDK_RUNTIME_DISABLE 旧版 GSI 系统二进制文件版本 旧版 GSI 支持
0 8.0 (任何) (不适用) 9
1.a 8.1 (空) (任何) 9
1.b 8.1 current true 9
2 8.1 current (空) 9
3 9 current true 9
4 9 current (空) 9

最常见的受支持用例是 2,其中旧版 GSI 支持运行 Android 8.1 且使用 BOARD_VNDK_VERSION 进行编译(而未通过设置 BOARD_VNDK_RUNTIME_DISABLE 进行编译,即,未停用运行时强制执行)的设备。

两个不受支持的用例是 1.a 和 1.b,其中旧版 GSI 不支持运行 Android 8.1 且未使用 BOARD_VNDK_VERSION 或通过设置 BOARD_VNDK_RUNTIME_DISABLE 进行编译(即,运行时强制执行已停用)的设备。这些设备不受支持,因为它们的供应商二进制文件依赖于 Android 8.1 非 VNDK 共享库,这些库未包含在旧版 GSI 中。

要使这些设备与旧版 GSI 兼容,供应商必须执行以下操作之一:

  • 启用 BOARD_VNDK_VERSION,但未设置 BOARD_VNDK_RUNTIME_DISABLE(用例 2)



  • 移植/升级供应商二进制文件,以便依赖于 Android 9 中的共享库(用例 3 和用例 4)。

编译 GSI

自 Android 9 开始,每个 Android 版本都在 AOSP 上拥有一个名为 DESSERT-gsi 的 GSI 分支(例如,pie-gsi 是 Android 9 的 GSI 分支)。GSI 分支包含应用了所有安全补丁程序GSI 补丁程序 的 Android 内容。

要编译 GSI,请从 GSI 分支进行下载,然后选择 GSI 编译目标,从而设置 Android 源代码树。请根据以下编译目标表确定设备应使用哪个 GSI 版本。编译完成后,GSI 便会成为系统映像(例如 system.img)并显示在输出文件夹 out/target/product/generic_arm64_ab 中。编译还会输出 vbmeta.img;对于使用 Android 验证启动的设备,您可以将其用于停用验证启动。

示例:以下命令可在 GSI 分支 pie-gsi 上编译旧版 GSI 编译目标 aosp_arm64_ab-userdebug

$ repo init -u https://android.googlesource.com/platform/manifest -b pie-gsi
$ repo sync -cq
$ source build/envsetup.sh
$ lunch aosp_arm64_ab-userdebug
$ make -j4

Android 9 GSI 编译目标

以下 GSI 编译目标适用于搭载 Android 9 的设备。由于架构之间的差异减少,Android 9 仅包含四个 GSI 产品。

GSI 名称 CPU 架构 Binder 接口位数 System-as-root 产品名称
aosp_arm ARM 64 Y aosp_arm-userdebug
aosp_arm64 ARM64 64 Y aosp_arm64-userdebug
aosp_x86 x86 64 Y aosp_x86-userdebug
aosp_x86_64 x86-64 64 Y aosp_x86_64-userdebug

Android 9 旧版 GSI 编译目标

以下旧版 GSI 编译目标适用于升级到 Android 9 的设备。旧版 GSI 名称包含后缀 _ab_a,以区别于 Android 9 GSI 名称。

GSI 名称 CPU 架构 Binder 接口位数 System-as-root 产品名称
aosp_arm_a ARM 32 N aosp_arm_a-userdebug
aosp_arm_ab ARM 32 Y aosp_arm_ab-userdebug
**NA ARM 64 N
aosp_arm_64b_ab ARM 64 Y aosp_arm_64b_ab-userdebug
aosp_arm64_a ARM64 64 N aosp_arm64_a-userdebug
aosp_arm64_ab ARM64 64 Y aosp_arm64_ab-userdebug
aosp_x86_a x86 32 N aosp_x86_a-userdebug
aosp_x86_ab x86 32 Y aosp_x86_ab-userdebug
**NA x86 64 N
**NA x86 64 Y
aosp_x86_64_a x86-64 64 N aosp_x86_64_a-userdebug
aosp_x86_64_ab x86-64 64 Y aosp_x86_64_ab-userdebug
**可以根据要求添加

刷写 GSI

Android 设备可能具有不同的设计,因此不可能通过单个命令或单组指令将 GSI 刷写到特定设备上。请使用以下常规步骤作为指南:

  1. 确保设备具备以下条件:
    • 支持 HIDL-HAL 接口。
    • 用于解锁设备的方法(以便能够使用 fastboot 对其进行刷写)。
    • 用于停用验证启动的方法(例如 vboot 1.0AVB 等)。
    • 解锁设备,使其可通过 fastboot 进行刷写。
  2. 停用验证启动。
  3. 清空当前系统分区,然后将 GSI 刷写到系统分区。
  4. 擦除用户数据,并清除来自其他必要分区的数据(例如元数据)。
  5. 重新启动设备。

例如,要将 GSI 刷写到 Pixel 2 设备,请执行以下操作:

  1. 启动到引导加载程序模式,然后解锁引导加载程序
  2. 通过刷写 vbmeta.img 来停用验证启动 (AVB):
    $ fastboot flash vbmeta vbmeta.img
  3. 清空系统分区,然后将 GSI 刷写到系统分区:
    $ fastboot erase system
    $ fastboot flash system system.img
    
  4. 擦除用户数据并清除其他必要分区的数据:
    $ fastboot -w
  5. 重新启动:
    $ fastboot reboot

为改进 GSI 积极贡献力量

Android 欢迎您为 GSI 开发贡献自己的力量。您可以通过以下方式参与开发并帮助改进 GSI:

  • 创建 GSI 补丁程序。由于 DESSERT-gsi不是开发分支,并且仅接受从 AOSP master 分支择优挑选的补丁程序,因此要提交 GSI 补丁程序,您必须:
    1. 将补丁程序提交到 AOSP master 分支。
    2. 择优挑选要提交到 DESSERT-gsi 的补丁程序。
    3. 提交错误,以便让择优挑选的补丁程序接受审核。
  • 报告 GSI 错误或提出其他建议。查看报告错误中的说明,然后浏览或提交 GSI 错误(在“平台”表中查找“常规系统映像”)。