Để triển khai A/B ảo trên thiết bị mới hoặc trang bị thêm cho thiết bị đã ra mắt, bạn phải thực hiện các thay đổi đối với mã dành riêng cho thiết bị.
dựng cờ
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 với các phân vùng động .
Đối với các thiết bị khởi chạy với A/B ảo, hãy đặt chúng 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 với A/B ảo chỉ cần kích thước bảng bằng một nửa cho BOARD_SUPER_PARTITION_SIZE
vì các vị trí B không còn ở dạng siêu nữa. Nghĩa là, BOARD_SUPER_PARTITION_SIZE
phải lớn hơn hoặc bằng tổng(kích thước của nhóm cập nhật) + tổng phí , do đó, phải lớn hơn hoặc bằng tổng (kích thước của phân vùng) + tổng phí .
Đối với Android 13 trở lên, để bật ảnh chụp nhanh được nén bằng Virtual A/B, 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/android_t_baseline.mk)
Điều này cho phép chụp nhanh không gian người dùng với A/B ảo trong khi sử dụng phương pháp nén không hoạt động. 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ợ, gz
và brotli
.
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := gz
Đối với Android 12, để bật ảnh chụp nhanh được nén bằng Virtual A/B, 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 phần 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
Đối với các thiết bị nâng cấp lên Android 13 trở lên, quy trình hợp nhất không gian người dùng như được mô tả trong Phân lớp trình ánh xạ thiết bị không được bật theo mặc định. Để bật hợp nhất không gian người dùng, hãy thêm dòng sau vào tệp .mk
của thiết bị:
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
Hợp nhất không gian người dùng được bật theo mặc định trên các thiết bị khởi chạy từ 13 trở lên.
Kiểm soát khởi động HAL
Điều khiển khởi động HAL cung cấp một giao diện cho các máy khách OTA để điều khiển các khe khởi động. A/B ảo yêu cầu nâng cấp phiên bản nhỏ của điều khiển khởi động HAL vì cần có các API bổ sung để đảm bảo bộ tải khởi động được bảo vệ trong quá trình flash/khôi phục cài đặt gốc. Xem IBootControl.hal và type.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
}
Fstab thay đổi
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, phân vùng siêu dữ liệu phải được kiểm tra trước khi first_stage_init
gắn nó. Để đảm bảo điều này xảy ra, hãy thêm cờ check
fs_mgr vào mục nhập cho /metadata
. Phần sau cung cấp 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 hạt nhân
Để bật tính năng chụp 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 người dùng để sửa lỗi ghim tệp. Bao gồm f2fs: cũng hỗ trợ bản vá nhân tệp được ghim thẳng hàng .
A/B ảo dựa trên các tính năng được thêm vào trong phiên bản nhân 4.3: bit trạng thái tràn trong snapshot
và các mục tiêu snapshot-merge
. Tất cả các thiết bị khởi chạy với Android 9 trở lên phải có kernel phiên bản 4.4 trở lên.
Để kích hoạt ảnh chụp nhanh được nén, phiên bản nhân 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 cũ (một mô-đun), mô-đun phải được nạp vào đĩa ram giai đoạn đầu. Điều này có thể đạt được 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
Trang bị thêm trên các thiết bị nâng cấp lên Android 11
Khi nâng cấp lên Android 11, các thiết bị khởi chạy với phân vùng động có thể tùy chọn trang bị thêm A/B ảo. Quá trình cập nhật hầu hết giống như đối với các thiết bị khởi chạy với A/B ảo, với một số khác biệt nhỏ:
Vị trí của tệp COW — Đối với thiết bị khởi chạy, ứng dụng khách OTA sử dụng tất cả dung lượng trống có sẵn trong siêu phân vùng trước khi sử dụng dung lượng trong
/data
. Đối với các thiết bị trang bị thêm, luôn có đủ dung lượng trong siêu phân vùng để tệp COW không bao giờ được tạo trên/data
.Cờ tính năng thời gian xây dựng — Đối với thiết bị trang bị thêm A/B ảo, cả
PRODUCT_VIRTUAL_AB_OTA
vàPRODUCT_VIRTUAL_AB_OTA_RETROFIT
đều được đặt thànhtrue
, như minh họa bên dưới:(call inherit-product, \
(SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
Kích thước siêu phân vùng — Các thiết bị khởi chạy với A/B ảo có thể cắt giảm một nửa
BOARD_SUPER_PARTITION_SIZE
vì các vị trí B không có trong siêu phân vùng. Các thiết bị trang bị thêm A/B ảo giữ nguyên kích thước siêu phân vùng cũ, vì vậyBOARD_SUPER_PARTITION_SIZE
lớn hơn hoặc bằng 2 * sum(size of update groups) + tổng chi phí , đến lượt nó lại lớn hơn hoặc bằng 2 * sum(size of partitions) + phí trên cao .
thay đổi bộ nạp khởi động
Trong bước hợp nhất của một bản cập nhật, /data
giữ toàn bộ phiên bản duy nhất của HĐH Android. Sau khi quá trình di chuyển bắt đầu, các phân vùng system
gốc, vendor
và product
chưa hoàn tất cho đến khi quá trình sao chép kết thúc. Nếu thiết bị được khôi phục cài đặt gốc trong quá trình này, bằng cách khôi phục hoặc thông qua hộp thoại Cài đặt hệ thống, thì thiết bị sẽ không thể khởi động được.
Trước khi xóa /data
, hãy kết thúc quá trình hợp nhất trong recovery hoặc rollback tùy thuộc vào trạng thái thiết bị:
- Nếu bản dựng mới đã khởi động thành công trước đó, hãy kết thúc quá trình di chuyển.
- Nếu không, hãy quay lại vị trí cũ:
- Đối với các phân vùng động, hãy quay lại trạng thái trước đó.
- Đối với các phân vùng tĩnh, hãy đặt vị trí hoạt động thành vị trí cũ.
Cả bootloader và fastbootd
đều có thể xóa phân vùng /data
nếu thiết bị được mở khóa. Mặc dù fastbootd
có thể buộc quá trình di chuyển hoàn tất nhưng bộ tải khởi động thì không thể. Bộ tải khởi động không biết liệu quá trình hợp nhất có đang diễn ra hay không hoặc khối nào trong /data
cấu thành các phân vùng HĐH. Các thiết bị phải ngăn người dùng vô tình làm cho thiết bị không thể hoạt động (cục gạch) bằng cách thực hiện như sau:
- Triển khai điều khiển khởi động HAL để bộ tải khởi động có thể đọc giá trị được đặt bởi phương thức
setSnapshotMergeStatus()
. - Nếu trạng thái hợp nhất là
MERGING
hoặc nếu trạng thái hợp nhất làSNAPSHOTTED
và vị trí đã thay đổi thành vị trí mới được cập nhật, thì yêu cầu xóauserdata
,metadata
hoặc phân vùng lưu trữ trạng thái hợp nhất phải bị từ chối trong bộ tải khởi động. - Triển khai lệnh
fastboot snapshot-update cancel
để người dùng có thể báo hiệu cho bộ tải khởi động rằng họ muốn bỏ qua cơ chế bảo vệ này. - Sửa đổi các công cụ hoặc tập lệnh flash tùy chỉnh để
fastboot snapshot-update cancel
khi flash toàn bộ thiết bị. Đây là vấn đề an toàn vì flash toàn bộ thiết bị sẽ loại bỏ OTA. Công cụ có thể phát hiện lệnh này trong thời gian chạy bằng cách triển khaifastboot getvar snapshot-update-status
. Lệnh này giúp phân biệt giữa các điều kiện lỗi.
Ví dụ
struct VirtualAbState {
uint8_t StructVersion;
uint8_t MergeStatus;
uint8_t SourceSlot;
};
bool ShouldPreventUserdataWipe() {
VirtualAbState state;
if (!ReadVirtualAbState(&state)) ...
return state.MergeStatus == MergeStatus::MERGING ||
(state.MergeStatus == MergeStatus::SNAPSHOTTED &&
state.SourceSlot != CurrentSlot()));
}
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à điều khiển khởi động HAL truyền tới bộ tải khởi động:- Nếu trạng thái là
MERGING
, bộ tải khởi động phải quay lạimerging
. - 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
.
- Nếu trạng thái là
-
snapshot-update merge
— Hoàn thành thao tác hợp nhất, khởi động vào recovery/fastbootd nếu cần. Lệnh này chỉ hợp lệ nếusnapshot-update-status
đangmerging
và chỉ được hỗ trợ trong fastbootd. -
snapshot-update cancel
— Đặt trạng thái hợp nhất của điều khiển khởi động HAL thànhCANCELLED
. Lệnh này không hợp lệ khi thiết bị bị khóa. -
erase
hoặcwipe
— Việcerase
hoặcwipe
metadata
,userdata
hoặc phân vùng giữ trạng thái hợp nhất cho điều khiển khởi động HAL 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ặcSNAPSHOTTED
, thiết bị sẽ hủy bỏ hoạt động. -
set_active
— Lệnhset_active
thay đổi vị trí 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ẽ hủy bỏ hoạt động. Vị trí có thể được thay đổi một cách an toàn ở trạng tháiSNAPSHOTTED
.
Những thay đổi này được thiết kế để ngăn việc vô tình làm cho thiết bị không thể khởi động được, nhưng chúng có thể gây gián đoạn cho công cụ tự động. Khi các lệnh được sử dụng như một thành phần của quá trình flash 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:
- Truy vấn
getvar snapshot-update-status
. - Nếu
merging
hoặcsnapshotted
, hãysnapshot-update cancel
. - Tiến hành các bước nhấp nháy.
Giảm yêu cầu lưu trữ
Các thiết bị không có bộ nhớ A/B đầy đủ được phân bổ trong super 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 việc 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 .
phương pháp nén OTA
Các gói Ota có thể được điều chỉnh cho các chỉ số hiệu suất khác nhau. Android hiện cung cấp một vài phương thức nén được hỗ trợ ( gz
, lz4
và none
) 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. Tùy chọn mặc định được bật cho ab ảo có nén là gz compression method
. (Lưu ý: hiệu suất tương đối giữa các phương pháp nén khác nhau tùy thuộc vào tốc độ CPU và thông lượng lưu trữ có thể thay đổi tùy theo thiết bị. Tất cả các gói OTA được tạo bên dưới đều bị vô hiệu hóa PostInstall, điều này sẽ làm chậm thời gian khởi động một chút. Tổng kích thước phân vùng động của một ota đầy đủ không nén là 4,81 GB ).
OTA gia tăng trên Pixel 6 Pro
Thời gian cài đặt không có giai đoạn hậu cài đặt | Sử dụng không gian COW | Đăng thời gian khởi động OTA | Thời gian hợp nhất ảnh chụp nhanh | |
---|---|---|---|---|
gz | 24 phút | 1,18 GB | 40,2 giây | 45,5 giây |
lz4 | 13 phút | 1,49 GB | 37,4 giây | 37,1 giây |
không có | 13 phút | 2,90 GB | 37,6 giây | 40,7 giây |
OTA đầy đủ trên Pixel 6 Pro
Thời gian cài đặt không có giai đoạn hậu cài đặt | Cách sử dụng không gian COW | Đăng thời gian khởi động OTA | Thời gian hợp nhất ảnh chụp nhanh | |
---|---|---|---|---|
gz | 23 phút | 2,79GB | 24,9 giây | 41,7 giây |
lz4 | 12 phút | 3,46 GB | 20,0 giây | 25,3 giây |
không có | 10 phút | 4,85 GB | 20,6 giây | 29,8 giây |