汎用ブート パーティション

Android 12 では、汎用カーネル イメージ(GKI)という汎用の boot イメージに、汎用 RAM ディスクと GKI カーネルが含まれています。

Android 13 を搭載してリリースされるデバイスの場合、汎用 RAM ディスクが boot イメージから削除され、別の init_boot イメージに配置されています。この変更により、boot イメージには GKI カーネルのみが残ります。

Android 12 以前のカーネル バージョンを引き続き使用するデバイスをアップグレードする場合、汎用 RAM ディスクは、新しい init_boot イメージを必要としない状態が維持されます。

汎用 RAM ディスクをビルドするには、ベンダー固有のリソースを RAM ディスクから移動して、汎用 RAM ディスクに第 1 ステージの init と、タイムスタンプ情報を含むプロパティ ファイルのみが含まれるようにします。

デバイスに応じて以下のようにします。

  • 専用の recovery パーティションを使用していないデバイスの場合、すべてのリカバリビットを汎用 RAM ディスクから vendor_boot RAM ディスクに移動します。

  • 専用の recovery パーティションを使用しているデバイスの場合、recovery RAM ディスクは自己完結しているため、recovery RAM ディスクの変更は必要ありません。

アーキテクチャ

次の図は、Android 12 以降を搭載したデバイスのアーキテクチャを示しています。Android 13 を搭載してリリースされるデバイスでは、汎用 RAM ディスクを含んでいる新しい init_boot イメージが追加されています。Android 12 から Android 13 にアップグレードするデバイスは、Android 12 と同じアーキテクチャを使用します。

Android 13 でリリース、専用のリカバリなし

デバイスのリリース / アップグレード、GKI あり、専用のリカバリなし

図 1. Android 13 でリリースまたは Android 13 にアップグレードするデバイス、GKI あり、専用のリカバリなし

Android 13 でリリース、専用の A/B リカバリ(専用の RAM ディスク)あり

デバイスのリリース / アップグレード、GKI あり、専用の A/B リカバリあり

図 2. Android 13 でリリースまたは Android 13 にアップグレードするデバイス、GKI あり、専用の A/B リカバリあり

デバイスに recovery_a パーティションと recovery_b パーティションがある場合は、この図を参照してください。

Android 13 でリリース、専用の非 A/B リカバリ(専用の RAM ディスク)あり

デバイスのリリース / アップグレード、GKI あり、専用の非 A/B リカバリあり

図 3. Android 13 でリリースまたは Android 13 へのアップグレード、GKI あり、専用の非 A/B リカバリあり

スロット サフィックスのない recovery というパーティションがデバイスにある場合は、この図を参照してください。

Android 12 でリリースまたは Android 12 へのアップグレード、専用のリカバリなし

デバイスのリリース / アップグレード、GKI あり、専用のリカバリなし

図 4. Android 12 でリリースまたは Android 12 にアップグレードするデバイス、GKI あり、専用のリカバリなし

Android 12 の起動または Android 12 へのアップグレード(専用の A/B リカバリ(専用の RAM ディスク)あり)

デバイスのリリース / アップグレード、GKI あり、専用の A/B リカバリあり

図 5. Android 12 でリリースまたは Android 12 にアップグレードするデバイス、GKI あり、専用の A/B リカバリあり

デバイスに recovery_a パーティションと recovery_b パーティションがある場合は、この図を参照してください。

Android 12 でリリースまたは Android 12 へのアップグレード、専用の非 A/B リカバリ(専用の RAM ディスク)あり

デバイスのリリース / アップグレード、GKI あり、専用の非 A/B リカバリあり

図 6. Android 12 でリリースまたは Android 12 へのアップグレード、GKI あり、専用の非 A/B リカバリあり

スロット サフィックスのない recovery というパーティションがデバイスにある場合は、この図を参照してください。

Android 12 へのアップグレード、リカバリをブートとして使用(リカバリを RAM ディスクとして使用)

デバイスのリリース / アップグレード、GKI なし、リカバリをブートとして使用

