一般啟動分區

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

對於使用 Android 13 啟動的裝置,一般 RAM 磁碟會從 boot 映像檔中移除,並放置在獨立的 init_boot 映像檔中。這項變更會讓 boot 映像檔僅包含 GKI 核心。

如果是繼續使用 Android 12 或更舊版本核心的升級裝置,通用 RAM 磁碟會保留在原處,不需要新的 init_boot 映像檔。

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

在下列裝置上:

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

  • 請使用專屬的 recovery 分割區,由於 recovery 隨機存取磁碟是自給自足的,因此無須變更 recovery 隨機存取磁碟。

建築

下圖說明搭載 Android 12 以上版本的裝置架構。搭載 Android 13 的裝置會使用含有通用 RAM 磁碟的新 init_boot 映像檔。從 Android 12 升級至 Android 13 的裝置,會使用與 Android 12 相同的架構。

推出時搭載 Android 13,無專屬救援方式

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

圖 1. 搭載 Android 13 或升級至 Android 13 的裝置未具備專屬復原機制。

推出時搭載 Android 13、專屬和 A/B 復原 (專屬 RAM 磁碟)

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

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

請參考此圖表,瞭解裝置是否有 recovery_arecovery_b 分區。

啟動時搭載 Android 13,專用和非 A/B 復原功能 (專屬 ramdisk)

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

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

如果裝置有名稱為 recovery 的區隔,但沒有插槽後置字串,請參閱這張圖片。

推出或升級至 Android 12,不需專用復原程序

啟動/升級裝置、GKI、無專用復原程序

圖 4. 搭載 Android 12 或升級至 Android 12 的裝置 (GKI 無專用復原機制)。

啟動或升級至 Android 12,專用和 A/B 復原 (專用 RAM 磁碟)

啟動/升級裝置、GKI、專屬和 A/B 復原程序

圖 5. 搭載 GKI、專屬和 A/B 復原功能,並啟動或升級至 Android 12 的裝置。

如果裝置有 recovery_arecovery_b 分區,請參閱這張圖片。

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

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

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

如果裝置有名稱為 recovery 的區隔,但沒有插槽後置字串,請參閱這張圖片。

升級至 Android 12,並使用「recovery-as-boot」(recovery-as-ramdisk)

啟動/升級裝置、不使用 GKI、復原即啟動

圖 7. 升級至 Android 12 的裝置,沒有 GKI,啟動時執行復原作業。

升級至 Android 12,專用復原 (專用 RAM 磁碟)

啟動/升級裝置、無 GKI、專屬救援

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

開機映像檔內容

Android 啟動映像檔包含下列項目:

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

    • 標頭版本 V4
    • 通用 RAM 磁碟映像檔
  • 通用 boot 圖片

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

    • vendor_boot 標頭
      • 裝置專屬 cmdline (BOARD_KERNEL_CMDLINE)
    • vendor_boot 隨機存取磁碟映像檔
      • lib/modules
      • 復原資源 (如果沒有專屬復原作業)
    • dtb的圖片
  • recovery的圖片

    • 標頭版本 2
      • 視需要使用裝置專屬的 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 會加到一般和 vendor_boot ramdisk 中,因此不需要單獨使用。例如:
      • lib/modules 可能只包含 vendor_boot ramdisk 中核心模組以外,啟動復原模式所需的其他核心模組。
      • /init 中可能存在符號連結,但會被開機映像檔中第一階段的 /init 二進位檔遮蔽。

一般 ramdisk 映像檔內容

一般 ramdisk 包含以下元件。

  • init
  • system/etc/ramdisk/build.prop
  • ro.PRODUCT.bootimg.* build 道具
  • 掛接點的空目錄: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,並設定大小。設定後,一般 RAM 磁碟會新增至 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 必須為空白。使用動態分區的裝置也不支援系統做為根目錄。

產品設定

