Triển khai thử nghiệm A/B ảo

Để triển khai A/B ảo trên một thiết bị mới hoặc trang bị thêm cho một thiết bị đã ra mắt, bạn phải thay đổi mã dành riêng cho thiết bị.

Cờ dựng

Các thiết bị sử dụng A/B ảo phải được định cấu hình là thiết bị A/B và phải khởi chạy bằng các phân vùng động.

Đối với các thiết bị khởi chạy bằng A/B ảo, hãy đặt các thiết bị đó để kế thừa cấu hình cơ sở của thiết bị A/B ảo:

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

Các thiết bị khởi chạy bằng A/B ảo chỉ cần một nửa kích thước bo mạch cho BOARD_SUPER_PARTITION_SIZE vì các khe B không còn nằm trong siêu phân vùng nữa. Tức là, BOARD_SUPER_PARTITION_SIZE phải lớn hơn hoặc bằng sum(size of update groups) + overhead, đến lượt nó phải lớn hơn hoặc bằng sum(size of partitions) + overhead.

Đối với Android 13 trở lên, để bật ảnh chụp nhanh được nén bằng A/B ảo, hãy kế thừa cấu hình cơ sở sau:

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

Điều này cho phép ảnh chụp nhanh trong không gian người dùng bằng A/B ảo trong khi sử dụng phương thức nén no-op. Sau đó, bạn có thể định cấu hình phương thức nén thành một trong các phương thức được hỗ trợ, zstdlz4. Đối với Android 15, bạn có thể tuỳ chỉnh thêm phương thức nén để phù hợp với nhu cầu của thiết bị. Để biết thêm thông tin, hãy xem Tinh chỉnh phương thức nén.

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536

Đối với Android 12, để bật ảnh chụp nhanh được nén bằng A/B ảo, hãy kế thừa cấu hình cơ sở sau:

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

Nén XOR

Đối với các thiết bị nâng cấp lên Android 13 trở lên, tính năng nén XOR không được bật theo mặc định. Để bật tính năng nén XOR, hãy thêm nội dung sau vào tệp .mk của thiết bị.

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true

Tính năng nén XOR được bật theo mặc định cho các thiết bị kế thừa từ android_t_baseline.mk.

Hợp nhất không gian người dùng

Trong phiên bản hiện đại của A/B ảo (Android T trở lên), quy trình hợp nhất ảnh chụp nhanh diễn ra hoàn toàn trong không gian người dùng. Thay đổi này được thực hiện nhờ snapuserd và dm-user. Các thiết bị khởi chạy bằng Android 13 trở lên được bật tính năng hợp nhất không gian người dùng theo mặc định và đối với các thiết bị cũ hơn nâng cấp, bạn có thể đặt thuộc tính này bằng cách sau:

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true

HAL kiểm soát quá trình khởi động

HAL kiểm soát quá trình khởi động cung cấp một giao diện để các ứng dụng OTA kiểm soát các khe khởi động. A/B ảo yêu cầu nâng cấp phiên bản nhỏ của HAL kiểm soát quá trình khởi động vì cần có các API bổ sung để đảm bảo trình tải khởi động được bảo vệ trong quá trình cài đặt ROM hoặc đặt lại về trạng thái ban đầu. Hãy xem IBootControl.haltypes.hal để biết phiên bản mới nhất của định nghĩa HAL.

// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
    NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };

// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
    setSnapshotMergeStatus(MergeStatus status)
        generates (bool success);
    getSnapshotMergeStatus()
        generates (MergeStatus status);
}
// Recommended implementation

Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
    // Write value to persistent storage
    // e.g. misc partition (using libbootloader_message)
    // bootloader rejects wipe when status is SNAPSHOTTED
    // or MERGING
}

Thay đổi Fstab

Tính toàn vẹn của phân vùng siêu dữ liệu là điều cần thiết cho quá trình khởi động, đặc biệt là ngay sau khi áp dụng bản cập nhật OTA. Vì vậy, bạn phải kiểm tra phân vùng siêu dữ liệu trước khi first_stage_init gắn phân vùng đó. Để đảm bảo điều này xảy ra, hãy thêm cờ fs_mgr check vào mục nhập cho /metadata. Sau đây là một ví dụ:

/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check

Yêu cầu về nhân hệ điều hành

Để bật tính năng chụp ảnh nhanh, hãy đặt CONFIG_DM_SNAPSHOT thành true.

Đối với các thiết bị sử dụng F2FS, hãy thêm cờ f2fs: export FS_NOCOW_FL vào bản vá nhân hệ điều hành của người dùng để khắc phục lỗi ghim tệp. Đồng thời thêm bản vá nhân hệ điều hành f2fs: support aligned pinned file.

A/B ảo dựa vào các tính năng được thêm vào phiên bản kernel 4.3: bit trạng thái overflow trong các mục tiêu snapshotsnapshot-merge. Tất cả các thiết bị khởi chạy bằng Android 9 trở lên đều đã có nhân hệ điều hành phiên bản 4.4 trở lên.

Để bật ảnh chụp nhanh được nén, phiên bản kernel tối thiểu được hỗ trợ là 4.19. Đặt CONFIG_DM_USER=m hoặc CONFIG_DM_USER=y. Nếu sử dụng mô-đun trước đó, mô-đun phải được tải trong ramdisk giai đoạn đầu. Bạn có thể thực hiện việc này bằng cách thêm dòng sau vào Makefile của thiết bị:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