図 7. Android 12 にアップグレードするデバイス、GKI なし、リカバリをブートとして使用

Android 12 へのアップグレード(専用のリカバリ(専用 RAM ディスク)あり)

デバイスのリリース / アップグレード、GKI なし、専用のリカバリあり

図 8. Android 12 にアップグレードするデバイス、GKI なし、専用のリカバリあり

ブートイメージの内容

Android のブートイメージには次のものが含まれます。

  • Android 13 を搭載したデバイスに追加された init_boot イメージ

    • ヘッダー バージョン V4
    • 汎用 RAM ディスク イメージ
  • 汎用 boot イメージ

    • ヘッダー バージョン V3 または V4
      • GKI boot.img 証明書用の boot_signature(v4 のみ)。認証済みの GKI boot.img は、確認付きブートで署名されていません。OEM は、デバイス固有の AVB 鍵を使用して、ビルド済みの boot.img に署名する必要があります。
      • 汎用 cmdlineGENERIC_KERNEL_CMDLINE
      • GKI カーネル
    • 汎用 RAM ディスク イメージ
      • Android 12 以前の boot イメージにのみ含まれています。
  • vendor_boot イメージ(詳細については、ベンダー ブート パーティションをご覧ください)

    • vendor_boot ヘッダー
      • デバイス固有の cmdlineBOARD_KERNEL_CMDLINE
    • vendor_boot RAM ディスク イメージ
      • lib/modules
      • リカバリ リソース(専用のリカバリがない場合)
    • dtb イメージ
  • recovery イメージ

    • ヘッダー バージョン V2
      • デバイス固有のリカバリ用 cmdline(必要な場合)
      • 非 A/B リカバリ パーティションの場合、ヘッダーのコンテンツはスタンドアロンにする必要があります(リカバリ イメージをご覧ください)。 例:
      • cmdlinebootvendor_bootcmdline に連結されません。
      • ヘッダーには、必要に応じてリカバリ DTBO を指定します。
      • A/B リカバリ パーティションの場合、コンテンツの連結や、bootvendor_boot からの推測が可能です。例:
      • cmdlinebootvendor_bootcmdline に連結されます。
      • DTBO は vendor_boot ヘッダーから推測できます。
    • recovery RAM ディスク イメージ
      • リカバリ リソース
      • 非 A/B リカバリ パーティションの場合、RAM ディスクのコンテンツはスタンドアロンにする必要があります。リカバリ イメージをご覧ください。 例:
      • lib/modules には、リカバリモードの起動に必要なすべてのカーネル モジュールを含める必要があります。
      • リカバリ RAM ディスクには init を含める必要があります。
      • A/B リカバリ パーティションの場合、リカバリ RAM ディスクは汎用および vendor_boot RAM ディスクの先頭に付加されるため、スタンドアロンにする必要はありません。例:
      • lib/modules には、vendor_boot RAM ディスクのカーネル モジュール以外に、リカバリモードの起動に必要な追加のカーネル モジュールのみを含めることができます。
      • /init にシンボリック リンクが存在する可能性がありますが、ブートイメージに第 1 ステージの /init バイナリがあるため、重要性は低くなります。

汎用 RAM ディスク イメージの内容

汎用 RAM ディスクには、次のコンポーネントが含まれています。

  • init
  • 追加された system/etc/ramdisk/build.prop
  • ro.PRODUCT.bootimg.* build.prop
  • マウント ポイント用の空のディレクトリ: debug_ramdisk/mnt/dev/sys/proc/metadata/
  • first_stage_ramdisk/
    • マウント ポイント用の重複した空のディレクトリ: debug_ramdisk/mnt/dev/sys/proc/metadata/

ブートイメージの統合

ビルドフラグは、init_bootbootrecovery、および 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 を使用することを示します。この変数は sysprop や PRODUCT_PACKAGES には影響しません。

    これはボードレベルの GKI スイッチであり、下記のすべての変数は、この変数により制限されます。

  • BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT。この変数は、RAM ディスクのリカバリ リソースが 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/B recovery パーティションを使用するデバイスでは、この変数を 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 が生成されるかどうかを制御し、そのサイズを設定します。設定すると、汎用 RAM ディスクが boot.img ではなく init_boot.img に追加され、チェーンされた vbmeta に対して BOARD_AVB_INIT_BOOT* 変数を設定することが必要になります。

