一般啟動分區

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

對於使用 Android 13 啟動的裝置,一般 RAM 磁碟會從 boot 映像檔中移除,並放置在個別的 init_boot 映像檔中。這項變更會讓 boot 映像檔只保留 GKI 核心。

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

如要建構通用的 RAM 磁碟,請將供應商專屬資源移出 RAM 磁碟,讓通用 RAM 磁碟只包含第一階段 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. 使用 GKI 的裝置,可啟動或升級至 Android 13,但沒有專屬的復原功能。

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

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

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

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

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

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

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

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

啟動或升級至 Android 12,沒有專屬的復原功能

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

圖 4. 搭載 GKI 的裝置,可啟動或升級至 Android 12,但沒有專屬的復原功能。

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

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

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

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

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

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

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

如果裝置有名稱為 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
      • 您可以從 vendor_boot 標頭推斷 DTBO。
    • recovery 隨機存取磁碟映像檔
      • 復原資源
      • 如果是 A/B 以外的復原分區,ramdisk 的內容必須是獨立的;請參閱「復原映像檔」。例如:
      • lib/modules 必須包含啟動復原模式所需的所有核心模組
      • 復原 RAM 磁碟必須包含 init
      • 對於 A/B 復原分割區,復原 RAM 磁碟會附加至通用和 vendor_boot RAM 磁碟,因此不必獨立運作。例如:
      • lib/modules 可能只包含 vendor_boot ramdisk 中的核心模組以外,啟動復原模式所需的其他核心模組。
      • /init 中可能存在符號連結,但會被開機映像檔中第一階段的 /init 二進位檔遮蔽。

一般 ramdisk 映像檔內容

通用 RAM 磁碟包含下列元件。

  • 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 的位置。不過,由於通用 RAM 磁碟會連結至 vendor_boot RAM 磁碟,因此 /init 符號連結會遭到覆寫。裝置啟動至復原模式時,需要 /system/bin/init 二進位檔才能支援第二階段初始化。vendor_boot + 一般 RAMDISK 的內容如下:

  • /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 快閃磁碟包含快閃磁碟和供應商核心模組的供應商位元,包括以下項目:

  • 裝置專屬 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。不過,由於啟動 RAM 磁碟會連結在 recovery RAM 磁碟之後,因此 /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 + 通用 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 的 RAM 磁碟區是在復原模式下載入,則該模組也會在 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 + 一般 RAM 磁碟機的運作方式與現有的啟動程序類似,差別只在於 fstab 會從 vendor_boot 載入。由於 system/bin/recovery 不存在,first_stage_init 會將其視為一般啟動。

啟動至復原模式時,啟動程序會有所變更。復原 + vendor_boot + 一般 RAM 磁碟機的運作方式與現有的復原程序類似,但核心會從 boot 映像檔載入,而非從 recovery 映像檔載入。還原模式的啟動程序如下所示。

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

    1. 將復原 + vendor_boot + 通用 RAM 磁碟推送至 /。(如果 OEM 廠商透過將核心模組新增至 BOARD_RECOVERY_KERNEL_MODULES 來複製救援 RAM 磁碟區中的核心模組,則 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 快閃磁碟包含快閃磁碟和供應商核心模組的供應商位元,包括以下項目:

  • 裝置專屬 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 (來自 RAM 磁碟,由 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

如要新增第一階段主控台所需的模組 (例如 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 + 通用 RAM 磁碟與現有的啟動程序類似,差別只在於 fstab 會從 vendor_boot 載入。由於 system/bin/recovery 不存在,first_stage_init 會將其視為一般啟動。

在啟動至復原模式時,啟動程序不會改變。還原 RAM 磁碟機的載入方式與現有還原程序相同。核心會從 recovery 映像檔載入。復原模式的啟動程序如下所示。

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

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

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

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

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