Thay đổi công cụ Fastboot

Android 11 thực hiện các thay đổi sau đối với giao thức fastboot:

  • getvar snapshot-update-status – Trả về giá trị mà HAL kiểm soát quá trình khởi động đã truyền đạt cho trình tải khởi động:
    • Nếu trạng thái là MERGING, bộ tải khởi động phải trả về merging.
    • Nếu trạng thái là SNAPSHOTTED, bộ tải khởi động phải trả về snapshotted.
    • Nếu không, bộ tải khởi động phải trả về none.
  • snapshot-update merge – Hoàn tất thao tác hợp nhất, khởi động vào chế độ khôi phục/fastbootd nếu cần. Lệnh này chỉ hợp lệ nếu snapshot-update-statusmerging và chỉ được hỗ trợ trong fastbootd.
  • snapshot-update cancel – Đặt trạng thái hợp nhất của HAL kiểm soát quá trình khởi động thành CANCELLED. Lệnh này không hợp lệ khi thiết bị bị khoá.
  • erase hoặc wipe – Lệnh erase hoặc wipe của metadata, userdata hoặc một phân vùng giữ trạng thái hợp nhất cho HAL kiểm soát quá trình khởi động sẽ kiểm tra trạng thái hợp nhất ảnh chụp nhanh. Nếu trạng thái là MERGING hoặc SNAPSHOTTED, thiết bị sẽ huỷ thao tác.
  • set_active – Lệnh set_active thay đổi khe đang hoạt động sẽ kiểm tra trạng thái hợp nhất ảnh chụp nhanh. Nếu trạng thái là MERGING, thiết bị sẽ huỷ thao tác. Bạn có thể thay đổi khe một cách an toàn ở trạng thái SNAPSHOTTED.

Những thay đổi này được thiết kế để ngăn việc vô tình khiến thiết bị không khởi động được, nhưng có thể gây gián đoạn cho công cụ tự động. Khi các lệnh được dùng làm thành phần của việc ghi lại tất cả các phân vùng, chẳng hạn như chạy fastboot flashall, bạn nên sử dụng quy trình sau:

  1. Truy vấn getvar snapshot-update-status.
  2. Nếu merging hoặc snapshotted, hãy phát hành snapshot-update cancel.
  3. Tiến hành các bước ghi lại.

Giảm yêu cầu về bộ nhớ

Các thiết bị không được phân bổ đầy đủ bộ nhớ A/B trong siêu phân vùng và dự kiến sử dụng /data khi cần thiết nên sử dụng công cụ ánh xạ khối. Công cụ ánh xạ khối giúp phân bổ khối nhất quán giữa các bản dựng, giảm số lần ghi không cần thiết vào ảnh chụp nhanh. Điều này được ghi lại trong phần Giảm kích thước OTA.

Thuật toán nén OTA

Bạn có thể điều chỉnh các gói OTA cho nhiều chỉ số hiệu suất. Android cung cấp một số phương thức nén được hỗ trợ (lz4, zstdnone) có sự đánh đổi giữa thời gian cài đặt, mức sử dụng dung lượng COW, thời gian khởi động và thời gian hợp nhất ảnh chụp nhanh. Tuỳ chọn mặc định được bật cho ab ảo có phương thức nén là lz4 compression method.

Tinh chỉnh phương thức nén

Bạn có thể tuỳ chỉnh thêm các thuật toán nén thông qua 2 phương thức: (compression level) (mức nén đạt được với chi phí là tốc độ) và (compression factor) (kích thước cửa sổ nén tối đa). Mức nén có sẵn cho một số thuật toán như zstd và việc thay đổi mức này sẽ đánh đổi giữa tốc độ và tỷ lệ nén. Hệ số nén mô tả kích thước cửa sổ nén tối đa được sử dụng trong quá trình cài đặt OTA. Giá trị mặc định được đặt ở mức 64k, nhưng bạn có thể ghi đè bằng cách tuỳ chỉnh tham số bản dựng PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR. Các hệ số nén được hỗ trợ là 4k, 8k, 16k, 32k, 64k, 128k và 256k.

PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536

OTA gia tăng trên Pixel 8 Pro

Thời gian cài đặt không có giai đoạn postinstall Mức sử dụng dung lượng COW Thời gian khởi động sau OTA Thời gian hợp nhất ảnh chụp nhanh
lz4 18 phút 15 giây 2,5 GB 32,7 giây 98,6 giây
zstd 24 phút 49 giây 2,05 GB 36,3 giây 133,2 giây
none 16 phút 42 giây 4,76 GB 28,7 giây 76,6 giây

OTA đầy đủ trên Pixel 8 Pro

Thời gian cài đặt không có giai đoạn postinstall Mức sử dụng dung lượng COW Thời gian khởi động sau OTA Thời gian hợp nhất ảnh chụp nhanh
lz4 15 phút 11 giây 4,16 GB 17,6 giây 82,2 giây
zstd 16 phút 19 giây 3,46 GB 21,0 giây 106,3 giây
none 13 phút 33 giây 6,39 GB 18,5 giây 92,5 giây