許可される組み合わせ

コンポーネントまたは変数 recovery パーティションを使用しないデバイスのアップグレード recovery パーティションを使用するデバイスのアップグレード recovery パーティションを使用しないデバイスのリリース A/B recovery パーティションを使用するデバイスの起動 非 A/B recovery パーティションを使用するデバイスの起動 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_IMAGEtrue または空に設定できます。これらのデバイスでは、BOARD_RECOVERYIMAGE_PARTITION_SIZE が設定されている場合、recovery イメージがビルドされます。

ブート用のチェーンされた vbmeta の有効化

bootinit_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 は、動的パーティションを使用するデバイスでもサポートされていません。

プロダクトの構成

汎用 RAM ディスクを使用するデバイスには、RAM ディスクへのインストールが許可されているファイルのリストをインストールする必要があります。これを行うには、device.mk で次のように指定します。

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)

また、generic_ramdisk.mk ファイルを使用することで、他の makefile が誤って他のファイルを RAM ディスクにインストールするのを防ぐことができます(そのようなファイルは vendor_ramdisk に移動されます)。

デバイスのセットアップ

セットアップ手順は、Android 13 を搭載したデバイス、Android 12 にアップグレードするデバイス、Android 12 を搭載したデバイスで異なります。Android 13 は、Android 12 と同様に手順でセットアップされます。

  • Android 12 にアップグレードするデバイス:

    • BOARD_USES_RECOVERY_AS_BOOT の値を保持できます。その場合、以前の構成が使用されているため、新しいビルド変数は空にする必要があります。これはデバイスによって次のように異なります。

      • BOARD_USES_RECOVERY_AS_BOOTtrue に設定されている場合、アーキテクチャは図 3 のようになります。

      • BOARD_USES_RECOVERY_AS_BOOT が空に設定されている場合、アーキテクチャは図 4 のようになります。

    • BOARD_USES_RECOVERY_AS_BOOT は空に設定できます。その場合、新しい構成が使用されます。これはデバイスによって次のように異なります。

      • 専用の recovery パーティションを使用しない場合、アーキテクチャは図 1 のようになります。デバイスのセットアップ オプションはオプション 1 です。

      • 専用の recovery パーティションを使用する場合、アーキテクチャは図 2a または 図 2b のようになります。デバイスのセットアップ オプションはオプション 2a またはオプション 2b です。

  • Android 12 を搭載したデバイスでは、BOARD_USES_RECOVERY_AS_BOOT を空にして新しい構成を使用する必要があります。これはデバイスによって次のように異なります。

    • 専用の recovery パーティションを使用しない場合、アーキテクチャは図 1 のようになります。デバイスのセットアップ オプションはオプション 1 です。

    • 専用の recovery パーティションを使用する場合、アーキテクチャは図 2a または図 2b のようになります。デバイス セットアップ オプションはオプション 2a またはオプション 2b です。

aosp_arm64 は、GKI のみをビルドし、vendor_boot またはリカバリはビルドしないため、完全なターゲットではありません。aosp_arm64 のビルド構成については、generic_arm64 をご覧ください。

オプション 1: 専用のリカバリ パーティションなし

recovery パーティションのないデバイスでは、boot パーティションに汎用 boot イメージが含まれています。vendor_boot RAM ディスクには、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

vendor_boot ramdisk には、/init から /system/bin/init へのシンボリック リンク、および /system/bin/initinit_second_stage.recovery を含めることができます。ただし、vendor_boot RAM ディスクの後に汎用 RAM ディスクが連結されるため、/init シンボリック リンクは上書きされます。デバイスがリカバリに起動する場合、第 2 ステージの init をサポートするには /system/bin/init バイナリが必要です。vendor_boot + 汎用 RAM ディスクのコンテンツは次のようになります。

  • /init(汎用 RAM ディスクのもの。init_first_stage からビルド)
  • /system/bin/initvendor_ramdisk のもの。init_second_stage.recovery からビルド)

