Giảm kích thước OTA

Trang này mô tả các thay đổi được thêm vào AOSP để giảm các thay đổi không cần thiết đối với tệp giữa các bản dựng. Những người triển khai thiết bị duy trì hệ thống xây dựng của riêng họ có thể sử dụng thông tin này làm hướng dẫn để giảm kích thước của các bản cập nhật qua mạng không dây (OTA).

Đôi khi, bản cập nhật OTA của Android chứa các tệp đã thay đổi không tương ứng với các thay đổi về mã. Thực ra, đó là các cấu phần phần mềm của hệ thống xây dựng. Điều này có thể xảy ra khi cùng một mã, được tạo tại nhiều thời điểm, từ nhiều thư mục hoặc trên nhiều máy tạo ra một số lượng lớn tệp đã thay đổi. Những tệp thừa đó làm tăng kích thước của bản vá OTA và khiến bạn khó xác định mã nào đã thay đổi.

Để nội dung của bản cập nhật OTA trở nên minh bạch hơn, AOSP bao gồm các thay đổi về hệ thống xây dựng được thiết kế để giảm kích thước của các bản vá OTA. Các thay đổi tệp không cần thiết giữa các bản dựng đã được loại bỏ và chỉ có các tệp liên quan đến bản vá mới có trong bản cập nhật OTA. AOSP cũng bao gồm một công cụ so sánh bản dựng, giúp lọc ra các thay đổi tệp phổ biến liên quan đến bản dựng để cung cấp bản so sánh tệp bản dựng rõ ràng hơn và một công cụ ánh xạ khối giúp bạn duy trì tính nhất quán trong việc phân bổ khối.

Hệ thống xây dựng có thể tạo các bản vá lớn không cần thiết theo một số cách. Để giảm thiểu vấn đề này, trong Android 8.0 trở lên, các tính năng mới đã được triển khai để giảm kích thước bản vá cho mỗi tệp khác biệt. Các điểm cải tiến giúp giảm kích thước gói cập nhật OTA bao gồm:

  • Sử dụng ZSTD, một thuật toán nén không tổn hao, dùng cho nhiều mục đích cho hình ảnh đầy đủ trên các bản cập nhật thiết bị không phải A/B. Bạn có thể tuỳ chỉnh ZSTD để có tỷ lệ nén cao hơn bằng cách tăng mức độ nén. Mức độ nén được đặt trong thời gian tạo OTA và có thể được đặt bằng cách truyền cờ --vabc_compression_param=zstd,$COMPRESSION_LEVEL
  • Tăng kích thước cửa sổ nén được sử dụng trong quá trình OTA. Bạn có thể đặt kích thước cửa sổ nén tối đa bằng cách tuỳ chỉnh tham số bản dựng trong tệp .mk của thiết bị. Biến này được đặt thành PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144
  • Sử dụng tính năng nén lại Puffin, một công cụ vá xác định cho các luồng giảm áp, xử lý các hàm nén và diff để tạo bản cập nhật OTA A/B.
  • Thay đổi đối với cách sử dụng công cụ tạo delta, chẳng hạn như cách thư viện bsdiff được dùng để nén các bản vá. Trong Android 9 trở lên, công cụ bsdiff sẽ chọn thuật toán nén mang lại kết quả nén tốt nhất cho một bản vá.
  • Các điểm cải tiến đối với update_engine đã giúp giảm mức sử dụng bộ nhớ khi áp dụng các bản vá cho bản cập nhật thiết bị A/B.

Các phần sau đây thảo luận về nhiều vấn đề ảnh hưởng đến kích thước bản cập nhật OTA, giải pháp cho các vấn đề đó và ví dụ về cách triển khai trong AOSP.

Thứ tự tệp

Vấn đề: Hệ thống tệp không đảm bảo thứ tự tệp khi được yêu cầu cung cấp danh sách tệp trong một thư mục, mặc dù thứ tự này thường giống nhau đối với cùng một lượt thanh toán. Các công cụ như ls sắp xếp kết quả theo mặc định, nhưng hàm ký tự đại diện mà các lệnh như findmake sử dụng thì không sắp xếp. Trước khi sử dụng các công cụ này, bạn phải sắp xếp đầu ra.

Giải pháp: Khi bạn sử dụng các công cụ như findmake với hàm ký tự đại diện, hãy sắp xếp đầu ra của các lệnh này trước khi sử dụng. Khi sử dụng $(wildcard) hoặc $(shell find) trong các tệp Android.mk, hãy sắp xếp các tệp đó. Một số công cụ, chẳng hạn như Java, sẽ sắp xếp dữ liệu đầu vào, vì vậy, trước khi bạn sắp xếp các tệp, hãy xác minh rằng công cụ bạn đang sử dụng chưa thực hiện việc này.

