在 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,無專屬救援方式
圖 1. 搭載 Android 13 或升級至 Android 13 的裝置未具備專屬復原機制。
推出時搭載 Android 13、專屬和 A/B 復原 (專屬 RAM 磁碟)
圖 2. 搭載 GKI、專屬和 A/B 復原功能,並升級至 Android 13 的裝置。
請參考此圖表,瞭解裝置是否有 recovery_a
和 recovery_b
分區。
啟動時搭載 Android 13,專用和非 A/B 復原功能 (專屬 ramdisk)
圖 3. 搭載 GKI、專屬和非 A/B 復原功能,並且已推出或升級至 Android 13 的裝置。
如果裝置有名稱為 recovery
的區隔,但沒有插槽後置字串,請參閱這張圖片。
推出或升級至 Android 12,不需專用復原程序
圖 4. 搭載 Android 12 或升級至 Android 12 的裝置 (GKI 無專用復原機制)。
啟動或升級至 Android 12,專用和 A/B 復原 (專用 RAM 磁碟)
圖 5. 搭載 GKI、專屬和 A/B 復原功能,並啟動或升級至 Android 12 的裝置。
如果裝置有 recovery_a
和 recovery_b
分區,請參閱這張圖片。
啟動或升級至 Android 12,專用和非 A/B 復原 (專用 RAM 磁碟)
圖 6. 推出或升級至 Android 12 的裝置,搭載 GKI 和非 A/B 復原功能。
如果裝置有名稱為 recovery
的區隔,但沒有插槽後置字串,請參閱這張圖片。
升級至 Android 12,並使用「recovery-as-boot」(recovery-as-ramdisk)
圖 7. 升級至 Android 12 的裝置,沒有 GKI,啟動時執行復原作業。
升級至 Android 12,專用復原 (專用 RAM 磁碟)
圖 8. 升級至 Android 12 的裝置,沒有 GKI,專用復原。
開機映像檔內容
Android 啟動映像檔包含下列項目:
init_boot
為搭載 Android 13 的裝置新增圖片- 標頭版本 V4
- 通用 RAM 磁碟映像檔
通用
boot
圖片vendor_boot
映像檔 (詳情請參閱「供應商啟動分割區」)vendor_boot
標頭- 裝置專屬
cmdline
(BOARD_KERNEL_CMDLINE
)
- 裝置專屬
vendor_boot
隨機存取磁碟映像檔lib/modules
- 復原資源 (如果沒有專屬復原作業)
dtb
的圖片
recovery
的圖片- 標頭版本 2
- 視需要使用裝置專屬的
cmdline
進行復原 - 如果是非 A/B 復原分區,標頭內容必須單獨使用;請參閱「復原映像檔」。例如:
cmdline
未連接至boot
和vendor_boot
cmdline
。- 標頭會在必要時指定復原 DTBO。
- 對於 A/B 復原分割區,您可以從
boot
和vendor_boot
串連或推斷內容。例如: cmdline
會串連為boot
和vendor_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
二進位檔遮蔽。
- 標頭版本 2
一般 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_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。這個變數不會影響 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/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
,並設定大小。設定後,一般 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
必須為 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
如需範例,請參閱這項變更。
以系統為根目錄
使用 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
設為空白。在此情況下,系統會採用新設定。遇到這類裝置時的處理方式:
搭載 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
快取磁碟可包含 /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 \
這可確保 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 \
如需範例,請參閱這個變更清單。
虛擬 A/B 壓縮
如要支援虛擬 A/B 壓縮,snapuserd
必須安裝至 vendor_ramdisk
。裝置應繼承自 virtual_ab_ota/compression.mk
,後者會安裝 snapuserd
的 vendor_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_a
和 recovery_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 \
這可確保 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 \
如需範例,請參閱這份變更清單。
虛擬 A/B 壓縮
如要支援虛擬 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
來複製核心模組,則可選用vendor_boot
。 - 從
boot
分區執行核心。
- 將復原 +
核心會將 RAM 磁碟掛載至
/
,然後從一般 RAM 磁碟執行/init
。第一階段初始化作業會開始,然後執行下列操作:
- 設定
IsRecoveryMode() == true
和ForceNormalBoot() == false
。 - 從
/lib/modules
載入供應商核心模組。 - 呼叫
DoFirstStageMount()
,但因為IsRecoveryMode() == true
而略過掛接程序。(裝置不會釋放 ramdisk (因為/
仍相同),但會呼叫SetInitAvbVersionInRecovery()
)。 - 從
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_ramdisk
和 recovery
RAM 磁碟。如需範例,請參閱這項變更。
安裝模組
您可以將裝置專屬模組安裝到 vendor_ramdisk
和 recovery
的 RAM 磁碟區 (如果沒有任何裝置專屬模組可安裝,請略過這個步驟)。init
不會切換根目錄。模組的 vendor_ramdisk
變化版本會安裝至 vendor_ramdisk
的根目錄。模組的 recovery
變化版本會安裝至 recovery
快取磁碟的根目錄。如需將模組安裝至 vendor_ramdisk
和 recovery
RAM 磁碟的範例,請參閱「第一階段主控台」和「中繼資料總和檢查碼」。
第一階段控制台
如要安裝模組的 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
。
如要新增第一個階段主控台所需的模組 (例如 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
映像檔載入。復原模式的啟動程序如下所示。
啟動載入器會啟動,然後執行下列操作:
- 將復原 RAM 磁碟推送至
/
。 - 從
recovery
分區執行核心。
- 將復原 RAM 磁碟推送至
核心會將 RAM 磁碟掛載至
/
,然後執行/init
,這是recovery
RAM 磁碟的/system/bin/init
符號連結。第一個階段 init 會啟動,然後執行以下操作:
- 設定
IsRecoveryMode() == true
和ForceNormalBoot() == false
。 - 從
/lib/modules
載入供應商核心模組。 - 呼叫
DoFirstStageMount()
,但因為IsRecoveryMode() == true
而略過掛接程序。(裝置不會釋放 ramdisk (因為/
仍相同),但會呼叫SetInitAvbVersionInRecovery()
)。 - 從
/system/bin/init
從recovery
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
圖片時間戳記屬性。