fstab ファイルの移動

汎用 RAM ディスクにインストールされているすべての fstab ファイルを vendor_ramdisk に移動します。具体的な例については、こちらの変更をご覧ください。

モジュールのインストール

必要に応じて、デバイス固有のモジュールを vendor_ramdisk にインストールできます(インストールするデバイス固有のモジュールがない場合は、このステップをスキップしてください)。

  • モジュールを /first_stage_ramdisk にインストールするときに、モジュールの vendor_ramdisk バリアントを使用します。このモジュールは、init がルートを /first_stage_ramdisk に切り替えた後、かつ init がルートを /system に切り替える前に使用可能にする必要があります。具体的な例については、メタデータ チェックサム仮想 A/B 圧縮をご覧ください。

  • モジュールを / にインストールするときに、モジュールの recovery バリアントを使用します。 このモジュールは、init がルートを /first_stage_ramdisk に切り替える前に使用可能にする必要があります。/ へのモジュールのインストールについて詳しくは、第 1 ステージのコンソールをご覧ください。

第 1 ステージのコンソール

第 1 ステージのコンソールは init がルートを /first_stage_ramdisk に切り替える前に開始されるため、モジュールの recovery バリアントをインストールする必要があります。デフォルトでは、両方のモジュール バリアントが build/make/target/product/base_vendor.mk にインストールされるため、デバイスの makefile がそのファイルを継承する場合は、recovery バリアントを明示的にインストールする必要はありません。

リカバリ モジュールを明示的にインストールするには、次のように記述します。

PRODUCT_PACKAGES += \
    linker.recovery \
    shell_and_utilities_recovery \

これにより、linkershtoybox$ANDROID_PRODUCT_OUT/recovery/root/system/bin にインストールされ、ここから vendor_ramdisk の下の /system/bin にインストールされます。

第 1 ステージのコンソールに必要なモジュール(adbd など)を追加するには、次のように記述します。

PRODUCT_PACKAGES += adbd.recovery

これにより、指定したモジュールが $ANDROID_PRODUCT_OUT/recovery/root/system/bin にインストールされ、その後これが vendor_ramdisk の下の /system/bin にインストールされます。

メタデータ チェックサム

第 1 ステージのマウント時にメタデータ チェックサムをサポートするため、GKI をサポートしていないデバイスでは、次のモジュールの RAM ディスク バリアントがインストールされます。GKI のサポートを追加するには、モジュールを $ANDROID_PRODUCT_OUT/vendor-ramdisk/first_stage_ramdisk/system/bin に移動します。

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    resize2fs.vendor_ramdisk \
    tune2fs.vendor_ramdisk \

具体的な例については、こちらの変更リストをご覧ください。

仮想 A/B 圧縮

仮想 A/B 圧縮をサポートするには、snapuserdvendor_ramdisk にインストールする必要があります。デバイスは、snapuserdvendor_ramdisk バリアントがインストールされている virtual_ab_ota/compression.mk から継承する必要があります。

起動プロセスの変更

リカバリまたは Android での起動プロセスは変わりませんが、以下の例外があります。

  • 第 2 ステージの init がブートのビルド タイムスタンプを読み取れるように、RAM ディスクの build.prop/second_stage_resources に移動します。

リソースは汎用 RAM ディスクから vendor_boot RAM ディスクに移動するため、汎用 RAM ディスクを vendor_boot RAM ディスクに連結した際の結果は変わりません。

e2fsck を利用できるようにする

デバイスの makefile は次の場所から継承できます。

  • virtual_ab_ota/launch_with_vendor_ramdisk.mk: デバイスが仮想 A/B をサポートしているが、圧縮はサポートしていない場合。

  • virtual_ab_ota/compression.mk: デバイスが仮想 A/B 圧縮をサポートしている場合。