Ví dụ: Nhiều thực thể đã được khắc phục trong hệ thống xây dựng cốt lõi bằng cách sử dụng macro all-*-files-under tích hợp, bao gồm cả all-cpp-files-under (vì một số định nghĩa đã được phân tán trong các tệp makefile khác). Để biết thông tin chi tiết, hãy tham khảo các nội dung sau:

Thư mục bản dựng

Vấn đề: Việc thay đổi thư mục tạo ra các tệp có thể khiến các tệp nhị phân khác nhau. Hầu hết các đường dẫn trong bản dựng Android đều là đường dẫn tương đối, vì vậy, __FILE__ trong C/C++ không phải là vấn đề. Tuy nhiên, theo mặc định, các ký hiệu gỡ lỗi sẽ mã hoá đường dẫn đầy đủ và .note.gnu.build-id được tạo bằng cách băm tệp nhị phân đã loại bỏ trước đó, vì vậy, đường dẫn này sẽ thay đổi nếu các ký hiệu gỡ lỗi thay đổi.

Giải pháp: AOSP hiện tạo các đường dẫn gỡ lỗi tương đối. Để biết thông tin chi tiết, hãy tham khảo CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02.

Dấu thời gian

Vấn đề: Dấu thời gian trong kết quả bản dựng dẫn đến các thay đổi không cần thiết đối với tệp. Điều này có thể xảy ra ở các vị trí sau:

  • Macro __DATE__/__TIME__/__TIMESTAMP__ trong mã C hoặc C++.
  • Dấu thời gian được nhúng trong các tệp lưu trữ dựa trên zip.

Giải pháp/Ví dụ: Để xoá dấu thời gian khỏi đầu ra bản dựng, hãy sử dụng hướng dẫn bên dưới trong __DATE__/__TIME__/__TIMESTAMP__ trong C/C++.Dấu thời gian được nhúng trong tệp lưu trữ.

__DATE__/__TIME__/__TIMESTAMP__ trong C/C++

Các macro này luôn tạo ra kết quả khác nhau cho các bản dựng khác nhau, vì vậy, đừng sử dụng các macro này. Dưới đây là một số tuỳ chọn để loại bỏ các macro này:

Dấu thời gian được nhúng trong các bản lưu trữ (zip, jar)

Android 7.0 đã khắc phục vấn đề về dấu thời gian được nhúng trong tệp lưu trữ zip bằng cách thêm -X vào tất cả các trường hợp sử dụng lệnh zip. Thao tác này đã xoá UID/GID của trình tạo và dấu thời gian Unix mở rộng khỏi tệp zip.

Một công cụ mới, ziptime (nằm trong /platform/build/+/android16-release/tools/ziptime/) đặt lại dấu thời gian thông thường trong tiêu đề tệp ZIP. Để biết thông tin chi tiết, hãy tham khảo tệp README.

Công cụ signapk đặt dấu thời gian cho các tệp APK có thể thay đổi tuỳ thuộc vào múi giờ của máy chủ. Để biết thông tin chi tiết, hãy tham khảo CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028.

Công cụ signapk đặt dấu thời gian cho các tệp APK có thể thay đổi tuỳ thuộc vào múi giờ của máy chủ. Để biết thông tin chi tiết, hãy tham khảo CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028.

Chuỗi phiên bản

Vấn đề: Chuỗi phiên bản APK thường có BUILD_NUMBER được thêm vào các phiên bản được mã hoá cứng. Ngay cả khi không có gì thay đổi trong tệp APK, kết quả là tệp APK đó vẫn sẽ khác.

Giải pháp: Xoá số bản dựng khỏi chuỗi phiên bản APK.

Ví dụ:

Bật tính năng tính toán xác thực trên thiết bị

Nếu bạn bật dm-verity trên thiết bị, thì các công cụ OTA sẽ tự động chọn cấu hình xác thực của bạn và bật tính năng tính toán xác thực trên thiết bị. Điều này cho phép tính toán các khối xác thực trên thiết bị Android, thay vì lưu trữ dưới dạng byte thô trong gói OTA. Khối Verity có thể sử dụng khoảng 16 MB cho một phân vùng 2 GB.

Tuy nhiên, việc tính toán tính xác thực trên thiết bị có thể mất nhiều thời gian. Cụ thể, mã Chuyển tiếp lỗi có thể mất nhiều thời gian. Trên thiết bị Pixel, quá trình này thường mất tối đa 10 phút. Trên các thiết bị cấp thấp, có thể mất nhiều thời gian hơn. Nếu muốn tắt tính năng tính toán xác thực trên thiết bị nhưng vẫn bật dm-verity, bạn có thể thực hiện việc này bằng cách truyền --disable_fec_computation vào công cụ ota_from_target_files khi tạo bản cập nhật OTA. Cờ này tắt tính năng tính toán tính xác thực trên thiết bị trong quá trình cập nhật OTA. Điều này làm giảm thời gian cài đặt OTA, nhưng làm tăng kích thước gói OTA. Nếu thiết bị của bạn không bật dm-verity, thì việc truyền cờ này sẽ không có hiệu lực.

