Trang này mô tả các thay đổi được thêm vào AOSP để giảm các thay đổi tệp không cần thiết 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 (OTA).
Các bản cập nhật OTA của Android đôi khi chứa các tệp đã thay đổi không tương ứng với các thay đổi về mã. Họ thực sự đang xây dựng các tạo phẩm hệ thống. Điều này có thể xảy ra khi cùng một mã, được xây dựng ở những thời điểm khác nhau, từ các thư mục khác nhau hoặc trên các máy khác nhau tạo ra một số lượng lớn các tệp bị thay đổi. Các tệp dư thừa như vậy sẽ làm tăng kích thước của bản vá OTA và gây khó khăn cho việc xác định mã nào đã thay đổi.
Để làm cho nội dung của OTA 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. Những thay đổi tệp không cần thiết giữa các bản dựng đã bị loại bỏ và chỉ các tệp liên quan đến bản vá mới được chứa trong các bản cập nhật OTA. AOSP cũng bao gồm một công cụ tìm khác biệt 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 sự khác biệt giữa tệp bản dựng rõ ràng hơn và công cụ ánh xạ khối , giúp bạn duy trì sự phân bổ khối nhất quán.
Hệ thống xây dựng có thể tạo ra các bản vá lớn không cần thiết theo nhiều cách. Để giảm thiểu điều 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 nhau. Những cải tiến giúp giảm kích thước gói cập nhật OTA bao gồm:
- Cách sử dụng Brotli , một thuật toán nén không mất dữ liệu, có mục đích chung cho hình ảnh đầy đủ trên các bản cập nhật thiết bị không phải A/B. Brotli có thể được tùy chỉnh để tối ưu hóa việc nén. Trên các bản cập nhật lớn hơn bao gồm hai hoặc nhiều khối trong hệ thống tệp (ví dụ:
system.img
), nhà sản xuất thiết bị hoặc đối tác có thể thêm thuật toán nén của riêng họ và có thể sử dụng các thuật toán nén khác nhau trên các khối khác nhau của cùng một bản cập nhật. - Việc sử dụng tính năng nén lại Puffin , một công cụ vá lỗi xác định cho các luồng giảm phát, xử lý các chức năng nén và khác biệt để tạo bản cập nhật A/B OTA.
- Những thay đổi về cách sử dụng công cụ tạo delta, chẳng hạn như cách sử dụng thư viện
bsdiff
để nén các bản vá. Trong Android 9 trở lên, công cụbsdiff
chọn thuật toán nén sẽ mang lại kết quả nén tốt nhất cho bản vá. - Những cải tiến đối với
update_engine
dẫn đến tiêu thụ ít bộ nhớ hơn khi áp dụng các bản vá cho bản cập nhật thiết bị A/B. - Cải tiến việc chia nhỏ các tệp zip lớn để cập nhật OTA dựa trên khối. Một chế độ trong
imgdiff
chia nhỏ các tệp APK quá khổ, dựa trên tên mục nhập. Điều này tạo ra một bản vá nhỏ hơn so với việc chia tuyến tính các tệp và sử dụng công cụbsdiff
để nén chúng.
Các phần sau thảo luận về các vấn đề khác nhau ảnh hưởng đến kích thước cập nhật OTA, giải pháp của chúng và ví dụ về triển khai trong AOSP.
Thứ tự tập tin
Sự cố : Hệ thống tệp không đảm bảo thứ tự tệp khi được yêu cầu danh sách tệp trong một thư mục, mặc dù điều này thường giống nhau đối với cùng một lần kiểm tra. 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 được sử dụng bởi các lệnh như find
và make
thì không sắp xếp. Trước khi sử dụng những công cụ này, bạn phải sắp xếp kết quả đầu ra.
Giải pháp : Khi bạn sử dụng các công cụ như find
và make
bằng chức năng 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 chúng. Khi sử dụng $(wildcard)
hoặc $(shell find)
trong tệp Android.mk
, hãy sắp xếp chúng. Một số công cụ, chẳng hạn như Java, thực hiện sắp xếp dữ liệu đầu vào, vì vậy trước khi bạn sắp xếp 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 phiên bản đã được sửa trong hệ thống xây dựng cốt lõi bằng cách sử dụng macro all-*-files-under
dựng sẵn, bao gồm all-cpp-files-under
(vì một số định nghĩa đã được phổ biến trong các tệp tạo tệp khác). Để biết chi tiết, hãy tham khảo như sau:
- https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f
- https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410
- https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653
- https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c
Xây dựng thư mục
Sự cố: Việc thay đổi thư mục chứa mọi thứ 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 nên __FILE__
trong C/C++ không phải là vấn đề. Tuy nhiên, các ký hiệu gỡ lỗi mã hóa tên đường dẫn đầy đủ theo mặc định và .note.gnu.build-id
được tạo từ việc băm tệp nhị phân bị tước bỏ trước, do đó, nó sẽ thay đổi nếu ký hiệu gỡ lỗi thay đổi.
Giải pháp: AOSP hiện làm cho các đường dẫn gỡ lỗi trở nên tương đối. Để biết chi tiết, hãy tham khảo CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02 .
Dấu thời gian
Sự cố: Dấu thời gian trong kết quả đầu ra của bản dựng dẫn đến những thay đổi tệp không cần thiết. Điều này có thể xảy ra ở những vị trí sau:
-
__DATE__/__TIME__/__TIMESTAMP__
macro trong mã C hoặc C++. - Dấu thời gian được nhúng trong kho lưu trữ dựa trên zip.
Giải pháp/Ví dụ: Để xóa 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++. và Dấu thời gian được nhúng trong kho lưu trữ .
__DATE__/__TIME__/__TIMESTAMP__ trong C/C++
Các macro này luôn tạo ra các kết quả đầu ra khác nhau cho các bản dựng khác nhau, vì vậy đừng sử dụng chúng. Dưới đây là một số tùy chọn để loại bỏ các macro này:
- Loại bỏ chúng. Để biết ví dụ, hãy tham khảo https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f .
- Để xác định duy nhất tệp nhị phân đang chạy, hãy đọc id bản dựng từ tiêu đề ELF.
- Để biết thời điểm hệ điều hành được xây dựng, hãy đọc
ro.build.date
(điều này áp dụng cho mọi thứ ngoại trừ các bản dựng tăng dần, có thể không cập nhật ngày này). Để biết ví dụ, hãy tham khảo https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84 .
Dấu thời gian được nhúng trong kho lưu trữ (zip, jar)
Android 7.0 đã khắc phục sự cố về dấu thời gian được nhúng trong kho lưu trữ zip bằng cách thêm -X
vào tất cả các cách sử dụng lệnh zip
. Thao tác này đã xóa 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/+/main/tools/ziptime/
) đặt lại dấu thời gian bình thường trong tiêu đề zip. Để biết 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 tùy theo múi giờ của máy chủ. Để biết chi tiết, hãy tham khảo CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028 .
Chuỗi phiên bản
Sự cố: 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ã hóa cứng của chúng. Do đó, ngay cả khi không có gì khác thay đổi trong APK thì APK vẫn sẽ khác.
Giải pháp: Xóa số bản dựng khỏi chuỗi phiên bản APK.
Ví dụ:
- https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27
- https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c
Bật tính toán xác thực trên thiết bị
Nếu dm-verity được bật trên thiết bị của bạn thì các công cụ OTA sẽ tự động nhận cấu hình xác thực của bạn và bật tính toán xác thực trên thiết bị. Điều này cho phép các khối xác thực được tính toán trên thiết bị Android, thay vì được lưu trữ dưới dạng byte thô trong gói OTA của bạn. Các khối Verity có thể sử dụng khoảng 16MB cho phân vùng 2GB.
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ã sửa lỗi chuyển tiếp có thể mất nhiều thời gian. Trên các thiết bị pixel, quá trình này có xu hướng mất tới 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 bạn muốn tắt 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ể làm như vậy bằng cách chuyển --disable_fec_computation
tới công cụ ota_from_target_files
khi tạo bản cập nhật OTA. Cờ này vô hiệu hóa tính toán xác thực trên thiết bị trong quá trình cập nhật OTA. Nó giảm thời gian cài đặt OTA nhưng 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 chuyển cờ này sẽ không có hiệu lực.
Công cụ xây dựng nhất quán
Sự cố: Các công cụ tạo tệp cài đặt phải nhất quán (đầ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ụ: Cần có những thay đổi trong các công cụ xây dựng sau:
- THÔNG BÁO người tạo tập tin . Trình tạo tệp THÔNG BÁO đã được thay đổi để tạo các bộ sưu tập THÔNG BÁO có thể tái tạo. Tham khảo CL: https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64 .
- Bộ biên dịch Java Android (Jack) . Chuỗi công cụ Jack yêu cầu cập nhật để xử lý các thay đổi không thường xuyên về thứ tự hàm tạo được tạo. Các trình truy cập xác định cho hàm tạo đã được thêm vào chuỗi công cụ: https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b .
- Trình biên dịch ART AOT (dex2oat) . Tệp nhị phân của trình biên dịch ART đã nhận được bản cập nhật bổ sung tùy chọn tạo hình ảnh xác định: https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9 .
- Tệp libpac.so (V8) . Mỗi bản dựng tạo một tệp
/system/lib/libpac.so
khác nhau vì ảnh chụp nhanh V8 thay đổi cho mỗi bản dựng. Giải pháp là xóa ảnh chụp nhanh: https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29 . - Các tệp tiền dexopt (.odex) của ứng dụng . Các tệp pre-dexopt (.odex) chứa phần đệm chưa được khởi tạo trên hệ thống 64 bit. Điều này đã được sửa: https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029 .
Sử dụng công cụ xây dựng khác biệt
Đối với những trường hợp không thể loại bỏ các thay đổi tệp liên quan đến bản dựng, AOSP bao gồm một công cụ tìm khác biệt bản dựng, target_files_diff.py
để sử dụng khi so sánh hai gói tệp. Công cụ này thực hiện sự khác biệt đệ 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ư
- Những thay đổi dự kiến về kết quả của bản dựng (ví dụ: do thay đổi số bản dựng).
- Những thay đổi do các sự cố đã biết trong hệ thống xây dựng hiện tại.
Để sử dụng công cụ build diff, hãy chạy lệnh sau:
target_files_diff.py dir1 dir2
dir1
và dir2
là các thư mục cơ sở chứa các tệp mục tiêu được trích xuất cho mỗi bản dựng.
Giữ phân bổ khối nhất quán
Đối với một tệp nhất định, mặc dù nội dung của nó 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 I/O không cần thiết để di chuyển các khối xung quanh để cập nhật OTA.
Trong bản cập nhật OTA A/B ảo, 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ữ ảnh chụp nhanh khi 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 để cập nhật OTA góp phần tăng thời gian cập nhật vì có nhiều I/O hơn do di chuyển khối.
Để giải quyết vấn đề này, trong Android 7.0, Google đã mở rộng công cụ make_ext4fs
để giữ cho việc phân bổ khối nhất quán trên các bản dựng. Công cụ make_ext4fs
chấp nhận cờ -d base_fs
tùy chọn để cố gắng phân bổ các tệp vào 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 bản đồ base_fs
) từ tệp zip của tệp mục tiêu của bản dựng trước đó. Đối với mỗi phân vùng ext4
, 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 đó, các tệp base_fs
này có thể được đăng ký và chỉ định thông qua PRODUCT_<partition>_BASE_FS_PATH
, như trong ví dụ này:
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ù điều này không giúp giảm kích thước gói OTA tổng thể nhưng nó 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 các bản cập nhật A/B ảo, nó giảm đáng kể dung lượng lưu trữ cần thiết để áp dụng OTA.
Tránh cập nhật ứng dụng
Ngoài việc giảm thiểu sự khác biệt về 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 ứng dụng nhận bản cập nhật thông qua cửa hàng ứng dụng. APK thường bao gồm một phần đáng kể của các phân vùng khác nhau trên thiết bị. Việc đưa các phiên bản ứng dụng mới nhất được cửa hàng ứng dụng cập nhật vào bản cập nhật OTA có thể có tác động lớn đến 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, được nhận trực tiếp từ các cửa hàng ứng dụng.