プロダクトの makefile により、$ANDROID_PRODUCT_OUT/vendor-ramdisk/first_stage_ramdisk/system/bin/e2fsck がインストールされます。実行時に、第 1 ステージの init がルートを /first_stage_ramdisk に切り替え、/system/bin/e2fsck を実行します。

オプション 2a: 専用の A/B リカバリ パーティション

このオプションは、A/B recovery パーティションを備えた(recovery_arecovery_b partition のある)デバイスに使用します。このようなデバイスには、リカバリ パーティションの更新が可能な A/B デバイスと仮想 A/B デバイスが含まれます。これらの構成は次のようになります。

AB_OTA_PARTITIONS += recovery

vendor_boot RAM ディスクには、次のように RAM ディスクとベンダー カーネル モジュールのベンダービットが含まれています。

  • デバイス固有の 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

recovery RAM ディスクには、/init -> /system/bin/init のシンボリック リンク、および /system/bin/initinit_second_stage.recovery を含めることができます。ただし、recovery RAM ディスクの後にブート RAM ディスクが連結されるため、/init シンボリック リンクは上書きされます。デバイスがリカバリモードで起動する場合、第 2 ステージの init をサポートするには /system/bin/init バイナリが必要です。

デバイスが recovery で起動する場合、recovery + vendor_boot + 汎用 RAM ディスクのコンテンツは次のようになります。

  • /init(RAM ディスクのもの。init_first_stage からビルド)
  • /system/bin/initrecovery RAM ディスクのもの。init_second_stage.recovery からビルドし、/init から実行)

デバイスが Android で起動する場合、vendor_boot + 汎用 RAM ディスクのコンテンツは次のようになります。

  • /init(汎用 RAM ディスクのもの。init_first_stage からビルド)

fstab ファイルの移動

汎用 RAM ディスクにインストールされたすべての fstab ファイルを vendor_ramdisk に移動します。具体的な例については、こちらの変更をご覧ください。

モジュールのインストール

必要に応じて、デバイス固有のモジュールを vendor_ramdisk にインストールできます(インストールするデバイス固有のモジュールがない場合は、このステップをスキップしてください)。Init はルートを切り替えません。モジュールの vendor_ramdisk バリアントは、vendor_ramdisk のルートにインストールされます。vendor_ramdisk へのモジュールのインストール例については、第 1 ステージのコンソールメタデータ チェックサム仮想 A/B 圧縮をご覧ください。

第 1 ステージのコンソール

モジュールの vendor_ramdisk バリアントをインストールするには、次のように記述します。

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    shell_and_utilities_vendor_ramdisk \

これにより、linkershtoybox$ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin にインストールされ、ここから vendor_ramdisk の下の /system/bin にインストールされます。

第 1 ステージのコンソールに必要なモジュール(adbd など)を追加するには、関連するパッチを AOSP にアップロードして、これらのモジュールの vendor_ramdisk バリアントを有効にしてから、次のように記述します。

PRODUCT_PACKAGES += adbd.vendor_ramdisk

これにより、指定したモジュールが $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin にインストールされます。vendor_boot RAM ディスクがリカバリモードで読み込まれる場合、モジュールは recovery でも使用できます。vendor_boot RAM ディスクがリカバリモードで読み込まれない場合は、必要に応じて adbd.recovery もインストールできます。

メタデータ チェックサム

第 1 ステージのマウント時にメタデータ チェックサムをサポートするため、GKI をサポートしていないデバイスでは、次のモジュールの RAM ディスク バリアントがインストールされます。GKI のサポートを追加するには、モジュールを $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin に移動します。

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    resize2fs.vendor_ramdisk \
    tune2fs.vendor_ramdisk \

具体的な例については、こちらの変更リストをご覧ください。

仮想 A/B 圧縮

仮想 A/B 圧縮をサポートするには、snapuserdvendor_ramdisk にインストールする必要があります。デバイスは、snapuserdvendor_ramdisk バリアントがインストールされている virtual_ab_ota/compression.mk から継承する必要があります。

起動プロセスの変更

