Các nhà cung cấp OEM và SoC muốn triển khai các bản cập nhật hệ thống A/B phải đảm bảo bộ tải khởi động của họ triển khai boot_control HAL và chuyển các tham số chính xác đến kernel.
Triển khai HAL kiểm soát khởi động
Bộ tải khởi động có khả năng A/B phải triển khai boot_control
HAL tại hardware/libhardware/include/hardware/boot_control.h
. Bạn có thể kiểm tra việc triển khai bằng cách sử dụ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 được hiển thị bên dưới:

Thiết lập hạt nhân
Để triển khai cập nhật hệ thống A/B:
- Cherrypick loạt bản vá kernel 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 recovery", Cherrypick android-review.googlesource.com/#/c/158491/ .
- Để thiết lập dm-verity mà không cần ramdisk, hãy Cherrypick 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 kernel chứa các đối số bổ sung sau:
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à ID của khóa chung được sử dụng để xác minh chữ ký bảng xác thực (để biết chi tiết, xem dm-verity ) . - Thêm chứng chỉ .X509 chứa khóa chung vào khóa 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ủakernel
. 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>
- Xây dựng
zImage
để bao gồm chứng chỉ như một phần của khóa 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
):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
Việc bao gồm thành công chứng chỉ .X509 cho biết sự hiện diện của khóa chung trong khóa hệ thống (đánh dấu biểu thị ID khóa chung). - Thay thế khoảng trắng bằng
#
và chuyển nó dưới dạng<public-key-id>
trong dòng lệnh kernel. Ví dụ: chuyểnAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
thay cho<public-key-id>
.
- Sao chép chứng chỉ .X509 được định dạng ở định dạng
Đặt biến xây dựng
Bộ tải khởi động có khả năng A/B phải đáp ứng các tiêu chí về biến bản dựng sau:
Phải xác định cho mục tiêu A/B |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk . Bạn có thể tùy ý tiến hành bước dex2oat sau cài đặt (nhưng trước khi khởi động lại) được mô tả trong Biên dịch . |
---|---|
Rất khuyến khích cho mục tiêu A/B |
|
Không thể xác định cho mục tiêu A/B |
|
Tùy chọn cho bản dựng gỡ lỗi | PRODUCT_PACKAGES_DEBUG += update_engine_client |
Đặt phân vùng (khe cắm)
Thiết bị A/B không cần phân vùng khôi phục hoặc phân vùng bộ đệm vì Android không còn sử dụng các phân vùng này nữa. Phân vùng dữ liệu hiện được sử 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 là A/B-ed phải được đặt tên như sau (các vị trí 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ộ đệm được sử 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 các bản cập nhật. Chưa bao giờ có cách tốt để xác định kích thước phân vùng bộ đệm: kích thước của nó cần lớn đến mức nào tùy thuộc vào bản cập nhật bạn muốn áp dụng. Trường hợp xấu nhất sẽ là phân vùng bộ đệm có kích thước lớn bằng hình ảnh hệ thống. Với các bản cập nhật A/B, bạn không cần phải 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 phát trực tuyến A/B, bạn không cần phải tải xuống toàn bộ gói OTA trước khi áp dụng.
Sự hồi phục
Đĩa RAM khôi phục hiện được chứa trong tệp boot.img
. Khi vào recovery, bootloader không thể đặt tùy chọn skip_initramfs
trên dòng lệnh kernel.
Đố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ã được sử dụng để áp dụng các bản cập nhật. Cập nhật A/B được áp dụng bởi update_engine
chạy trong hình ảnh hệ thống được khởi động thông thường. Vẫn còn một chế độ khôi phục được sử dụng để thực hiện thiết lập lại dữ liệu ban đầu và tải các gói cập nhật (đó 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 đĩa RAM; để khởi động vào hình ảnh hệ thống, bộ nạp khởi động sẽ báo cho kernel bỏ qua đĩa RAM (nếu không thiết bị sẽ khởi động vào chế độ recovery. Chế độ recovery nhỏ (và phần lớn đã có trên phân vùng khởi động), do đó phân vùng khởi động không tăng về kích thước.
fstab
Đối số slotselect
phải nằm trên dòng dành cho phân vùng A/B-ed. Ví dụ:
<path-to-block-device>/vendor /vendor ext4 ro wait,verify=<path-to-block-device>/metadata,slotselect
Không có phân vùng nào được đặt tên là vendor
. Thay vào đó, phân vùng vendor_a
hoặc vendor_b
sẽ được chọn và gắn vào điểm gắn kết /vendor
.
Đối số vùng hạt nhân
Hậu tố vị trí hiện tại phải được chuyển qua nút cây thiết bị (DT) cụ thể ( /firmware/android/slot_suffix
) hoặc thông qua dòng lệnh kernel androidboot.slot_suffix
hoặc đối số bootconfig.
Theo mặc định, fastboot flash slot 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 cắm không hiện tại khác, fastboot cũng sẽ nhấp nháy những hình ảnh đó. Các tùy chọn có sẵn bao gồm:
-
--slot SLOT
. Ghi đè hành vi mặc định và nhắc fastboot flash slot được chuyển vào làm đối số. -
--set-active [ SLOT ]
. Đặt vị trí là hoạt động. Nếu không có đối số tùy chọn nào được chỉ định thì vị trí hiện tại được đặt là hoạt động. -
fastboot --help
. Nhận thông tin chi tiết về các lệnh.
Nếu bộ nạp khởi động triển khai fastboot, nó sẽ hỗ trợ lệnh set_active <slot>
để đặt vị trí hoạt động hiện tại vào vị trí nhất định (điều này cũng phải xóa cờ không thể khởi động cho vị trí đó và đặt lại số lần thử lại về giá trị mặc định). Bộ 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ề “có” nếu phân vùng đã cho hỗ trợ các khe cắm, nếu không thì trả về “không”. -
current-slot
. Trả về hậu tố vị trí sẽ được khởi động từ lần tiếp theo. -
slot-count
. Trả về một số nguyên biểu thị số lượng vị trí có sẵn. Hiện tại, hai vị trí được hỗ trợ nên giá trị này là2
. -
slot-successful:<slot-suffix>
. Trả về "có" nếu vị trí đã cho đã được đánh dấu là khởi động thành công, nếu không thì trả về "không". -
slot-unbootable:<slot-suffix>
. Trả về “có” nếu vị trí đã cho được đánh dấu là không thể khởi động được, nếu không thì trả về "không". -
slot-retry-count
. Số lần thử lại còn lại để cố gắng khởi động vị trí đã cho.
Để xem tất cả các biến, hãy chạy fastboot getvar all
.
Tạo gói OTA
Các công cụ gói OTA tuân theo các lệnh tương tự như các lệnh dành cho thiết bị không phải A/B. Tệp target_files.zip
phải được tạo bằng cách xác định các biến xây dựng cho mục tiêu A/B. Các công cụ gói OTA tự động xác định và tạo các gói theo định dạng dành cho trình cập nhật A/B.
Ví dụ:
- Để tạo OTA đầy đủ:
./build/make/tools/releasetools/ota_from_target_files \ dist_output/tardis-target_files.zip \ ota_update.zip
- Để tạo 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
Cấu hình 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ó tiền tố chung (chẳng hạn như system
hoặc boot
) và hậu tố trên mỗi vị trí (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ởi biến tạo AB_OTA_PARTITIONS
.
Ví dụ: nếu bao gồm một cặp phân vùng bootloader_a
và booloader_b
( _a
và _b
là hậu tố vị trí), bạn có thể cập nhật các phân vùng này bằng cách chỉ định các mục 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 được cập nhật bởi update_engine
không được sửa đổi bởi phần còn lại của hệ thống. Trong quá trình cập nhật tăng dần hoặc delta , dữ liệu nhị phân từ vị trí hiện tại được sử dụng để tạo dữ liệu trong vị trí mới. Bất kỳ sửa đổi nào cũng có thể khiến dữ liệu vị trí mới không được xác minh trong quá trình cập nhật và do đó không cập nhật được.
Định cấu hình cài đặt sau
Bạn có thể định cấu hình bước sau cài đặt khác nhau cho từng phân vùng được cập nhật bằng cách sử dụng một tập hợp các cặp khóa-giá trị. Để chạy chương trình có tại /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 đĩa RAM). Ngoài ra, chỉ định loại hệ thống tệp để chuyển tới lệnh gọi hệ thống mount(2)
. Thêm phần 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
Các ứng dụng có thể được biên dịch ở chế độ nền trước khi khởi động lại với hình ảnh hệ thống mới. Để biên dịch các ứng dụng ở chế độ nền, hãy thêm phần 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):
- Đưa 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à các 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
sao cho tập lệnh này chạy như một 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 chưa được sử dụng, hãy tham khảo Cài đặt lần khởi động đầu tiên của tệp DEX_PREOPT .