一般啟動分區

在 Android 12 中,通用 boot 映像檔 (稱為通用核心映像檔 (GKI)) 包含通用 RAM 磁碟和 GKI 核心。

如果是搭載 Android 13 的裝置,一般 ramdisk 會從 boot 映像檔中移除,並放在獨立的 init_boot 映像檔中。這項變更會讓 boot 映像檔只保留 GKI 核心。

如要升級繼續使用 Android 12 或舊版核心的裝置,一般 ramdisk 會保留在原處,不需要新的 init_boot 映像檔。

如要建構一般 ramdisk,請將供應商專屬資源移出 ramdisk,讓一般 ramdisk 只包含第一階段 init 和含有時間戳記資訊的屬性檔案。

在下列裝置上:

  • 請勿使用專屬 recovery 分區,所有復原位元都會從一般 ramdisk 移至 vendor_boot ramdisk。

  • 請使用專屬的 recovery 分區,由於 recovery ramdisk 是獨立的,因此不需要變更 recovery ramdisk。

建築

下圖說明搭載 Android 12 以上版本的裝置架構。搭載 Android 13 的裝置會使用包含通用 ramdisk 的新init_boot映像檔。從 Android 12 升級至 Android 13 的裝置,會沿用 Android 12 的架構。

推出時搭載 Android 13,沒有專屬復原模式

推出/升級裝置、GKI,沒有專屬復原功能

圖 1. 推出或升級至 Android 13 的裝置 (搭載 GKI,沒有專屬的復原模式)。

推出時搭載 Android 13,並提供專用和 A/B 復原功能 (專用 ramdisk)

啟動/升級裝置、GKI、專用和 A/B 復原

圖 2. 推出或升級至 Android 13 的裝置,搭載 GKI、專用和 A/B 復原功能。

如果裝置有 recovery_arecovery_b 分割區,請參閱下圖。

推出時搭載 Android 13,專用和非 A/B 復原 (專用 ramdisk)

啟動/升級裝置、GKI、專用和非 A/B 復原

圖 3. 推出或升級至 Android 13 的裝置,搭載 GKI、專用和非 A/B 復原功能。

如果裝置有名為 recovery 的分割區,但沒有 slot 後置字串,請參閱下圖。

推出或升級至 Android 12,沒有專屬復原功能

推出/升級裝置、GKI,沒有專屬復原功能

圖 4. 推出或升級至 Android 12 的裝置 (搭載 GKI,沒有專屬的復原功能)。

啟動或升級至 Android 12、專用和 A/B 復原 (專用 ramdisk)

啟動/升級裝置、GKI、專用和 A/B 復原

圖 5. 推出或升級至 Android 12 的裝置,且搭載 GKI、專用和 A/B 復原功能。

如果裝置有 recovery_arecovery_b 分割區,請參閱下圖。

啟動或升級至 Android 12,專用和非 A/B 復原 (專用 ramdisk)

啟動/升級裝置、GKI、專用和非 A/B 復原

圖 6. 推出或升級至 Android 12 的裝置,搭載 GKI、專用和非 A/B 復原功能。

如果裝置有名為 recovery 的分割區,但沒有 slot 後置字串,請參閱下圖。

升級至 Android 12,recovery-as-boot (recovery-as-ramdisk)

啟動/升級裝置,沒有 GKI,以復原模式開機

圖 7. 裝置升級至 Android 12,沒有 GKI,以復原模式開機。

升級至 Android 12,專屬復原 (專屬 ramdisk)

啟動/升級裝置,無 GKI,專用復原

圖 8. 升級至 Android 12 的裝置,不含 GKI,專用復原。

開機映像檔內容