使用通用 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 快取磁碟可包含 /init/system/bin/init 的符號連結,以及 init_second_stage.recovery/system/bin/init 的位置。不過,由於一般 ramdisk 是在 vendor_boot ramdisk 後串連,所以 /init 符號連結會遭到覆寫。裝置啟動至復原模式時,需要 /system/bin/init 二進位檔才能支援第二階段初始化。vendor_boot + 一般 RAMDISK 的內容如下:

  • /init (來自通用 RAM 磁碟,由 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 之前提供。如需相關範例,請參閱「中繼資料總和檢查碼」和「虛擬 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 但不支援壓縮。

  • 如果裝置支援虛擬 A/B 壓縮,則為 virtual_ab_ota/compression.mk

產品 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 快閃磁碟包含所有復原資源。在這些裝置上,產品設定會繼承 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 快取磁碟可包含 /init -> /system/bin/init 符號連結,以及 /system/bin/init 中的 init_second_stage.recovery。不過,由於開機磁碟是在 recovery ramdisk 後串連,因此 /init 符號連結會遭到覆寫。裝置啟動至復原模式時,需要 /system/bin/init 二進位檔才能支援第二階段初始化。

當裝置啟動至 recovery 時,recovery + vendor_boot + 一般 RAMdisk 的內容如下:

  • /init (來自 RAM 磁碟,由 init_first_stage 建構)
  • /system/bin/init (來自 recovery 快取磁碟,由 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 的範例,請參閱第一階段主控台中繼資料總和檢查碼虛擬 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 壓縮

如要支援虛擬 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 來複製核心模組,則可選用 vendor_boot
    2. boot 分區執行核心。
  2. 核心會將 RAM 磁碟掛載至 /,然後從一般 RAM 磁碟執行 /init

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

    1. 設定 IsRecoveryMode() == trueForceNormalBoot() == false
    2. /lib/modules 載入供應商核心模組。
    3. 呼叫 DoFirstStageMount(),但因為 IsRecoveryMode() == true 而略過掛接程序。(裝置不會釋放 ramdisk (因為 / 仍相同),但會呼叫 SetInitAvbVersionInRecovery())。
    4. recovery 的 RAM 磁碟區 /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 且沒有插槽後置字元的分區。這類裝置包括:

  • 非 A/B 裝置。
  • A/B 和虛擬 A/B 裝置,其復原分區無法更新。(此為異常現象)。

vendor_boot ramdisk 包含 ramdisk 和供應商核心模組的廠商位元,包括:

  • 裝置專屬的 fstab 檔案
  • lib/modules (包含供應商核心模組)

recovery 圖片必須是獨立的。必須包含啟動復原模式所需的所有資源,包括:

  • 核心映像檔
  • DTBO 映像檔
  • lib/modules」中的核心模組
  • 第一階段初始化為符號連結 /init -> /system/bin/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 快取磁碟必須包含 /init -> /system/bin/init 符號連結,並在 /system/bin/init 中包含 init_second_stage.recovery。裝置啟動至復原模式時,/system/bin/init 二進位檔必須同時支援第一階段和第二階段初始化。

當裝置啟動至 recovery 時,recovery ramdisk 的內容如下:

  • /init -> /system/bin/init (來自 recovery 快取磁碟)
  • /system/bin/init (來自 recovery 快取磁碟,由 init_second_stage.recovery 建構,並由 /init 執行)

裝置啟動至 Android 時,vendor_boot + 通用 RAMDISK 的內容如下:

  • /init (從 ramdisk,透過 init_first_stage 建構)

移動 fstab 檔案

將所有已安裝至通用 RAM 磁碟的 fstab 檔案移至 vendor_ramdiskrecovery RAM 磁碟。如需範例,請參閱這項變更

安裝模組

您可以將裝置專屬模組安裝到 vendor_ramdiskrecovery 的 RAM 磁碟區 (如果沒有任何裝置專屬模組可安裝,請略過這個步驟)。init 不會切換根目錄。模組的 vendor_ramdisk 變化版本會安裝至 vendor_ramdisk 的根目錄。模組的 recovery 變化版本會安裝至 recovery 快取磁碟的根目錄。如需將模組安裝至 vendor_ramdiskrecovery RAM 磁碟的範例,請參閱「第一階段主控台」和「中繼資料總和檢查碼」。

第一階段控制台

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

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    shell_and_utilities_vendor_ramdisk \

這可確保 linkershtoybox 安裝至 $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin,然後再安裝至 vendor_ramdisk 底下的 /system/bin

如要新增第一個階段主控台所需的模組 (例如 ADB),請將相關修補程式上傳至 Android 開放原始碼計畫,藉此啟用這些模組的 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 + 通用 RAM 磁碟與現有的啟動程序類似,差別只在於 fstab 會從 vendor_boot 載入。由於 system/bin/recovery 不存在,first_stage_init 會將其視為一般啟動。

啟動進入復原模式時,啟動程序不會變更。復原 ramdisk 的載入方式與現有復原程序相同。 核心會從 recovery 映像檔載入。復原模式的啟動程序如下所示。

  1. 啟動載入器會啟動,然後執行下列操作:

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

  3. 第一個階段 init 會啟動,然後執行以下操作:

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

  • 在執行階段,第一階段 init 會先從 RAM 磁碟複製檔案到 tmpfs,再釋放 RAM 磁碟,以便第二階段 init 讀取此檔案,設定 boot 圖片時間戳記屬性。