Android で起動する場合、起動プロセスは変更されません。vendor_boot + 汎用 RAM ディスクは、fstabvendor_boot から読み込まれることを除けば、既存の起動プロセスと似ています。system/bin/recovery が存在しないため、first_stage_init はこれを通常のブートとして処理します。

リカバリモードで起動すると、起動プロセスが変更されます。recovery + vendor_boot + 汎用 RAM ディスクは既存のリカバリ プロセスと似ていますが、カーネルは recovery イメージではなく boot イメージから読み込まれます。リカバリモードの起動プロセスは次のとおりです。

  1. ブートローダーが起動し、次の処理が行われます。

    1. recovery + vendor_boot + 汎用 RAM ディスクを / に push します(OEM が recovery RAM ディスクでカーネル モジュールを BOARD_RECOVERY_KERNEL_MODULES に追加して複製する場合、vendor_boot は省略可能です)。
    2. boot パーティションからカーネルを実行します。
  2. カーネルは RAM ディスクを / にマウントし、汎用 RAM ディスクから /init を実行します。

  3. 第 1 ステージの init が起動し、次の処理が行われます。

    1. IsRecoveryMode() == trueForceNormalBoot() == false を設定します。
    2. ベンダーのカーネル モジュールを /lib/modules から読み込みます。
    3. DoFirstStageMount() を呼び出しますが、IsRecoveryMode() == true のためマウントをスキップします。(/ が同じであるため、デバイスは RAM ディスクを解放せずに、SetInitAvbVersionInRecovery() を呼び出します)。
    4. recovery RAM ディスクの /system/bin/init から第 2 ステージの init を開始します。

e2fsck を利用できるようにする

デバイスの makefile は次の場所から継承できます。

  • virtual_ab_ota/launch_with_vendor_ramdisk.mk: デバイスが仮想 A/B をサポートしているが、圧縮はサポートしていない場合。

  • virtual_ab_ota/compression.mk: デバイスが仮想 A/B 圧縮をサポートしている場合。

プロダクトの makefile により、$ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin/e2fsck がインストールされます。実行時に、第 1 ステージの init/system/bin/e2fsck を実行します。

オプション 2b: 専用の非 A/B リカバリ パーティション

このオプションは、非 A/B recovery パーティションを備えたデバイス(スロット サフィックスのない、recovery という名前のパーティションがあるデバイス)に使用します。こうしたデバイスには次のようなものがあります。

  • 非 A/B デバイス
  • リカバリ パーティションの更新ができない A/B デバイスと仮想 A/B デバイス(これはめったにありません)。

vendor_boot RAM ディスクには、次のように RAM ディスクとベンダー カーネル モジュールのベンダービットが含まれています。

  • デバイス固有の fstab ファイル
  • lib/modules(ベンダー カーネル モジュールを含む)

recovery イメージは自己完結型でなければなりません。また、リカバリモードを起動するために必要なすべてのリソースが含まれている必要があります。以下にその例を示します。

  • カーネル イメージ
  • DTBO イメージ
  • lib/modules のカーネル モジュール
  • 第 1 ステージの init(/init -> /system/bin/init のシンボリック リンクとして)
  • 第 2 ステージの 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

recovery RAM ディスクには、/init -> /system/bin/init のシンボリック リンク、および /system/bin/initinit_second_stage.recovery が含まれている必要がありますデバイスがリカバリモードで起動する際、第 1 ステージと第 2 ステージの init の両方をサポートするには /system/bin/init バイナリが必要です。

デバイスが recovery で起動する場合、recovery RAM ディスクのコンテンツは次のようになります。

  • /init -> /system/bin/initrecovery RAM ディスクのもの)
  • /system/bin/initrecovery RAM ディスクのもの。init_second_stage.recovery からビルドし、/init から実行)

デバイスが Android で起動する場合、vendor_boot + 汎用 RAM ディスクのコンテンツは次のようになります。

  • /init(RAM ディスクのもの。init_first_stage からビルド)

fstab ファイルの移動

