通用系统映像

通用系统映像 (GSI) 是指已针对 Android 设备调整配置的系统映像。GSI 被视为“纯 Android”实现,它包含未经修改的 Android 开源项目 (AOSP) 代码,任何搭载 Android 9 或更高版本的 Android 设备都能顺利运行这种代码。

GSI 用于运行 VTS 和 CTS-on-GSI 测试。为确保运行最新版 Android 的设备正确实现供应商接口,您需要将 Android 设备的系统映像替换为 GSI,然后使用供应商测试套件 (VTS)兼容性测试套件 (CTS) 来测试设备。

使用 GSI 之前,请先阅读下面几部分内容,详细了解 GSI 配置(和允许的差异)、类型。准备好使用 GSI 后,请为目标设备下载并构建 GSI,然后将 GSI 刷写到 Android 设备上。

GSI 配置和差异

当前的 Android GSI 具有以下配置:

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

  • CPU 架构 - 支持不同的 CPU 指令(ARM、x86 等)和 CPU 位数(32 位或 64 位)。

适用于 Treble 合规性测试的 GSI 目标

合规性测试中使用的 GSI 取决于设备发布时搭载的 Android 版本。

设备类型 build 目标
发布时搭载 Android 15 的设备 gsi_$arch-user(已签名)
发布时搭载 Android 14 的设备 gsi_$arch-user(已签名)
发布时搭载 Android 13 的设备 gsi_$arch-user(已签名)
发布时搭载 Android 12L 的设备 gsi_$arch-user(已签名)
发布时搭载 Android 12 的设备 gsi_$arch-user(已签名)
发布时搭载 Android 11 的设备 gsi_$arch-user(已签名)

所有 GSI 都基于 Android 12 代码库构建而成,并且每个 CPU 架构都有一个对应的 GSI 二进制文件(请参阅构建 GSI 中的构建目标列表)。

Android 12 GSI 变更

发布时搭载或更新到 Android 12 的设备必须使用 Android 12 GSI 进行合规性测试。此 GSI 与早期 GSI 相比存在以下主要变更:

  • 目标名称 - 合规性测试的 GSI 目标名称更改为 gsi_$arch。目标名称为 aosp_$arch 的 GSI 会保留供 Android 应用开发者使用。测试计划 CTS-on-GSI 也针对供应商接口测试进行了缩减。
  • 旧版 GSI 会被逐步淘汰 - GSI 12 移除了适用于未完全支持 Treble 的 Android 8.0 或 8.1 设备的权宜解决方法。
  • Userdebug SEPolicy - GSI gsi_$arch 包含 userdebug_plat_sepolicy.cil。刷写 OEM 专用 vendor_boot-debug.imgboot-debug.img 时,/system/bin/init 将从 GSI system.img 中加载 userdebug_plat_sepolicy.cil。如需了解详情,请参考使用调试 Ramdisk 进行 VTS 测试

Android 11 GSI 变更

发布时搭载或更新到 Android 11 的设备必须使用 Android 11 GSI 进行合规性测试。此 GSI 与早期 GSI 相比存在以下主要变更:

  • system_ext 内容 - Android 11 定义了一个新分区 system_ext。GSI 会将系统扩展内容放在文件夹 system/system_ext 下。
  • APEXes - GSI 既包含扁平化 APEX,又包含已压缩的 APEX。使用哪种 APEX 由运行时 vendor 分区中的系统属性 ro.apex.updatable 确定。如需了解详情,请参阅配置系统以支持 APEX 更新

Android 10 GSI 变更

发布时搭载或更新到 Android 10 的设备必须使用 Android 10 GSI 进行合规性测试。此 GSI 与早期 GSI 相比存在以下主要变更:

  • User build - 此 GSI 的 user build 基于 Android 10。在 Android 10 中,user build 版的 GSI 可用在 CTS-on-GSI/VTS 合规性测试中。如需了解详情,请参阅使用调试 Ramdisk 进行 VTS 测试
  • 非稀疏格式 - 目标为 aosp_$arch 的 GSI 采用非稀疏格式构建而成。如果需要,您可以使用 img2simg 将非稀疏 GSI 转换为稀疏格式。
  • system-as-root - 名为 aosp_$arch_a 的旧版 GSI build 目标已被淘汰。对于从 Android 8 或 8.1 升级至 Android 10 且使用 ramdisk 和 non-system-as-root 的设备,请使用旧版 GSI aosp_$arch_ab。ramdisk 中升级后的 init 支持采用 system-as-root 布局的 OEM system.img。
  • 启动时验证 - 使用 GSI 时,您只需解锁设备,无需停用“启动时验证”功能。

Android 9 GSI 变更

