Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.

Triển khai cập nhật A / B

OEM và nhà cung cấp SoC muốn triển khai cập nhật hệ thống A / B phải đảm bảo bộ nạp khởi động của họ triển khai boot_control HAL và chuyển các tham số chính xác cho hạt nhân.

Triển khai điều khiển khởi động HAL

Bộ nạp 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/bootctlsystem/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:

Hình 1. Máy trạng thái Bootloader

Thiết lập nhân

Để triển khai cập nhật hệ thống A / B:

  1. Cherrypick loạt bản vá hạt nhân sau (nếu cần):
  2. Đảm bảo các đối số dòng lệnh hạt nhân 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>"
    ... trong đó giá trị <public-key-id> là ID của khóa công khai được sử dụng để xác minh chữ ký bảng verity (để biết chi tiết, xem dm-verity ) .
  3. Thêm chứng chỉ .X509 có chứa khóa công khai vào khóa hệ thống:
    1. 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ục kernel . Nếu chứng chỉ .X509 được định dạng dưới dạng tệp .pem , hãy sử dụng lệnh openssl sau để chuyển đổi từ định dạng .pem sang .der :
      openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
    2. 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ập procfs (yêu cầu KEYS_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 công khai trong khóa hệ thống (đánh dấu biểu thị ID khóa công khai).
    3. Thay thế khoảng trắng bằng # và chuyển nó thành <public-key-id> trong dòng lệnh kernel. Ví dụ: chuyển Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f thay cho <public-key-id> .

Đặt các biến bản dựng

Bộ nạp khởi động có khả năng A / B phải đáp ứng các tiêu chí biến xây dựng sau:

Phải xác định cho mục tiêu A / B
  • AB_OTA_UPDATER := true
  • AB_OTA_PARTITIONS := \
    boot \
    system \
    vendor
    và các phân vùng khác được cập nhật thông qua update_engine (radio, bootloader, v.v.)
  • PRODUCT_PACKAGES += \
    update_engine \
    update_verifier
Để có ví dụ, hãy tham khảo /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 .
Được đề xuất mạnh mẽ cho mục tiêu A / B
  • Xác định TARGET_NO_RECOVERY := true
  • Xác định BOARD_USES_RECOVERY_AS_BOOT := true
  • Không xác định BOARD_RECOVERYIMAGE_PARTITION_SIZE
Không thể xác định cho mục tiêu A / B
  • BOARD_CACHEIMAGE_PARTITION_SIZE
  • BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
Tùy chọn cho các bản dựng gỡ lỗi PRODUCT_PACKAGES_DEBUG += update_engine_client

Đặt phân vùng (vị trí)

Các 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ớ cache 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 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ộ nhớ cache được sử dụng để lưu trữ các gói OTA đã tải xuống và lưu trữ các khối tạm thời trong khi áp dụng các bản cập nhật. Không bao giờ có một cách tốt để định kích thước phân vùng bộ nhớ cache: nó cần phải có kích thước lớn như thế nào phụ thuộc vào những 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ộ nhớ cache 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 việc phát trực tuyến A / B, không cần tải xuống toàn bộ gói OTA trước khi áp dụng nó.

Sự hồi phục

Đĩa RAM khôi phục hiện được chứa trong tệp boot.img . Khi bắt đầu khôi phục, bộ nạp khởi động không thể đặt tùy 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ã đượ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ó 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à truyền tải các gói cập nhật (đó là nơi xuất phát tên "recovery"). 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 yêu cầu hạt nhân bỏ qua đĩa ram (nếu không thiết bị khởi động vào chế độ khôi phục. Chế độ khôi phục nhỏ (và phần lớn 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 về kích thước.

Fstab

slotselect số chọn vị trí phải nằm trên dòng cho các 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 nên đượ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 trên điểm gắn kết /vendor .

Đối số vị trí 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ị cụ thể (DT) ( /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, fastboot sẽ nhấp nháy khe cắm 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 vị trí khác, không phải hiện tại, 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 vị trí được chuyển vào dưới dạng đố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 bootloader triển khai fastboot, nó sẽ hỗ trợ lệnh set_active <slot> đặt vị trí hoạt động hiện tại thành vị trí đã cho (đ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ộ nạp 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 vị trí, nếu không thì trả về “không”.
  • current-slot . Trả về hậu tố vị trí sẽ được khởi động từ 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 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, "không" nếu 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, "không" nếu 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 các gói OTA

Các công cụ gói OTA tuân theo các lệnh tương tự như lệnh cho các 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 ở định dạng 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ố cho mỗi vị trí (chẳng hạn như _a ). Danh sách các phân vùng mà trình tạo trọng tải xác định bản cập nhật được cấu hình bởi biến AB_OTA_PARTITIONS .

Ví dụ: nếu một cặp phân vùng bootloader_abooloader_b được bao gồm ( _a_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 những điều sau trên sản phẩm hoặc cấu hình bo mạch:

AB_OTA_PARTITIONS := \
  boot \
  system \
  bootloader

Tất cả các phân vùng được update_engine cập nhật 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ó 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 đó cập nhật không thành công.

Định cấu hình sau cài đặt

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 một chương trình tại /system/usr/bin/postinst trong một hình ảnh mới, hãy chỉ định đường dẫn liên quan đến thư mục gốc của hệ thống tệp trong phân vùng hệ thống.

Ví dụ, usr/bin/postinstsystem/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 đến 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

Vì lý do bảo mật, system_server không thể sử dụng biên dịch chỉ trong thời gian (JIT) . Điều này có nghĩa là bạn phải biên dịch trước các tệp odex cho system_server và các phụ thuộc của nó ở mức tối thiểu; bất cứ điều gì khác là tùy chọn.

Để biên dịch ứng dụng ở chế độ nền, bạn phải thêm phần sau vào cấu hình thiết bị của sản phẩm (trong product.mk của sản phẩm):

  1. Bao gồm các thành phần gốc trong bản dựng để đảm bảo tập lệnh biên dịch và mã 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
    
  2. Kết nối tập lệnh biên dịch với update_engine để chạy như một bước sau 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 mở sẵn trong phân vùng hệ thống thứ hai không sử dụng, hãy tham khảo Cài đặt khởi động đầu tiên của tệp DEX_PREOPT .