搭载 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.im
g 可能不适用于新的 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_a
→ boot_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) ... | |
分区布局 | 无 |
|
|
设置 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
本身上)。
需要下列内核补丁程序:
注意:您也可以在 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/*
下自动创建它们)。