Trang này mô tả những 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 nhà triển khai thiết bị duy trì hệ thống xây dựng riêng 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ã. Thực ra, chúng là các cấu phần phần mềm của hệ thống bản dựng. Điều này có thể xảy ra khi cùng một mã, được tạo vào 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 đã thay đổi. Những tệp thừa như vậy làm tăng kích thước của bản vá OTA và gây khó khăn trong việc xác định mã nào đã thay đổi.
Để nội dung của bản cập nhật qua mạng (OTA) minh bạch hơn, AOSP bao gồm các thay đổi về hệ thống bản dựng được thiết kế để giảm kích thước của các bản vá OTA. Các thay đổi không cần thiết đối với tệp giữa các bản dựng đã được loại bỏ và chỉ các tệp liên quan đến bản vá mới có trong bản cập nhật qua mạng. 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 thường gặp về tệp liên quan đến bản dựng để cung cấp một 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ì việc phân bổ khối nhất quán.
Hệ thống bản dựng có thể tạo ra các bản vá có kích thước quá lớn theo nhiều 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 từng tệp khác nhau. Những điểm cải tiến giúp giảm kích thước gói cập nhật qua mạng (OTA) bao gồm:
-
Sử dụng ZSTD, một thuật toán nén không mất dữ liệu, đa năng cho hình ảnh đầy đủ khi 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 dùng trong quá trình cập nhật qua mạng. Bạn có thể đặt kích thước tối đa của cửa sổ nén 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ànhPRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144
- 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 deflate, xử lý các hàm nén và chênh lệch để tạo bản cập nhật OTA A/B.
-
Thay đổi đối với việc 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
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á. -
Những điểm cải tiến đối với
update_engine
giúp giảm mức tiêu thụ bộ nhớ khi các bản vá được áp dụng 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 của bản cập nhật qua mạng (OTA), các giải pháp và ví dụ về việc triển khai trong AOSP.
Thứ tự tệp
Vấn đề: Hệ thống tệp không đảm bảo thứ tự của 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ường thì thứ tự này sẽ giống nhau đối với cùng một lần 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ư find
và make
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 các đầu ra.
Giải pháp: Khi bạn sử dụng các công cụ như find
và make
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 các đầu vào, vì vậy, trước khi 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 trường hợp đã được khắc phục trong hệ thống bản dựng cốt lõi bằng cách sử dụng macro all-*-files-under
tích hợp sẵn, bao gồm all-cpp-files-under
(vì một số định nghĩa được trải rộng trong các tệp makefile khác).
Để biết thông tin chi tiết, hãy tham khảo phần 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
Thư mục bản dựng
Vấn đề: Việc thay đổi thư mục nơi các thành phần được tạo 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 biểu tượng gỡ lỗi mã hoá 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 đã được xoá trước, vì vậy, mã này sẽ thay đổi nếu các biểu tượng 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ả đầu ra của bản dựng dẫn đến những thay đổi không cần thiết đối với tệp. Điều này có thể xảy ra ở những địa điểm 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 làm theo 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 các tệp lưu trữ.
__DATE__/__TIME__/__TIMESTAMP__ trong C/C++
Các macro này luôn tạo ra đầu ra khác nhau cho các bản dựng khác nhau, vì vậy, đừng sử dụng chúng. Sau đây là một số cách để loại bỏ các macro này:
- Xoá các tệp đó. Để xem ví dụ, hãy tham khảo https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f.
- Để xác định riêng biệt tệp nhị phân đang chạy, hãy đọc build-id từ tiêu đề ELF.
-
Để biết thời điểm hệ điều hành được tạo, hãy đọc
ro.build.date
(thao tác này áp dụng cho mọi thứ, ngoại trừ các bản dựng gia tăng. Các bản dựng này có thể không cập nhật ngày này). Ví dụ: hãy tham khảo https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84.
Dấu thời gian được nhúng trong tệp 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 lần sử dụng lệnh zip
. Thao tác này sẽ xoá UID/GID của trình tạo và dấu thời gian mở rộng của Unix khỏi tệp zip.
Một công cụ mới, ziptime
(nằm trong /platform/build/+/android16-release/tools/ziptime/
) sẽ đặ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. Dấu thời gian này có thể thay đổi tuỳ theo 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. Dấu thời gian này có thể thay đổi tuỳ theo 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ì khác thay đổi trong một APK, kết quả là 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ụ:
- https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27
- https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c
Bật tính năng tính toán tính 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 minh của bạn và bật tính năng tính toán xác minh trên thiết bị. Điều này cho phép tính toán các khối tính toàn vẹn trên thiết bị Android thay vì lưu trữ dưới dạng byte thô trong gói OTA. Các khối xác minh 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ã Sửa lỗi chuyển tiếp 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ó cấu hình thấp, có thể sẽ mất nhiều thời gian hơn. Nếu muốn tắt tính năng tính toán tính 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
đến công cụ ota_from_target_files
khi tạo bản cập nhật OTA. Cờ này vô hiệu hoá quá trình tính toán tính xác thực trên thiết bị trong quá trình cập nhật qua mạng (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ó tác dụng.
Công cụ tạo bản 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 trong các công cụ tạo bản dựng sau:
- Công cụ tạo tệp THÔNG BÁO. Người 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ộ trình biên dịch Android Java (Jack). Chuỗi công cụ Jack cần được cập nhật để xử lý những thay đổi không thường xuyên trong việc sắp xếp hàm khởi tạo được tạo. Đã thêm các phương thức truy cập xác định cho hàm khởi tạo vào chuỗi công cụ: https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b.
- Trình biên dịch AOT ART (dex2oat). Trình biên dịch ART nhị phân đã nhận được bản cập nhật bổ sung một lựa 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 sẽ 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à xoá ảnh chụp nhanh: https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29. - Tệp tối ưu hoá trước DEX của ứng dụng (.odex). Các tệp pre-dexopt (.odex) chứa khoảng đệm chưa được khởi tạo trên hệ thống 64 bit. Đã sửa đổi thành: https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029.
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 một diff đệ quy giữa hai bản dựng, không bao gồm các thay đổi phổ biến về tệp liên quan đến bản dựng, chẳng hạn như
- Các thay đổi dự kiến trong đầu ra bản dựng (ví dụ: do thay đổi số bản dựng).
- Những thay đổi do các vấn đề đã biết trong hệ thống bản 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
dir1
và dir2
là các thư mục cơ sở chứa các tệp đích đã trích xuất cho mỗi bản dựng.
Duy trì việc 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 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 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, 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 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 sẽ góp phần làm tăng thời gian cập nhật vì có nhiều hoạt động đầu vào/đầu ra hơn do các khối di chuyển.
Để giải quyết vấn đề này, trong Android 7.0, Google đã mở rộng công cụ make_ext4fs
để duy trì 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 một cờ -d base_fs
không bắt buộc để 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 á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ụ 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ù không giúp giảm kích thước gói OTA tổng thể, nhưng điều này giúp 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ể lượng bộ nhớ 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 giữa các bản dựng, bạn có thể giảm kích thước của bản cập nhật qua mạng bằng cách loại trừ các bản cập nhật cho những ứng dụng nhận bản cập nhật thông qua cửa hàng ứng dụng. 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 mới nhất của ứng dụng được cửa hàng ứng dụng cập nhật vào bản cập nhật qua mạng không dây có thể ảnh hưởng lớn đến kích thước của các gói cập nhật qua mạng không dây và mang lại ít lợi ích cho người dùng. Khi người dùng nhận được gói OTA, họ có thể đã có ứng dụng được cập nhật hoặc thậm chí là một phiên bản mới hơn, nhận trực tiếp từ cửa hàng ứng dụng.