Android 開機映像檔包含下列項目。

  • init_boot 新增搭載 Android 13 的裝置圖片

    • 標頭版本 V4
    • 一般 ramdisk 映像檔
  • 一般boot圖片

    • 標頭版本 V3V4
      • GKI boot.img 認證的 boot_signature (僅限 v4)。認證 GKI boot.img 未簽署驗證開機程序。OEM 仍須使用裝置專屬的 AVB 金鑰簽署預先建構的 boot.img
      • 一般 cmdline (GENERIC_KERNEL_CMDLINE)
      • GKI 核心
    • 通用 ramdisk 映像檔
      • 僅包含在 Android 12 以下版本的 boot 圖片中
  • vendor_boot 映像檔 (詳情請參閱「供應商啟動磁碟分割區」)

    • vendor_boot header
      • 裝置專屬 cmdline (BOARD_KERNEL_CMDLINE)
    • vendor_boot ramdisk 映像檔
      • lib/modules
      • 復原資源 (如果沒有專屬復原資源)
    • dtb 張圖片
  • recovery 張圖片

    • 標題版本 V2
      • 視需要使用特定裝置的 cmdline 進行復原
      • 如為非 A/B 復原分割區,標頭內容必須是獨立的;請參閱「復原映像檔」。例如:
      • cmdline 不會串連至 bootvendor_boot cmdline
      • 標頭會視需要指定復原 DTBO。
      • 如果是 A/B 復原分割區,內容可以從 bootvendor_boot 串連或推斷。例如:
      • cmdline 會串連至 bootvendor_boot cmdline
      • DTBO 可從 vendor_boot 標頭推斷得出。
    • recovery ramdisk 映像檔
      • 復原資源
      • 如為非 A/B 復原磁碟分割區,ramdisk 的內容必須是獨立的;請參閱「復原映像檔」。例如:
      • lib/modules 必須包含啟動復原模式所需的所有核心模組
      • 復原 RAM 磁碟必須包含 init
      • 對於 A/B 復原分割區,復原 ramdisk 會預先附加至一般和 � ramdisk,因此不需要獨立。vendor_boot例如:
      • lib/modules 可能只包含啟動復原模式所需的額外核心模組,vendor_boot ramdisk 中的核心模組除外。
      • /init 可能存在符號連結,但會被開機映像檔中的第一階段 /init 二進位檔遮蔽。

一般 ramdisk 映像檔內容

一般 RAM 磁碟包含下列元件。

  • init
  • system/etc/ramdisk/build.prop
  • ro.PRODUCT.bootimg.* build props
  • 掛接點的空白目錄:debug_ramdisk/mnt/dev/sys/proc/metadata/
  • first_stage_ramdisk/
    • 掛接點的空白目錄重複:debug_ramdisk/mnt/dev/sys/proc/metadata/

整合開機映像檔

建構旗標可控管 init_bootbootrecoveryvendor_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。這個變數不會影響 sysprops 或 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/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,並設定大小。設定後,系統會將一般 ramdisk 新增至 init_boot.img,而非 boot.img,且需要為鏈結的 vbmeta 設定 BOARD_AVB_INIT_BOOT* 變數。

允許的組合

元件或變數 升級裝置 (不含復原磁碟分割區) 使用復原磁碟分割區升級裝置 啟動裝置,但不使用復原磁碟分割區 使用 A/B 復原磁碟分割區啟動裝置 啟動裝置,但使用非 A/B 復原磁碟分割區 aosp_arm64
boot
包含 init_boot (Android 13) no no
vendor_boot 選用 選用 no
recovery no no no
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

必須為 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

如需範例,請參閱這項變更

系統即根目錄

使用 GKI 的裝置不支援以系統做為根目錄。在這些裝置上,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_BOOT 設為 true,架構如圖 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 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