汎用 RAM ディスクにインストールされたすべての fstab ファイルを、vendor_ramdiskrecovery RAM ディスクに移動します。具体的な例については、こちらの変更をご覧ください。

モジュールのインストール

必要に応じて、デバイス固有のモジュールを vendor_ramdiskrecovery RAM ディスクにインストールできます(インストールするデバイス固有のモジュールがない場合は、このステップをスキップしてください)。init はルートを切り替えません。モジュールの vendor_ramdisk バリアントは、vendor_ramdisk のルートにインストールされます。モジュールの recovery バリアントは、recovery RAM ディスクのルートにインストールされます。vendor_ramdiskrecovery RAM ディスクへのモジュールのインストール例については、第 1 ステージのコンソールメタデータ チェックサムをご覧ください。

第 1 ステージのコンソール

モジュールの vendor_ramdisk バリアントをインストールするには、次のように記述します。

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    shell_and_utilities_vendor_ramdisk \

これにより、linkershtoybox$ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin にインストールされ、ここから vendor_ramdisk の下の /system/bin にインストールされます。

第 1 ステージのコンソールに必要なモジュール(adbd など)を追加するには、関連するパッチを AOSP にアップロードして、これらのモジュールの vendor_ramdisk バリアントを有効にしてから、次のように記述します。

PRODUCT_PACKAGES += adbd.vendor_ramdisk

これにより、指定したモジュールが $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin にインストールされます。

モジュールの recovery バリアントをインストールするには、vendor_ramdiskrecovery に置き換えます。

PRODUCT_PACKAGES += \
    linker.recovery \
    shell_and_utilities_recovery \
    adbd.recovery \

メタデータ チェックサム

第 1 ステージのマウント時にメタデータ チェックサムをサポートするため、GKI をサポートしていないデバイスでは、次のモジュールの RAM ディスク バリアントがインストールされます。GKI のサポートを追加するには、モジュールを $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin に移動します。

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    resize2fs.vendor_ramdisk \
    tune2fs.vendor_ramdisk \

リカバリの第 1 ステージのマウント時にメタデータ チェックサムをサポートするには、これらのモジュールのリカバリ バリアントを有効にしてからインストールします。

起動プロセスの変更

Android で起動する場合、起動プロセスは変更されません。vendor_boot + 汎用 RAM ディスクは、fstabvendor_boot から読み込まれることを除けば、既存の起動プロセスと似ています。system/bin/recovery が存在しないため、first_stage_init はこれを通常のブートとして処理します。

リカバリモードで起動する場合、起動プロセスは変更されません。リカバリ用 RAM ディスクは、既存のリカバリ プロセスと同じ方法で読み込まれます。カーネルは recovery イメージから読み込まれます。リカバリモードの起動プロセスは次のとおりです。

  1. ブートローダーが起動し、次の処理が行われます。

    1. リカバリ用 RAM ディスクを / に push します。
    2. recovery パーティションからカーネルを実行します。
  2. カーネルは RAM ディスクを / にマウントし、/init を実行します。これは、recovery RAM ディスクから /system/bin/init へのシンボリック リンクです。

  3. 第 1 ステージの init が起動し、次の処理が行われます。

    1. IsRecoveryMode() == trueForceNormalBoot() == false を設定します。
    2. ベンダーのカーネル モジュールを /lib/modules から読み込みます。
    3. DoFirstStageMount() を呼び出しますが、IsRecoveryMode() == true のためマウントをスキップします。(/ が同じであるため、デバイスは RAM ディスクを解放せずに、SetInitAvbVersionInRecovery() を呼び出します)。
    4. recovery RAM ディスクの /system/bin/init から第 2 ステージの 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
  • ビルド時に、system/etc/ramdisk/build.prop ファイルが汎用 RAM ディスクに追加されます。このファイルにはビルドのタイムスタンプ情報が含まれています。

  • 実行時に、第 1 ステージの init は RAM ディスクのファイルを tmpfsコピーし、その後 RAM ディスクを解放します。これにより、第 2 ステージの init がこのファイルを読み取りboot イメージのタイムスタンプ プロパティを設定できるようになります。