发布时搭载或更新到 Android 9 的设备必须使用 Android 9 GSI 进行合规性测试。此 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_VERSION
  • 兼容的系统属性 - Android 9 支持对兼容的系统属性进行访问检查:PRODUCT_COMPATIBLE_PROPERTY_OVERRIDE := true

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,请参阅由硬件支持的密钥库

下载 GSI

您可以从 AOSP 持续集成 (CI) 网站 ci.android.com 下载预构建 GSI。如果适用于您硬件平台的 GSI 无法下载,请参阅以下部分,详细了解如何针对特定目标构建 GSI。

构建 GSI

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

如需构建 GSI,请从 GSI 分支进行下载,然后选择 GSI build 目标,设置 Android 源代码树。您可以根据以下构建目标表来确定哪个 GSI 版本适合您的设备。构建完成后,GSI 便会成为系统映像(即 system.img)并显示在输出文件夹 out/target/product/generic_arm64 下。

例如,如需在 GSI 分支 android12-gsi 上构建 GSI build 目标 gsi_arm64-userdebug,请运行以下命令。

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

Android GSI 构建目标

以下 GSI build 目标适用于发布时搭载 Android 9 或更高版本的设备。

GSI 名称 CPU 架构 Binder 接口位数 System-as-root build 目标
gsi_arm ARM 32 gsi_arm-user
gsi_arm-userdebug
gsi_arm64 ARM64 64 gsi_arm64-user
gsi_arm64-userdebug
gsi_x86 x86 32 gsi_x86-user
gsi_x86-userdebug
gsi_x86_64 x86-64 64 gsi_x86_64-user
gsi_x86_64-userdebug

刷写 GSI 的要求

Android 设备可能具有不同的设计,因此无法通过通用命令或通用指令组将 GSI 刷写到所有设备上。您可以向 Android 设备的制造商索要详细的刷写说明,也可以参考以下常规步骤:

  1. 确保设备具备以下条件:
    • 支持 Treble
    • 用于解锁设备的方法(以便能够使用 fastboot 对其进行刷写)
    • 使其可通过 fastboot 进行刷写的已解锁状态(为确保您拥有最新版本的 fastboot,请基于 Android 源代码树进行构建。)
  2. 清空当前系统分区,然后将 GSI 刷写到系统分区。
  3. 擦除用户数据,并清除来自其他必要分区(例如,用户数据分区和 system 分区)的数据。
  4. 重新启动设备。

例如,如需将 GSI 刷写到任何 Pixel 设备,请执行以下操作:

  1. 启动到 fastboot 模式,然后解锁引导加载程序
  2. 支持 fastbootd 的设备还需要通过以下命令启动进入 fastbootd
    $ fastboot reboot fastboot
  3. 清空系统分区,然后将 GSI 刷写到系统分区:
    $ fastboot erase system
    $ fastboot flash system system.img
  4. 擦除用户数据,并清除来自其他必要分区的数据(例如,用户数据分区和 system 分区):
    $ fastboot -w
  5. 重新启动到引导加载程序:
    $ fastboot reboot-bootloader
  6. 在刷写提供的 vbmeta 时停用启动时验证:
    $ fastboot --disable-verification flash vbmeta vbmeta.img
  7. Reboot:
    $ fastboot reboot
在具有较小系统分区的 Android 10 或更高版本设备上,刷写 GSI 时可能会出现以下错误消息:
    Resizing 'system_a'    FAILED (remote: 'Not enough space to resize partition')
    fastboot: error: Command failed
您可以使用以下命令删除产品分区并为系统分区释放空间。这可以为刷写 GSI 提供额外的空间:
$ fastboot delete-logical-partition product_a
后缀 _a 应与 system 分区的槽位 ID 匹配,例如本示例中的 system_a

为 GSI 贡献自己的力量

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

  • 创建 GSI 补丁。DESSERT-gsi 不是开发分支,并且仅接受从 AOSP main 分支择优挑选的补丁,因此要提交 GSI 补丁,您必须:
    1. 将补丁提交到 AOSP main 分支。
    2. 择优挑选要提交到 DESSERT-gsi 的补丁。
    3. 提交 bug,让择优挑选的补丁接受审核。
  • 报告 GSI bug 或提出其他建议。查看报告 bug 中的说明,然后浏览或提交 GSI bug

提示

使用 adb 更改导航栏模式

使用 GSI 启动时,导航栏模式通过供应商替换配置。您可以通过在运行时过程中运行以下 adb 命令来更改导航栏模式:

adb exec-out cmd overlay enable-exclusive com.android.internal.systemui.navbar.mode

其中,mode 可以是 threebuttontwobuttongestural 等。