搭载 Android 9 的所有新设备都必须使用 system-as-root(BOARD_BUILD_SYSTEM_ROOT_IMAGE必须为 true),它可以将ramdisk.img合并到system.img,而后者会反过来再作为 rootfs 进行装载。对于要升级到 Android 9的设备,使用system-as-root并非强制要求。本文档介绍了system-as-root、列出了dm-verity支持的内核要求(包括所依赖的内核补丁程序),还提供了一些设置示例。

关于系统专用 OTA

当前 Android 生态系统支持两种类型的分区布局:

  • 在 A/B 分区架构中,system 分区作为 rootfs 装载。
  • 在非 A/B 分区架构中,/boot 分区中的 ramdisk.img 会被加载到内存中(反过来再作为 rootfs 进行装载),而 system 分区则在 /system 中装载。

在 Android 8.0 中进行的架构更改(在 Project Treble 项目中)支持系统专用 OTA(其中 system.img 可在不更改其他分区的情况下跨主要 Android 版本进行更新)。不过,对于非 A/B 设备来说,由于 ramdisk.img 位于 /boot 分区中,因此它无法使用 Android 8.x 架构通过系统专用 OTA 进行更新。这样一来,旧的 ramdisk.img 可能不适用于新的 system.img,具体原因如下:
ramdisk.img 中较旧的 /init 可能无法解析 /system 上的 *.rc 文件。
ramdisk 包含 /init.rc,它也可能已过期(相较于新 /system 所要求的)。

为确保系统专用 OTA 按预期运行,Android 9 中必须使用 system-as-root。非 A/B 设备必须从 ramdisk 分区布局切换到 system-as-root 分区布局;A/B 设备已被要求使用 system-as-root,因此无需做出改动。

关于 A/B 设备和非 A/B 设备

A/B 设备和非 A/B 设备的分区详情如下:

A/B 设备 非 A/B 设备
每个分区(userdata 除外)都包含两个副本(插槽): 每个分区都包含一个副本,无其他备份分区。
/boot_a /boot
/boot_b /system
/system_a /vendor
/system_b
/vendor_a
/vendor_b

关于 system-as-root

在 Android 9 中,非 A/B 设备应采用 system-as-root,以便通过系统专用 OTA 进行更新。

注意:如果设备使用的是 A/B 分区架构,则无需做出任何改动。

注意:如果设备使用的是 A/B 分区架构,则无需做出任何改动。与将 /boot 改编为recovery分区的A/B设备不同,非A/B设备必须保留单独的/recovery 分区,因为它们没有后备插槽分区(例如,从 boot_aboot_b)。如果在非A/B 设备上移除 /recovery并使其与A/B架构类似,那么在/boot分区更新失败时,恢复模式可能会遭到破坏。因此,对于非A/B设备来说,/recovery分区必须作为单独的分区存在(不同于非A/B设备的/boot),这意味着恢复映像将继续延迟更新(即如同 Android 9 之前的设备中那样)。

非 A/B 设备在使用 Android 9 前后的分区布局差异:

组件 映像 ramdisk(9 之前) system-as-root(9 之后)
映像内容 boot.img 包含内核和 ramdisk.img:

ramdisk.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
仅包含正常启动内核。
recovery.img 包含恢复内核和 recovery-ramdisk.img。
system.img 包含以下内容:

system.img
  -/
    - bin/
    - etc
    - vendor -> /vendor
    - ...
包含原始 system.img 和 ramdisk.img 的合并内容:

system.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/
      - bin/
      - etc/
      - vendor -> /vendor
      - ...
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
分区布局
  1. /boot
  2. /system
  3. /recovery
  4. /vendor 等
  1. /boot
  2. /system
  3. /recovery
  4. /vendor 等

设置 dm-verity

在 system-as-root 中,内核必须使用 dm-verity 在 /(装载点)下装载 system.img。AOSP 支持 system.img 的下列 dm-verity 实现:

  • 对于 vboot 1.0,内核必须在 /system上解析 Android 专用元数据,然后转换为 dm-verity 参数以设置 dm-verity。需要这些内核补丁程序。
  • 对于 vboot 2.0 (AVB),引导加载程序必须先整合 external/avb/libavb,external/avb/libavb随后会解析/system的哈希树描述符),然后将其转换为 dm-verity 参数,最后再通过内核命令行将这些参数传递给内核(/system的哈希树描述符可能位于 /vbmeta/system 本身上)。

需要下列内核补丁程序:
– https://android-review.googlesource.com/#/c/kernel/common/+/158491/

注意:您也可以在 external/avb/contrib/linux/{4.4,4.9,etc.}/*上找到上述AVB专用内核补丁程序文件。

下面是来自真实设备的示例,显示的是内核命令行中 system-as-root 的 dm-verity 相关设置:

vboot 1.0
ro root=/dev/dm-0 rootwait skip_initramfs init=/init
dm="system none ro,0 1 android-verity /dev/sda34"
veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f
vboot 2.0 (AVB)
ro root=/dev/dm-0 rootwait  skip_initramfs init=/init

dm="1 vroot none ro 1,0 5159992 verity 1
PARTUUID=00000016-0000-0000-0000-000000000000
PARTUUID=00000016-0000-0000-0000-000000000000 4096 4096 644999 644999
sha1 d80b4a8be3b58a8ab86fad1b498640892d4843a2
8d08feed2f55c418fb63447fec0d32b1b107e42c 10 restart_on_corruption
ignore_zero_blocks use_fec_from_device
PARTUUID=00000016-0000-0000-0000-000000000000 fec_roots 2 fec_blocks
650080 fec_start 650080"

特定于设备的根文件夹

借助 system-as-root,在设备上刷写常规系统映像(GSI)之后(以及在运行供应商测试套件测试之前),任何通过BOARD_ROOT_EXTRA_FOLDERS添加的特定于设备的根文件夹都将消失,因为整个根目录内容已被system-as-root GSI取而代之。如果存在对特定于设备的根文件夹的依赖性(例如此类文件夹作装载点),则移除这些文件夹可能会导致设备无法启动。

要避免出现此问题,请不要使用BOARD_ROOT_EXTRA_FOLDERS来添加特定于设备的根文件夹(此类文件夹将来可能会被弃用)。如果您需要指定特定于设备的装载点,请使用/mnt/vendor/<mount point>(已在这些更改列表中添加)。这些特定于供应商的装载点可在fstab设备树(适用于第一阶段的装载)和/vendor/etc/fstab.{ro.hardware}文件中直接指定,而无需进行额外设置(因为fs_mgr将在/mnt/vendor/*下自动创建它们)。

Android 9 安卓P System-as-root简介
Tagged on:

发表评论

邮箱地址不会被公开。 必填项已用*标注