vendor_boot ramdisk 可以包含 /init/system/bin/init 的符號連結,以及 /system/bin/initinit_second_stage.recovery。不過,由於通用 RAM 磁碟會在 vendor_boot RAM 磁碟後串連,因此 /init 符號連結會遭到覆寫。裝置啟動進入復原模式時,需要 /system/bin/init 二進位檔才能支援第二階段的 init。vendor_boot + 一般 RAM 磁碟的內容如下:

  • /init (來自通用 RAM 磁碟,由 init_first_stage 建構)
  • /system/bin/init (來自 vendor_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 之前提供。如要瞭解如何將模組安裝至 /,請參閱第一階段控制台

第一階段控制台

因為第一階段控制台會在 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

如要新增第一階段控制台所需的模組 (例如 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 \

如需範例,請參閱這份更動清單

虛擬 A/B 壓縮

如要支援虛擬 A/B 壓縮,必須將 snapuserd 安裝至 vendor_ramdisk。裝置應從 virtual_ab_ota/compression.mk 繼承,這會安裝 snapuserdvendor_ramdisk 變體。

啟動程序異動

啟動進入復原模式或 Android 的程序不會改變,但有以下例外情況:

  • Ramdisk build.prop 會移至 /second_stage_resources,以便第二階段 init 讀取開機的建構時間戳記。

因為資源會從一般 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。在執行階段,第一個階段 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 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

recovery ramdisk 可以包含 /init -> /system/bin/init 符號連結,以及 /system/bin/initinit_second_stage.recovery。不過,由於開機 ramdisk 是在 recovery ramdisk 後串連,因此 /init 符號連結會遭到覆寫。裝置啟動進入復原模式時,需要 /system/bin/init 二進位檔支援第二階段 init。

裝置啟動進入 recovery 時,recovery + vendor_boot + 一般 ramdisk 的內容如下:

  • /init (來自 ramdisk,由 init_first_stage 建構)
  • /system/bin/init (來自 recovery ramdisk,由 init_second_stage.recovery 建構,並從 /init 執行)

裝置啟動進入 Android 時,vendor_boot + 一般 ramdisk 的內容如下:

  • /init (來自通用 RAM 磁碟,由 init_first_stage 建構)

移動 fstab 檔案

將安裝到一般 RAM 磁碟的任何 fstab 檔案移至 vendor_ramdisk。如需範例,請參閱這項變更

安裝模組

(選用) 安裝裝置專用模組,以 vendor_ramdisk (如果沒有要安裝的裝置專用模組,請略過這個步驟)。Init 不會切換根目錄。模組的 vendor_ramdisk 變體會安裝至 vendor_ramdisk 的根目錄。如需將模組安裝至 vendor_ramdisk 的範例,請參閱「第一階段控制台」、「中繼資料總和檢查碼」和「虛擬 A/B 壓縮」。

第一階段控制台

如要安裝模組的 vendor_ramdisk 變體,請使用下列指令:

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    shell_and_utilities_vendor_ramdisk \

這樣可確保 linkershtoybox 會安裝至 $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 \

如需範例,請參閱這份更動清單

虛擬 A/B 壓縮

如要支援 Virtual A/B 壓縮,必須將 snapuserd 安裝至 vendor_ramdisk。裝置應從 virtual_ab_ota/compression.mk 繼承,這會安裝 snapuserdvendor_ramdisk 變體。

啟動程序異動

啟動 Android 時,開機程序不會改變。vendor_boot + 一般 ramdisk 與現有的啟動程序類似,差別在於 fstab 會從 vendor_boot 載入。由於 system/bin/recovery 不存在,first_stage_init 會將其視為正常啟動。

啟動進入復原模式時,啟動程序會有所不同。復原 + vendor_boot + 一般 ramdisk 與現有的復原程序類似,但核心是從 boot 映像檔載入,而不是從 recovery 映像檔載入。 復原模式的啟動程序如下。

  1. 開機載入程式會啟動,然後執行下列操作:

    1. 將復原 + vendor_boot + 通用 ramdisk 推送至 /。(如果原始設備製造商 (OEM) 透過將核心模組新增至 BOARD_RECOVERY_KERNEL_MODULES,在復原 ramdisk 中複製核心模組,則 vendor_boot 為選用項目)。
    2. boot 分區執行核心。
  2. 核心會將 ramdisk 掛接到 /,然後從一般 ramdisk 執行 /init

  3. 第一階段初始化作業會啟動,然後執行下列操作:

    1. 設定 IsRecoveryMode() == trueForceNormalBoot() == false
    2. /lib/modules 載入供應商核心模組。
    3. 呼叫 DoFirstStageMount(),但略過掛接,因為 IsRecoveryMode() == true。(裝置不會釋放 ramdisk (因為 / 仍相同),但會呼叫 SetInitAvbVersionInRecovery())。
    4. recovery ramdisk 的 /system/bin/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。在執行階段,第一個階段 init 會執行 /system/bin/e2fsck

選項 2b:專用和非 A/B 復原磁碟分割區

如果裝置具有非 A/B recovery 分區,也就是裝置有名為 recovery 的分區,但沒有 slot 後置字元,請使用這個選項。這類裝置包括:

  • 非 A/B 裝置;
  • A/B 和虛擬 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

recovery ramdisk 必須包含 /init -> /system/bin/init 符號連結,以及 /system/bin/initinit_second_stage.recovery。裝置啟動進入復原模式時,需要 /system/bin/init 二進位檔,才能支援第一階段和第二階段的 init。

裝置啟動進入 recovery 時,recovery ramdisk 的內容如下:

  • /init -> /system/bin/init (來自 recovery ramdisk)
  • /system/bin/init (來自 recovery ramdisk,由 init_second_stage.recovery 建構,並從 /init 執行)

裝置啟動進入 Android 時,vendor_boot + 一般 ramdisk 的內容如下:

  • /init (來自 ramdisk,由 init_first_stage 建構)

移動 fstab 檔案

將安裝到一般 RAM 磁碟的任何 fstab 檔案移至 vendor_ramdiskrecovery RAM 磁碟。如需範例,請參閱這項變更

安裝模組

您可以將裝置專用模組安裝至 vendor_ramdiskrecovery ramdisk (如果沒有任何裝置專用模組要安裝,請略過這個步驟)。init 不會切換根目錄。模組的 vendor_ramdisk 變體會安裝至 vendor_ramdisk 的根目錄。模組的 recovery 變體會安裝至 recovery ramdisk 的根目錄。如需將模組安裝至 vendor_ramdiskrecovery ramdisk 的範例,請參閱第一階段主控台中繼資料檢查碼

第一階段控制台

如要安裝模組的 vendor_ramdisk 變體,請使用下列指令:

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    shell_and_utilities_vendor_ramdisk \

這樣可確保 linkershtoybox 會安裝至 $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 映像檔載入。復原模式的啟動程序如下。

  1. 開機載入程式會啟動,然後執行下列操作:

    1. 將復原 ramdisk 推送至 /
    2. recovery 分區執行核心。
  2. 核心會將 ramdisk 掛接到 /,然後執行 /init,這是 recovery ramdisk 中 /system/bin/init 的符號連結。

  3. 第一階段初始化作業會啟動,然後執行下列操作:

    1. 設定 IsRecoveryMode() == trueForceNormalBoot() == false
    2. /lib/modules 載入供應商核心模組。
    3. 呼叫 DoFirstStageMount(),但略過掛接,因為 IsRecoveryMode() == true。(裝置不會釋放 ramdisk (因為 / 仍相同),但會呼叫 SetInitAvbVersionInRecovery())。
    4. recovery ramdisk 的 /system/bin/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 檔案新增至一般 ramdisk。這個檔案包含建構作業的時間戳記資訊。

  • 在執行階段,第一階段 init 會先將檔案從 ramdisk 複製tmpfs,然後釋放 ramdisk,以便第二階段 init 讀取這個檔案,設定 boot 映像檔時間戳記屬性。