Công cụ xây dựng nhất quán

Vấn đề: Các công cụ tạo tệp đã cài đặt phải nhất quán (một đầu vào nhất định phải luôn tạo ra cùng một đầu ra).

Giải pháp/Ví dụ: Bạn cần thay đổi các công cụ xây dựng sau:

Sử dụng công cụ so sánh bản dựng

Trong trường hợp không thể loại bỏ các thay đổi về tệp liên quan đến bản dựng, AOSP sẽ bao gồm một công cụ so sánh bản dựng, target_files_diff.py để sử dụng trong việc so sánh hai gói tệp. Công cụ này thực hiện việc so sánh đệ quy giữa hai bản dựng, ngoại trừ các thay đổi tệp phổ biến liên quan đến bản dựng, chẳng hạn như

  • Các thay đổi dự kiến trong đầu ra của bản dựng (ví dụ: do thay đổi số bản dựng).
  • Thay đổi do các vấn đề đã biết trong hệ thống xây dựng hiện tại.

Để sử dụng công cụ so sánh bản dựng, hãy chạy lệnh sau:

target_files_diff.py dir1 dir2

dir1dir2 là các thư mục cơ sở chứa các tệp mục tiêu đã trích xuất cho mỗi bản dựng.

Duy trì tính nhất quán của quá trình phân bổ khối

Đối với một tệp nhất định, mặc dù nội dung của tệp đó vẫn giữ nguyên giữa hai bản dựng, nhưng các khối thực tế chứa dữ liệu có thể đã thay đổi. Do đó, trình cập nhật phải thực hiện các hoạt động I/O không cần thiết để di chuyển các khối xung quanh cho bản cập nhật OTA.

Trong bản cập nhật OTA A/B ảo, hoạt động I/O không cần thiết có thể làm tăng đáng kể dung lượng lưu trữ cần thiết để lưu trữ bản tổng quan nhanh sao chép khi ghi. Trong bản cập nhật OTA không phải A/B, việc di chuyển các khối xung quanh cho bản cập nhật OTA sẽ góp phần làm tăng thời gian cập nhật do có nhiều hoạt động I/O hơn do việc di chuyển các khối.

Để giải quyết vấn đề này, trong Android 7.0, Google đã mở rộng công cụ make_ext4fs để duy trì tính nhất quán trong việc phân bổ khối trên các bản dựng. Công cụ make_ext4fs chấp nhận một cờ -d base_fs không bắt buộc để cố gắng phân bổ tệp cho cùng một khối khi tạo hình ảnh ext4. Bạn có thể trích xuất các tệp ánh xạ khối (chẳng hạn như tệp ánh xạ base_fs) từ tệp zip của các tệp đích của bản dựng trước. Đối với mỗi phân vùng ext4, sẽ có một tệp .map trong thư mục IMAGES (ví dụ: IMAGES/system.map tương ứng với phân vùng system). Sau đó, bạn có thể kiểm tra và chỉ định các tệp base_fs này thông qua PRODUCT_<partition>_BASE_FS_PATH, như trong ví dụ sau:

  PRODUCT_SYSTEM_BASE_FS_PATH := path/to/base_fs_files/base_system.map
  PRODUCT_SYSTEM_EXT_BASE_FS_PATH := path/to/base_fs_files/base_system_ext.map
  PRODUCT_VENDOR_BASE_FS_PATH := path/to/base_fs_files/base_vendor.map
  PRODUCT_PRODUCT_BASE_FS_PATH := path/to/base_fs_files/base_product.map
  PRODUCT_ODM_BASE_FS_PATH := path/to/base_fs_files/base_odm.map

Mặc dù không giúp giảm kích thước tổng thể của gói OTA, nhưng việc này sẽ cải thiện hiệu suất cập nhật OTA bằng cách giảm lượng I/O. Đối với bản cập nhật A/B ảo, tính năng này giúp giảm đáng kể dung lượng bộ nhớ cần thiết để áp dụng bản cập nhật qua mạng.

Tránh cập nhật ứng dụng

Ngoài việc giảm thiểu sự khác biệt giữa các bản dựng, bạn có thể giảm kích thước bản cập nhật OTA bằng cách loại trừ các bản cập nhật cho các ứng dụng nhận bản cập nhật thông qua cửa hàng ứng dụng. Tệp APK thường chiếm một phần đáng kể trong nhiều phân vùng trên thiết bị. Việc đưa các phiên bản ứng dụng mới nhất được cập nhật qua cửa hàng ứng dụng vào bản cập nhật OTA có thể ảnh hưởng lớn đến kích thước của các gói OTA và mang lại ít lợi ích cho người dùng. Vào thời điểm người dùng nhận được gói OTA, họ có thể đã có ứng dụng đã cập nhật hoặc phiên bản mới hơn nữa, nhận được trực tiếp từ cửa hàng ứng dụng.