在 Android 12 中,通用 boot 镜像(称为通用内核镜像 (GKI))包含通用 ramdisk 和 GKI 内核。
对于搭载 Android 13 发布的设备,通用 ramdisk 将从 boot 镜像中移除,并放置在单独的 init_boot 镜像中。此更改使 boot 镜像仅包含 GKI 内核。
对于继续使用 Android 12 或更旧内核版本的升级设备,通用 ramdisk 仍保留在原来的位置,无需新的 init_boot 镜像。
要构建通用 ramdisk,请将供应商特定的资源移出 ramdisk,以便通用 ramdisk 仅包含第一阶段 init 和包含时间戳信息的属性文件。
在以下设备上:
不使用专用
recovery分区,所有恢复位都从通用 ramdisk 移至vendor_bootramdisk。使用专用
recovery分区,则无需更改recoveryramdisk,因为recoveryramdisk 是自包含的。
架构
以下图表说明了运行 Android 12 及更高版本的设备的架构。搭载 Android 13 推出的设备具有新的 init_boot 镜像,其中包含通用 ramdisk。从 Android 12 升级到 Android 13 的设备使用的架构与 Android 12 相同。
搭载 Android 13 推出,无专用恢复
图 1. 搭载或升级到 Android 13 的设备,使用 GKI,无专用恢复。
搭载 Android 13 推出,专用和 A/B 恢复(专用 ramdisk)
图 2. 搭载或升级到 Android 13 的设备,使用 GKI,专用和 A/B 恢复。
如果设备具有 recovery_a 和 recovery_b 分区,请参考此图。
搭载 Android 13 推出,专用和非 A/B 恢复(专用 ramdisk)
图 3. 搭载或升级到 Android 13 的设备,使用 GKI,专用和非 A/B 恢复。
如果设备具有名为 recovery 且没有槽后缀的分区,请参考此图。
搭载或升级到 Android 12,无专用恢复
图 4. 搭载或升级到 Android 12 的设备,使用 GKI,无专用恢复。
搭载或升级到 Android 12,专用和 A/B 恢复(专用 ramdisk)
图 5. 搭载或升级到 Android 12 的设备,使用 GKI,专用和 A/B 恢复。
如果设备具有 recovery_a 和 recovery_b 分区,请参考此图。
搭载或升级到 Android 12,专用和非 A/B 恢复(专用 ramdisk)
图 6. 搭载或升级到 Android 12 的设备,使用 GKI,专用和非 A/B 恢复。
如果设备具有名为 recovery 且没有槽后缀的分区,请参考此图。
升级到 Android 12,recovery-as-boot(recovery-as-ramdisk)
图 7. 升级到 Android 12 的设备,无 GKI,recovery-as-boot。
升级到 Android 12,专用恢复(专用 ramdisk)
图 8. 升级到 Android 12 的设备,无 GKI,专用恢复。
启动镜像内容
Android 启动镜像包含以下内容。
init_boot镜像为搭载 Android 13 推出的设备添加- 标头版本 V4
- 通用 ramdisk 镜像
通用
boot镜像vendor_boot镜像(有关详情,请参阅 供应商启动分区)vendor_boot标头- 设备特定的
cmdline(BOARD_KERNEL_CMDLINE)
- 设备特定的
vendor_bootramdisk 镜像lib/modules- 恢复资源(如果没有专用恢复)
dtb镜像
recovery镜像- 标头版本 V2
- 设备特定的恢复
cmdline(如果需要) - 对于非 A/B 恢复分区,标头的内容必须是独立的;请参阅 恢复镜像。例如
cmdline未连接到boot和vendor_bootcmdline。- 标头指定恢复 DTBO(如果需要)。
- 对于 A/B 恢复分区,内容可以连接或从
boot和vendor_boot推断。例如 cmdline连接到boot和vendor_bootcmdline。- DTBO 可以从
vendor_boot标头推断。
- 设备特定的恢复
recoveryramdisk 镜像- 恢复资源
- 对于非 A/B 恢复分区,ramdisk 的内容必须是独立的;请参阅 恢复镜像。例如
lib/modules必须包含启动恢复模式所需的所有内核模块- 恢复 ramdisk 必须包含
init。 - 对于 A/B 恢复分区,恢复 ramdisk 会预先添加到通用和
vendor_bootramdisk,因此无需独立。例如 lib/modules可能仅包含启动恢复模式所需的其他内核模块,以及vendor_bootramdisk 中的内核模块。- 位于
/init的符号链接可能存在,但会被启动镜像中第一阶段的/init二进制文件所取代。
- 标头版本 V2
通用 ramdisk 镜像内容
通用 ramdisk 包含以下组件。
initsystem/etc/ramdisk/build.propro.PRODUCT.bootimg.* build属性- 挂载点的空目录:
debug_ramdisk/、mnt/、dev/、sys/、proc/、metadata/ first_stage_ramdisk/- 挂载点的重复空目录:
debug_ramdisk/、mnt/、dev/、sys/、proc/、metadata/
- 挂载点的重复空目录:
启动镜像集成
构建标志控制如何构建 init_boot、boot、recovery 和 vendor_boot 镜像。布尔值板变量的值必须是字符串 true 或为空(默认值)。
TARGET_NO_KERNEL。此变量指示构建是否使用预构建的启动镜像。如果此变量设置为true,则将BOARD_PREBUILT_BOOTIMAGE设置为预构建启动镜像的位置 (BOARD_PREBUILT_BOOTIMAGE:= device/${company}/${board}/boot.img)BOARD_USES_RECOVERY_AS_BOOT。此变量指示设备是否使用recovery镜像作为boot镜像。使用 GKI 时,此变量为空,恢复资源应移至vendor_boot。BOARD_USES_GENERIC_KERNEL_IMAGE。此变量指示板是否使用 GKI。此变量不影响系统属性或PRODUCT_PACKAGES。这是板级 GKI 开关;以下所有变量都受此变量限制。
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT。此变量控制是否将 ramdisk 恢复资源构建到vendor_boot。设置为
true时,恢复资源仅构建到vendor-ramdisk/,而不构建到recovery/root/。为空时,恢复资源仅构建到
recovery/root/,而不构建到vendor-ramdisk/。
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT。此变量控制是否将 GSI AVB 密钥构建到vendor_boot。设置为
true时,如果BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT已设置,GSI AVB 密钥将构建到
$ANDROID_PRODUCT_OUT/vendor-ramdisk/first_stage_ramdisk/avb。未设置,GSI AVB 密钥将构建到
$ANDROID_PRODUCT_OUT/vendor-ramdisk/avb。
为空时,如果
BOARD_RECOVERY_AS_ROOT已设置,GSI AVB 密钥将构建到
$ANDROID_PRODUCT_OUT/recovery/root/first_stage_ramdisk/avb。未设置,GSI AVB 密钥将构建到
$ANDROID_PRODUCT_OUT/ramdisk/avb。
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE。此变量控制recovery镜像是否包含内核。搭载 Android 12 并使用 A/Brecovery分区推出的设备必须将此变量设置为true。搭载 Android 12 并使用非 A/B 推出的设备必须将此变量设置为false,以保持恢复镜像的自包含性。BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES。此变量控制是否将$OUT/boot*.img复制到目标文件下的IMAGES/。aosp_arm64必须将此变量设置为true。其他设备必须将此变量留空。
BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE。此变量控制是否生成init_boot.img并设置大小。设置后,通用 ramdisk 会添加到init_boot.img而不是boot.img,并且需要设置BOARD_AVB_INIT_BOOT*变量以用于 链接的 vbmeta。
允许的组合
| 组件或变量 | 升级不带恢复分区的设备 | 升级带恢复分区的设备 | 搭载不带恢复分区的设备推出 | 搭载带 A/B 恢复分区的设备推出 | 搭载带非 A/B 恢复分区的设备推出 | aosp_arm64 |
|---|---|---|---|---|---|---|
包含 boot |
是 | 是 | 是 | 是 | 是 | 是 |
包含 init_boot (Android 13) |
否 | 否 | 是 | 是 | 是 | 是 |
包含 vendor_boot |
可选 | 可选 | 是 | 是 | 是 | 否 |
包含 recovery |
否 | 是 | 否 | 是 | 是 | 否 |
BOARD_USES_RECOVERY_AS_BOOT |
true |
空 | 空 | 空 | 空 | 空 |
BOARD_USES_GENERIC_KERNEL_IMAGE |
空 | 空 | true |
true |
true |
true |
PRODUCT_BUILD_RECOVERY_IMAGE |
空 | true 或空 |
空 | true 或空 |
true 或空 |
空 |
BOARD_RECOVERYIMAGE_PARTITION_SIZE |
空 | > 0 | 空 | > 0 | > 0 | 空 |
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT |
空 | 空 | true |
空 | 空 | 空 |
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT |
空 | 空 | true |
true |
true |
空 |
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE |
空 | 空 | 空 | true |
空 | 空 |
BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES |
空 | 空 | 空 | 空 | 空 | true |
具有专用 recovery 分区的设备可以将 PRODUCT_BUILD_RECOVERY_IMAGE 设置为 true 或空。对于这些设备,如果设置了 BOARD_RECOVERYIMAGE_PARTITION_SIZE,则会构建 recovery 镜像。
为启动启用链接的 vbmeta
必须为 boot 和 init_boot 镜像启用链接的 vbmeta。指定以下内容
BOARD_AVB_BOOT_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem
BOARD_AVB_BOOT_ALGORITHM := SHA256_RSA4096
BOARD_AVB_BOOT_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_BOOT_ROLLBACK_INDEX_LOCATION := 2
BOARD_AVB_INIT_BOOT_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_INIT_BOOT_ALGORITHM := SHA256_RSA2048
BOARD_AVB_INIT_BOOT_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_INIT_BOOT_ROLLBACK_INDEX_LOCATION := 3
有关示例,请参阅此更改。
System-as-root
使用 GKI 的设备不支持 System-as-root。在此类设备上,BOARD_BUILD_SYSTEM_ROOT_IMAGE 必须为空。使用动态分区的设备也不支持 System-as-root。
产品配置
使用通用 ramdisk 的设备必须安装允许安装到 ramdisk 的文件列表。为此,请在 device.mk 中指定以下内容
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
generic_ramdisk.mk 文件还可防止其他 makefile 意外地将其他文件安装到 ramdisk(请将此类文件移至 vendor_ramdisk)。
设置设备
搭载 Android 13 推出的设备、升级到 Android 12 的设备和搭载 Android 12 推出的设备之间的设置说明有所不同。Android 13 的设置方式与 Android 12 类似
升级到 Android 12 的设备
可以保留
BOARD_USES_RECOVERY_AS_BOOT的值。如果这样做,他们将使用旧版配置,并且新的构建变量必须为空。如果此类设备可以将
BOARD_USES_RECOVERY_AS_BOOT设置为空。如果这样做,他们将使用新的配置。如果此类设备
搭载 Android 12 推出的设备必须将
BOARD_USES_RECOVERY_AS_BOOT设置为空并使用新的配置。如果此类设备
由于 aosp_arm64 仅构建 GKI(而非 vendor_boot 或恢复),因此它不是完整的目标。对于 aosp_arm64 构建配置,请参阅 generic_arm64。
选项 1:无专用恢复分区
没有 recovery 分区的设备在 boot 分区中包含通用 boot 镜像。vendor_boot ramdisk 包含所有恢复资源,包括 lib/modules(带有供应商内核模块)。在此类设备上,产品配置继承自 generic_ramdisk.mk。
设置 BOARD 值
设置以下值
BOARD_USES_RECOVERY_AS_BOOT :=
BOARD_USES_GENERIC_KERNEL_IMAGE := true
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT := true
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE :=
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT := true
Init 二进制文件和符号链接
vendor_boot ramdisk 可以包含 /init 到 /system/bin/init 的符号链接,以及位于 /system/bin/init 的 init_second_stage.recovery。但是,由于通用 ramdisk 连接在 vendor_boot ramdisk 之后,因此 /init 符号链接将被覆盖。当设备启动进入恢复模式时,需要 /system/bin/init 二进制文件来支持第二阶段 init。vendor_boot + 通用 ramdisk 的内容如下
/init(来自通用 ramdisk,从init_first_stage构建)/system/bin/init(来自vendor_ramdisk,从init_second_stage.recovery构建)
移动 fstab 文件
将安装到通用 ramdisk 的任何 fstab 文件移动到 vendor_ramdisk。有关示例,请参阅此更改。
安装模块
您可以将设备特定的模块安装到 vendor_ramdisk(如果您没有任何设备特定的模块要安装,请跳过此步骤)。
当模块安装到
/first_stage_ramdisk时,请使用模块的vendor_ramdisk变体。此模块应在init将根切换到/first_stage_ramdisk之后但在init将根切换到/system之前可用。有关示例,请参阅元数据校验和和Virtual A/B 压缩。当模块安装到
/时,请使用模块的recovery变体。此模块应在init将根切换到/first_stage_ramdisk之前可用。有关将模块安装到/的详细信息,请参阅第一阶段控制台。
第一阶段控制台
由于第一阶段控制台在 init 将根切换到 /first_stage_ramdisk 之前启动,因此您需要安装模块的 recovery 变体。默认情况下,这两个模块变体都安装到 build/make/target/product/base_vendor.mk,因此如果设备 makefile 从该文件继承,则无需显式安装 recovery 变体。
要显式安装恢复模块,请使用以下代码。
PRODUCT_PACKAGES += \
linker.recovery \
shell_and_utilities_recovery \
这可确保 linker、sh 和 toybox 安装到 $ANDROID_PRODUCT_OUT/recovery/root/system/bin,然后安装到 vendor_ramdisk 下的 /system/bin。
要添加第一阶段控制台所需的模块(例如,adbd),请使用以下代码。
PRODUCT_PACKAGES += adbd.recovery
这可确保指定的模块安装到 $ANDROID_PRODUCT_OUT/recovery/root/system/bin,然后安装到 vendor_ramdisk 下的 /system/bin。
元数据校验和
为了在第一阶段挂载期间支持 元数据校验和,不支持 GKI 的设备会安装以下模块的 ramdisk 变体。要添加对 GKI 的支持,请将模块移动到 $ANDROID_PRODUCT_OUT/vendor-ramdisk/first_stage_ramdisk/system/bin
PRODUCT_PACKAGES += \
linker.vendor_ramdisk \
resize2fs.vendor_ramdisk \
tune2fs.vendor_ramdisk \
有关示例,请参阅此变更列表。
Virtual A/B 压缩
为了支持 Virtual A/B 压缩,必须将 snapuserd 安装到 vendor_ramdisk。设备应从 virtual_ab_ota/compression.mk 继承,该文件会安装 snapuserd 的 vendor_ramdisk 变体。
启动过程的更改
启动进入恢复模式或 Android 的过程不会更改,但以下情况除外
- Ramdisk
build.prop移至/second_stage_resources,以便第二阶段init可以读取启动的构建时间戳。
由于资源从通用 ramdisk 移至 vendor_boot ramdisk,因此将通用 ramdisk 连接到 vendor_boot ramdisk 的结果不会更改。
使 e2fsck 可用
设备 makefile 可以从以下文件继承
virtual_ab_ota/launch_with_vendor_ramdisk.mk(如果设备支持 Virtual A/B 但不支持压缩)。virtual_ab_ota/compression.mk(如果设备支持 Virtual A/B 压缩)。
产品 makefile 安装 $ANDROID_PRODUCT_OUT/vendor-ramdisk/first_stage_ramdisk/system/bin/e2fsck。在运行时,第一阶段 init 将根切换到 /first_stage_ramdisk,然后执行 /system/bin/e2fsck。
选项 2a:专用和 A/B 恢复分区
对于具有 A/B recovery 分区的设备,请使用此选项;即,设备具有 recovery_a 和 recovery_b 分区。此类设备包括恢复分区可更新的 A/B 和 Virtual A/B 设备,具有以下配置
AB_OTA_PARTITIONS += recovery
vendor_boot ramdisk 包含 ramdisk 的供应商位和供应商内核模块,包括以下内容
设备特定的
fstab文件lib/modules(包括供应商内核模块)
recovery ramdisk 包含所有恢复资源。在此类设备上,产品配置继承自 generic_ramdisk.mk。
设置 BOARD 值
为具有 A/B recovery 分区的设备设置以下值
BOARD_USES_RECOVERY_AS_BOOT :=
BOARD_USES_GENERIC_KERNEL_IMAGE := true
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT :=
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE := true
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT := true
Init 二进制文件和符号链接
recovery ramdisk 可以包含 /init -> /system/bin/init 符号链接,以及位于 /system/bin/init 的 init_second_stage.recovery。但是,由于启动 ramdisk 连接在 recovery ramdisk 之后,因此 /init 符号链接将被覆盖。当设备启动进入恢复模式时,需要 /system/bin/init 二进制文件来支持第二阶段 init。
当设备启动进入 recovery 时,recovery + vendor_boot + 通用 ramdisk 的内容如下
/init(来自 ramdisk,从init_first_stage构建)/system/bin/init(来自recoveryramdisk,从init_second_stage.recovery构建,并从/init执行)
当设备启动进入 Android 时,vendor_boot + 通用 ramdisk 的内容如下
/init(来自通用 ramdisk,从init_first_stage构建)
移动 fstab 文件
将安装到通用 ramdisk 的任何 fstab 文件移动到 vendor_ramdisk。有关示例,请参阅此更改。
安装模块
(可选)您可以将设备特定的模块安装到 vendor_ramdisk(如果您没有任何设备特定的模块要安装,请跳过此步骤)。Init 不切换根。模块的 vendor_ramdisk 变体会安装到 vendor_ramdisk 的根目录。有关将模块安装到 vendor_ramdisk 的示例,请参阅第一阶段控制台、元数据校验和和Virtual A/B 压缩。
第一阶段控制台
要安装模块的 vendor_ramdisk 变体,请使用以下代码
PRODUCT_PACKAGES += \
linker.vendor_ramdisk \
shell_and_utilities_vendor_ramdisk \
这可确保 linker、sh 和 toybox 安装到 $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin,然后安装到 vendor_ramdisk 下的 /system/bin。
要添加第一阶段控制台所需的模块(例如,adbd),请通过将相关补丁上传到 AOSP 来启用这些模块的 vendor_ramdisk 变体,然后使用以下代码,
PRODUCT_PACKAGES += adbd.vendor_ramdisk
这可确保指定的模块安装到 $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin。如果在恢复模式下加载 vendor_boot ramdisk,则该模块在 recovery 中也可用。如果未在恢复模式下加载 vendor_boot ramdisk,则设备可以选择也安装 adbd.recovery。
元数据校验和
为了在第一阶段挂载期间支持 元数据校验和,不支持 GKI 的设备会安装以下模块的 ramdisk 变体。要添加对 GKI 的支持,请将模块移动到 $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin
PRODUCT_PACKAGES += \
linker.vendor_ramdisk \
resize2fs.vendor_ramdisk \
tune2fs.vendor_ramdisk \
有关示例,请参阅此变更列表。
Virtual A/B 压缩
为了支持 Virtual A/B 压缩,必须将 snapuserd 安装到 vendor_ramdisk。设备应从 virtual_ab_ota/compression.mk 继承,该文件会安装 snapuserd 的 vendor_ramdisk 变体。
启动过程的更改
启动进入 Android 时,启动过程不会更改。vendor_boot + 通用 ramdisk 类似于现有的启动过程,只不过 fstab 从 vendor_boot 加载。由于 system/bin/recovery 不存在,first_stage_init 会将其作为正常启动来处理。
启动进入恢复模式时,启动过程会更改。恢复 + vendor_boot + 通用 ramdisk 类似于现有的恢复过程,但内核从 boot 镜像而不是从 recovery 镜像加载。恢复模式的启动过程如下。
引导加载程序启动,然后执行以下操作
- 将恢复 +
vendor_boot+ 通用 ramdisk 推送到/。(如果 OEM 通过将内核模块添加到BOARD_RECOVERY_KERNEL_MODULES在恢复 ramdisk 中复制内核模块),vendor_boot是可选的。) - 运行来自
boot分区的内核。
- 将恢复 +
内核将 ramdisk 挂载到
/,然后从通用 ramdisk 执行/init。第一阶段 init 启动,然后执行以下操作
- 设置
IsRecoveryMode() == true和ForceNormalBoot() == false。 - 从
/lib/modules加载供应商内核模块。 - 调用
DoFirstStageMount(),但由于IsRecoveryMode() == true而跳过挂载。(设备不会释放 ramdisk(因为/仍然相同),但会调用SetInitAvbVersionInRecovery()。) - 从
recoveryramdisk 中的/system/bin/init启动第二阶段 init。
- 设置
使 e2fsck 可用
设备 makefile 可以从以下文件继承
virtual_ab_ota/launch_with_vendor_ramdisk.mk(如果设备支持 Virtual A/B 但不支持压缩)。virtual_ab_ota/compression.mk(如果设备支持 Virtual A/B 压缩)。
产品 makefile 安装 $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin/e2fsck。在运行时,第一阶段 init 执行 /system/bin/e2fsck。
选项 2b:专用和非 A/B 恢复分区
对于具有非 A/B recovery 分区的设备,请使用此选项;即,设备具有名为 recovery 且没有槽后缀的分区。此类设备包括
- 非 A/B 设备;
- 恢复分区不可更新的 A/B 和 Virtual A/B 设备。(这种情况不常见。)
vendor_boot ramdisk 包含 ramdisk 的供应商位和供应商内核模块,包括以下内容
- 设备特定的
fstab文件 lib/modules(包括供应商内核模块)
recovery 镜像必须是自包含的。它必须包含启动恢复模式所需的所有资源,包括
- 内核镜像
- DTBO 镜像
lib/modules中的内核模块- 第一阶段 init 作为符号链接
/init -> /system/bin/init - 第二阶段 init 二进制文件
/system/bin/init - 设备特定的
fstab文件 - 所有其他恢复资源,包括
recovery二进制文件
在此类设备上,产品配置继承自 generic_ramdisk.mk。
设置 BOARD 值
为非 A/B 设备设置以下值
BOARD_USES_RECOVERY_AS_BOOT :=
BOARD_USES_GENERIC_KERNEL_IMAGE := true
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT :=
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE :=
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT := true
Init 二进制文件和符号链接
recovery ramdisk 必须包含 /init -> /system/bin/init 符号链接,以及位于 /system/bin/init 的 init_second_stage.recovery。当设备启动进入恢复模式时,需要 /system/bin/init 二进制文件来支持第一阶段和第二阶段 init。
当设备启动进入 recovery 时,recovery ramdisk 的内容如下
/init -> /system/bin/init(来自recoveryramdisk)/system/bin/init(来自recoveryramdisk,从init_second_stage.recovery构建,并从/init执行)
当设备启动进入 Android 时,vendor_boot + 通用 ramdisk 的内容如下
/init(来自 ramdisk,从init_first_stage构建)
移动 fstab 文件
将安装到通用 ramdisk 的任何 fstab 文件移动到 vendor_ramdisk 和 recovery ramdisk。有关示例,请参阅此更改。
安装模块
您可以将设备特定的模块安装到 vendor_ramdisk 和 recovery ramdisk(如果您没有任何设备特定的模块要安装,请跳过此步骤)。init 不切换根。模块的 vendor_ramdisk 变体会安装到 vendor_ramdisk 的根目录。模块的 recovery 变体会安装到 recovery ramdisk 的根目录。有关将模块安装到 vendor_ramdisk 和 recovery ramdisk 的示例,请参阅第一阶段控制台和元数据校验和。
第一阶段控制台
要安装模块的 vendor_ramdisk 变体,请使用以下代码
PRODUCT_PACKAGES += \
linker.vendor_ramdisk \
shell_and_utilities_vendor_ramdisk \
这可确保 linker、sh 和 toybox 安装到 $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin,然后安装到 vendor_ramdisk 下的 /system/bin。
要添加第一阶段控制台所需的模块(例如,adbd),请通过将相关补丁上传到 AOSP 来启用这些模块的 vendor_ramdisk 变体,然后使用以下代码,
PRODUCT_PACKAGES += adbd.vendor_ramdisk
这可确保指定的模块安装到 $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin。
要安装模块的 recovery 变体,请将 vendor_ramdisk 替换为 recovery
PRODUCT_PACKAGES += \
linker.recovery \
shell_and_utilities_recovery \
adbd.recovery \
元数据校验和
为了在第一阶段挂载期间支持 元数据校验和,不支持 GKI 的设备会安装以下模块的 ramdisk 变体。要添加对 GKI 的支持,请将模块移动到 $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin
PRODUCT_PACKAGES += \
linker.vendor_ramdisk \
resize2fs.vendor_ramdisk \
tune2fs.vendor_ramdisk \
为了在恢复模式下的第一阶段挂载期间支持元数据校验和,请启用这些模块的恢复变体并同时安装它们。
启动过程的更改
启动进入 Android 时,启动过程不会更改。vendor_boot + 通用 ramdisk 类似于现有的启动过程,只不过 fstab 从 vendor_boot 加载。由于 system/bin/recovery 不存在,first_stage_init 会将其作为正常启动来处理。
启动进入恢复模式时,启动过程不会更改。恢复 ramdisk 的加载方式与现有的恢复过程相同。内核从 recovery 镜像加载。恢复模式的启动过程如下。
引导加载程序启动,然后执行以下操作
- 将恢复 ramdisk 推送到
/。 - 运行来自
recovery分区的内核。
- 将恢复 ramdisk 推送到
内核将 ramdisk 挂载到
/,然后执行/init,这是来自recoveryramdisk 的/system/bin/init的符号链接。第一阶段 init 启动,然后执行以下操作
- 设置
IsRecoveryMode() == true和ForceNormalBoot() == false。 - 从
/lib/modules加载供应商内核模块。 - 调用
DoFirstStageMount(),但由于IsRecoveryMode() == true而跳过挂载。(设备不会释放 ramdisk(因为/仍然相同),但会调用SetInitAvbVersionInRecovery()。) - 从
recoveryramdisk 中的/system/bin/init启动第二阶段 init。
- 设置
启动镜像时间戳
以下代码是 boot 镜像时间戳文件的示例
####################################
# from generate-common-build-props
# These properties identify this partition image.
####################################
ro.product.bootimage.brand=Android
ro.product.bootimage.device=generic_arm64
ro.product.bootimage.manufacturer=unknown
ro.product.bootimage.model=AOSP on ARM64
ro.product.bootimage.name=aosp_arm64
ro.bootimage.build.date=Mon Nov 16 22:46:27 UTC 2020
ro.bootimage.build.date.utc=1605566787
ro.bootimage.build.fingerprint=Android/aosp_arm64/generic_arm64:S/MASTER/6976199:userdebug/test-keys
ro.bootimage.build.id=MASTER
ro.bootimage.build.tags=test-keys
ro.bootimage.build.type=userdebug
ro.bootimage.build.version.incremental=6976199
ro.bootimage.build.version.release=11
ro.bootimage.build.version.release_or_codename=S
ro.bootimage.build.version.sdk=30
# Auto-added by post_process_props.py
persist.sys.usb.config=none
# end of file