Các nhà sản xuất thiết bị gốc (OEM) và nhà cung cấp SoC muốn triển khai bản cập nhật hệ thống A/B phải đảm bảo trình tải khởi động của họ triển khai HAL boot_control và truyền các thông số chính xác đến nhân.
Triển khai HAL điều khiển khởi động
Trình tải khởi động có khả năng A/B phải triển khai HAL boot_control
tại hardware/libhardware/include/hardware/boot_control.h
. Bạn có thể kiểm thử quá trình triển khai bằng tiện ích system/extras/bootctl
và system/extras/tests/bootloader/
.
Bạn cũng phải triển khai máy trạng thái như minh hoạ bên dưới:

Thiết lập hạt nhân
Cách triển khai bản cập nhật hệ thống A/B:
-
Chọn các loạt bản vá hạt nhân sau (nếu cần):
- Nếu khởi động mà không có ramdisk và sử dụng "khởi động dưới dạng khôi phục", hãy chọn lọc android-review.googlesource.com/#/c/158491/.
- Để thiết lập dm-verity mà không cần ramdisk, hãy chọn lọc android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18.
-
Đảm bảo các đối số dòng lệnh của hạt nhân chứa các đối số bổ sung sau:
... trong đó giá trịskip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity <public-key-id> <path-to-system-partition>"
<public-key-id>
là mã nhận dạng của khoá công khai dùng để xác minh chữ ký bảng verity (để biết thông tin chi tiết, hãy xem dm-verity). -
Thêm chứng chỉ .X509 chứa khoá công khai vào chuỗi khoá hệ thống:
-
Sao chép chứng chỉ .X509 được định dạng ở định dạng
.der
vào thư mục gốc của thư mụckernel
. Nếu chứng chỉ .X509 được định dạng dưới dạng tệp.pem
, hãy sử dụng lệnhopenssl
sau để chuyển đổi từ định dạng.pem
sang.der
:openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
-
Tạo
zImage
để đưa chứng chỉ vào chuỗi khoá hệ thống. Để xác minh,hãy kiểm tra mục nhậpprocfs
(yêu cầu bậtKEYS_CONFIG_DEBUG_PROC_KEYS
): Việc đưa chứng chỉ .X509 vào thành công cho biết có khoá công khai trong khoá hệ thống (đánh dấu là mã khoá công khai).angler:/# cat /proc/keys 1c8a217e I------ 1 perm 1f010000 0 0 asymmetri Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f [] 2d454e3e I------ 1 perm 1f030000 0 0 keyring .system_keyring: 1/4
-
Thay thế dấu cách bằng
#
và truyền dấu cách đó dưới dạng<public-key-id>
trong dòng lệnh hạt nhân. Ví dụ: truyềnAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
thay vì<public-key-id>
.
-
Sao chép chứng chỉ .X509 được định dạng ở định dạng
Đặt biến bản dựng
Trình tải khởi động có khả năng A/B phải đáp ứng các tiêu chí sau đây về biến bản dựng:
Phải xác định cho mục tiêu thử nghiệm A/B |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk . Bạn có thể tuỳ ý thực hiện bước dex2oat sau khi cài đặt (nhưng trước khi khởi động lại) được mô tả trong phần Biên dịch.
|
---|---|
Rất nên dùng cho mục tiêu thử nghiệm A/B |
|
Không thể xác định cho mục tiêu thử nghiệm A/B |
|
Không bắt buộc đối với bản gỡ lỗi | PRODUCT_PACKAGES_DEBUG += update_engine_client |
Đặt các phân vùng (khe)
Thiết bị A/B không cần phân vùng khôi phục hoặc phân vùng bộ nhớ đệm vì Android không còn sử dụng các phân vùng này. Phân vùng dữ liệu hiện được dùng cho gói OTA đã tải xuống và mã hình ảnh khôi phục nằm trên phân vùng khởi động. Tất cả các phân vùng được phân chia theo A/B phải được đặt tên như sau (các khe luôn được đặt tên là a
, b
, v.v.): boot_a
,
boot_b
, system_a
, system_b
, vendor_a
,
vendor_b
.
Bộ nhớ đệm
Đối với các bản cập nhật không phải A/B, phân vùng bộ nhớ đệm được dùng để lưu trữ các gói OTA đã tải xuống và để tạm thời lưu trữ các khối trong khi áp dụng bản cập nhật. Không bao giờ có cách tốt để xác định kích thước phân vùng bộ nhớ đệm: kích thước cần thiết phụ thuộc vào nội dung cập nhật mà bạn muốn áp dụng. Trường hợp xấu nhất sẽ là phân vùng bộ nhớ đệm lớn bằng hình ảnh hệ thống. Với bản cập nhật A/B, bạn không cần lưu trữ các khối (vì bạn luôn ghi vào một phân vùng hiện không được sử dụng) và với tính năng truyền trực tuyến A/B, bạn không cần tải toàn bộ gói OTA xuống trước khi áp dụng.
Khôi phục
Đĩa RAM khôi phục hiện nằm trong tệp boot.img
. Khi chuyển sang chế độ khôi phục, trình tải khởi động không thể đặt tuỳ chọn skip_initramfs
trên dòng lệnh hạt nhân.
Đối với các bản cập nhật không phải A/B, phân vùng khôi phục chứa mã dùng để áp dụng các bản cập nhật. Bản cập nhật A/B được áp dụng bằng update_engine
chạy trong hình ảnh hệ thống khởi động thông thường.
Vẫn có một chế độ khôi phục được dùng để triển khai tính năng đặt lại dữ liệu về trạng thái ban đầu và tải không qua cửa hàng của các gói cập nhật (đây là nguồn gốc của tên "khôi phục"). Mã và dữ liệu cho chế độ khôi phục được lưu trữ trong phân vùng khởi động thông thường trong một ổ đĩa RAM; để khởi động vào hình ảnh hệ thống, trình tải khởi động sẽ yêu cầu hạt nhân bỏ qua ổ đĩa RAM (nếu không, thiết bị sẽ khởi động vào chế độ khôi phục). Chế độ khôi phục có kích thước nhỏ (và phần lớn đã có trên phân vùng khởi động), vì vậy, phân vùng khởi động không tăng kích thước.
Fstab
Đối số slotselect
phải nằm trên dòng cho các phân vùng A/B. Ví dụ:
<path-to-block-device>/vendor /vendor ext4 ro wait,verify=<path-to-block-device>/metadata,slotselect
Không được đặt tên phân vùng là vendor
. Thay vào đó, phân vùng vendor_a
hoặc vendor_b
sẽ được chọn và gắn trên điểm gắn /vendor
.
Đối số khe nhân
Hậu tố của khe hiện tại phải được truyền thông qua một nút cây thiết bị (DT) cụ thể (/firmware/android/slot_suffix
) hoặc thông qua dòng lệnh hạt nhân androidboot.slot_suffix
hoặc đối số bootconfig.
Theo mặc định, tính năng khởi động nhanh sẽ cài đặt ROM cho khe hiện tại trên thiết bị A/B. Nếu gói cập nhật cũng chứa hình ảnh cho khe khác không phải khe hiện tại, thì tính năng khởi động nhanh cũng sẽ cài đặt nhanh các hình ảnh đó. Có các lựa chọn sau:
-
--slot SLOT
. Ghi đè hành vi mặc định và nhắc tính năng khởi động nhanh cài đặt ROM cho khe được truyền vào dưới dạng đối số. -
--set-active [SLOT]
. Đặt vị trí thành đang hoạt động. Nếu không chỉ định đối số tuỳ chọn, thì vị trí hiện tại sẽ được đặt thành đang hoạt động. fastboot --help
. Xem thông tin chi tiết về các lệnh.
Nếu trình tải khởi động triển khai tính năng khởi động nhanh, thì trình tải khởi động đó phải hỗ trợ lệnh set_active <slot>
đặt khe đang hoạt động hiện tại thành khe đã cho (lệnh này cũng phải xoá cờ không thể khởi động cho khe đó và đặt lại số lần thử lại thành giá trị mặc định). Trình tải khởi động cũng phải hỗ trợ các biến sau:
-
has-slot:<partition-base-name-without-suffix>
. Trả về "yes" nếu phân vùng đã cho hỗ trợ khe, "no" nếu không. current-slot
. Trả về hậu tố của khe sẽ được khởi động từ lần tiếp theo.-
slot-count
. Trả về một số nguyên đại diện cho số lượng vị trí có sẵn. Hiện tại, hai khe được hỗ trợ nên giá trị này là2
. -
slot-successful:<slot-suffix>
. Trả về "yes" nếu khe đã cho được đánh dấu là khởi động thành công, "no" nếu không. -
slot-unbootable:<slot-suffix>
. Trả về "yes" nếu khe được chỉ định được đánh dấu là không thể khởi động, "no" nếu không. -
slot-retry-count:<slot-suffix>
. Số lần thử lại còn lại để cố gắng khởi động khe đã cho.
Để xem tất cả biến, hãy chạy fastboot getvar all
.
Tạo gói OTA
Công cụ gói OTA tuân theo các lệnh tương tự như lệnh dành cho thiết bị không phải A/B. Bạn phải tạo tệp target_files.zip
bằng cách xác định các biến bản dựng cho mục tiêu A/B. Các công cụ gói OTA sẽ tự động xác định và tạo các gói ở định dạng cho trình cập nhật A/B.
Ví dụ:
-
Cách tạo bản cập nhật OTA đầy đủ:
./build/make/tools/releasetools/ota_from_target_files \ dist_output/tardis-target_files.zip \ ota_update.zip
-
Cách tạo bản cập nhật OTA gia tăng:
./build/make/tools/releasetools/ota_from_target_files \ -i PREVIOUS-tardis-target_files.zip \ dist_output/tardis-target_files.zip \ incremental_ota_update.zip
Định cấu hình các phân vùng
update_engine
có thể cập nhật bất kỳ cặp phân vùng A/B nào được xác định trong cùng một ổ đĩa.
Một cặp phân vùng có một tiền tố chung (chẳng hạn như system
hoặc boot
) và hậu tố trên mỗi khe (chẳng hạn như _a
). Danh sách các phân vùng mà trình tạo tải trọng xác định bản cập nhật được định cấu hình bằng biến tạo AB_OTA_PARTITIONS
.
Ví dụ: nếu một cặp phân vùng bootloader_a
và booloader_b
được đưa vào (_a
và _b
là hậu tố của khe), bạn có thể cập nhật các phân vùng này bằng cách chỉ định những thông tin sau trên cấu hình sản phẩm hoặc bo mạch:
AB_OTA_PARTITIONS := \ boot \ system \ bootloader
Tất cả các phân vùng do update_engine
cập nhật không được phần còn lại của hệ thống sửa đổi. Trong quá trình cập nhật gia tăng hoặc delta, dữ liệu nhị phân từ khe hiện tại được dùng để tạo dữ liệu trong khe mới. Mọi nội dung sửa đổi đều có thể khiến dữ liệu về khung giờ mới không được xác minh trong quá trình cập nhật, do đó, quá trình cập nhật sẽ không thành công.
Định cấu hình sau khi cài đặt
Bạn có thể định cấu hình bước cài đặt sau cho từng phân vùng đã cập nhật theo cách khác nhau bằng cách sử dụng một tập hợp các cặp khoá-giá trị. Để chạy một chương trình nằm ở /system/usr/bin/postinst
trong một hình ảnh mới, hãy chỉ định đường dẫn tương ứng với thư mục gốc của hệ thống tệp trong phân vùng hệ thống.
Ví dụ: usr/bin/postinst
là system/usr/bin/postinst
(nếu không sử dụng ổ RAM). Ngoài ra, hãy chỉ định loại hệ thống tệp để truyền đến lệnh gọi hệ thống mount(2)
. Thêm nội dung sau vào tệp .mk
của sản phẩm hoặc thiết bị (nếu có):
AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=usr/bin/postinst \ FILESYSTEM_TYPE_system=ext4
Biên dịch ứng dụng
Bạn có thể biên dịch ứng dụng ở chế độ nền trước khi khởi động lại bằng hình ảnh hệ thống mới. Để biên dịch các ứng dụng ở chế độ nền, hãy thêm nội dung sau vào cấu hình thiết bị của sản phẩm (trong device.mk của sản phẩm):
-
Thêm các thành phần gốc vào bản dựng để đảm bảo tập lệnh biên dịch và tệp nhị phân được biên dịch và đưa vào hình ảnh hệ thống.
# A/B OTA dexopt package PRODUCT_PACKAGES += otapreopt_script
-
Kết nối tập lệnh biên dịch với
update_engine
để chạy dưới dạng bước sau khi cài đặt.# A/B OTA dexopt update_engine hookup AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=system/bin/otapreopt_script \ FILESYSTEM_TYPE_system=ext4 \ POSTINSTALL_OPTIONAL_system=true
Để được trợ giúp cài đặt các tệp được chọn trước trong phân vùng hệ thống thứ hai không sử dụng, hãy tham khảo phần Cài đặt tệp DEX_PREOPT trong lần khởi động đầu tiên.