Na tej stronie opisujemy zmiany dodane do AOSP, aby ograniczyć niepotrzebne zmiany plików między kompilacjami. Te informacje mogą posłużyć za wskazówkę dla osób implementujących urządzenia, które zarządzają własnymi systemami kompilacji. , które mają na celu zmniejszenie rozmiaru aktualizacji bezprzewodowych.
Aktualizacje OTA Androida czasami zawierają zmienione pliki, które nie są powiązane ze zmianami w kodzie. Są to tak naprawdę artefakty systemowe. Może się tak zdarzyć, gdy ten sam kod utworzony z różnych katalogów lub komputerów powoduje dużą liczbę zmian . Taki nadmiar plików zwiększa rozmiar poprawki OTA i utrudnia ustalenie, który kod się zmienił.
Aby zwiększyć przejrzystość zawartości OTA, AOSP uwzględnia zmiany w systemie kompilacji w celu zmniejszenia rozmiaru instalacji OTA. Niepotrzebne zmiany w plikach między kompilacjami zostały wprowadzone i w aktualizacjach OTA zawierają tylko pliki związane z poprawkami. AOSP obejmuje również narzędzie do tworzenia różnic, które odfiltrowuje typowe zmian w plikach, aby zwiększyć czytelność różnic między plikami kompilacji. narzędzie do mapowania bloków, które pomaga zachować przydzielanie blokad spójne.
System kompilacji może tworzyć niepotrzebnie duże poprawki na kilka sposobów. Aby temu zaradzić, w sekcji W Androidzie 8.0 i nowszych wprowadzono nowe funkcje, aby zmniejszyć rozmiar poprawek dla każdej różnice plików Usprawnienia, które pozwalają ograniczyć rozmiar pakietów aktualizacji OTA, to między innymi:
-
Wykorzystanie ogólnego, bezstratnego algorytmu kompresji ZSTD do pełnego
obrazów w aktualizacjach urządzeń innych niż A/B. ZSTD można dostosować, aby zwiększać
współczynnik kompresji, zwiększenie poziomu kompresji. Poziom kompresji jest ustawiony podczas OTA
czasu generowania. Można go ustawić,
przesyłając flagę
--vabc_compression_param=zstd,$COMPRESSION_LEVEL
-
Zwiększ rozmiar okna kompresji używany podczas OTA. Maksymalny rozmiar okna kompresji
można ustawić, dostosowując parametr kompilacji w pliku
.mk
urządzenia. Ten zmienna jest ustawiona jakoPRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144
. - Zastosowanie rekompresji Puffin, deterministycznego narzędzia do łatania deflate strumienie, które obsługują funkcje kompresji i różnicy na potrzeby generowania aktualizacji OTA przez A/B.
-
zmiany w wykorzystaniu narzędzia do generowania delta, takie jak sposób
bsdiff
jest używana do kompresowania poprawek. W Androidzie 9 i nowszych parametrbsdiff
wybiera algorytm kompresji, który zapewni uzyskać najlepsze wyniki kompresji dla poprawki. -
Ulepszenia
update_engine
zmniejszyło zużycie pamięci przy stosowaniu poprawek do aktualizacji urządzeń typu A/B.
W poniższych sekcjach opisano różne problemy, które wpływają na rozmiary aktualizacji OTA, ich rozwiązania i przykładów implementacji w AOSP.
Kolejność plików
Problem: systemy plików nie gwarantują kolejności plików, gdy pojawi się prośba o podanie listy
w katalogu, choć najczęściej są identyczne w przypadku tej samej płatności. Narzędzia takie jak
ls
domyślnie sortuje wyniki, ale funkcja z symbolem wieloznacznym używana przez polecenia takie jak
ponieważ find
i make
nie są sortowane. Przed użyciem tych narzędzi musisz posortować
dane wyjściowe.
Rozwiązanie: jeśli używasz narzędzi takich jak find
czy
make
za pomocą funkcji symbolu wieloznacznego, posortuj dane wyjściowe tych poleceń, zanim użyjesz
. Gdy używasz $(wildcard)
lub $(shell find)
w
Android.mk
, posortuj też je. Niektóre narzędzia, takie jak Java, sortują dane wejściowe, więc
przed posortowaniem sprawdź, czy narzędzie, którego używasz, jeszcze tego nie zrobiło.
Przykłady: wiele wystąpień zostało naprawionych w podstawowym systemie kompilacji przy użyciu parametru
wbudowane makro all-*-files-under
, które zawiera
all-cpp-files-under
(kilka definicji pojawiło się w innych plikach Makefile).
Szczegółowe informacje można znaleźć w następujących dokumentach:
- 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
Katalog kompilacji
Problem: zmiana katalogu, w którym budowane są elementy, może spowodować
pliki binarne. Większość ścieżek w kompilacji Androida to ścieżki względne,
__FILE__
w C/C++ nie stanowi problemu. Symbole debugowania kodują jednak pełną
ścieżki, a element .note.gnu.build-id
jest generowany na podstawie haszowania
wstępnie skrócony plik binarny, który zmienia się, gdy symbole debugowania ulegną zmianie.
Rozwiązanie: AOSP ustawia teraz ścieżki debugowania względne. Szczegółowe informacje znajdziesz w CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02
Sygnatury czasowe
Problem: sygnatury czasowe w danych wyjściowych kompilacji powodują niepotrzebne zmiany w pliku. Może się tak zdarzyć w tych miejscach:
- Makra
__DATE__/__TIME__/__TIMESTAMP__
w kodzie w C lub C++. - Sygnatury czasowe umieszczone w archiwach ZIP.
Rozwiązania/przykłady: aby usunąć sygnatury czasowe z danych wyjściowych kompilacji, użyj funkcji instrukcje podane poniżej w __DATE__/__TIME__/__TIMESTAMP__ w języku C/C++. i Sygnatury czasowe umieszczone w archiwach.
__DATE__/__TIME__/__TIMESTAMP__ w języku C/C++
Nie używaj tych makr zawsze w przypadku różnych kompilacji. Tutaj możesz je usunąć na kilka sposobów:
- Usuń je. Na przykład: https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f
- Aby jednoznacznie zidentyfikować uruchomiony plik binarny, odczytaj identyfikator kompilacji z nagłówka ELF.
-
Aby dowiedzieć się, kiedy został utworzony system operacyjny, przeczytaj dokument
ro.build.date
(działa to wszystko oprócz kompilacji przyrostowych, które mogą nie aktualizować tej daty). Na przykład: do https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84
sygnatury czasowe umieszczone w archiwach (zip, jar);
Android 7.0 rozwiązał problem z sygnaturami czasowymi w archiwum ZIP, dodając
-X
we wszystkich przypadkach użycia polecenia zip
. Spowoduje to usunięcie identyfikatora UID/GID
i rozszerzonej sygnatury czasowej systemu Unix z pliku ZIP.
Nowe narzędzie ziptime
(w języku:
/platform/build/+/main/tools/ziptime/
) resetuje normalne sygnatury czasowe w nagłówkach ZIP. Aby dowiedzieć się więcej, zapoznaj się z
Plik README.
Narzędzie signapk
ustawia sygnatury czasowe plików APK, które mogą się różnić w zależności od
strefie czasowej serwera. Szczegółowe informacje znajdziesz w dokumencie CL
https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028
Narzędzie signapk
ustawia sygnatury czasowe plików APK, które mogą się różnić w zależności od
strefie czasowej serwera. Szczegółowe informacje znajdziesz w dokumencie CL
https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028
Ciągi znaków wersji
Problem: ciągi znaków wersji pliku APK często miały dołączone ciąg BUILD_NUMBER
.
do ich zakodowanych na stałe wersji. Nawet jeśli w pliku APK nic się nie zmieniło, pakiet
byłyby inne.
Rozwiązanie: usuń numer kompilacji z ciągu znaków wersji pliku APK.
Przykłady:
- https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27
- https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c
Włącz obliczanie poprawności na urządzeniu
Jeśli dm-verity jest włączona na urządzeniu, narzędzia OTA automatycznie odbiorą Twoją konfigurację, włącz obliczanie poprawności na urządzeniu. Umożliwia to obliczanie bloków poprawności na Androidzie urządzenia, a nie jako nieprzetworzone bajty w pakiecie OTA. Bloki wiarygodności mogą używać około 16 MB na partycję 2 GB.
Jednak przetwarzanie danych na urządzeniu może zająć dużo czasu. Mówiąc konkretnie,
Kod naprawienia błędu może zająć dużo czasu. Na urządzeniach Pixel zwykle zajmuje to do 10 sekund,
min. Na mniej zaawansowanych urządzeniach może to potrwać dłużej. Jeśli chcesz wyłączyć wersję na urządzeniu
a przy tym włącz dm-verity, przekazując
--disable_fec_computation
do narzędzia ota_from_target_files
, gdy
i generuję aktualizację OTA. Ta flaga wyłącza obliczanie poprawności na urządzeniu podczas aktualizacji OTA.
Skraca to czas instalacji OTA, ale zwiększa rozmiar pakietu OTA. Jeśli urządzenie nie
ma włączoną wartość dm-verity, przekazanie tej flagi nie przynosi żadnego efektu.
Narzędzia do spójnej kompilacji
Problem: narzędzia generujące zainstalowane pliki muszą być spójne (dane dane wejściowe zawsze powinny dawać te same dane wyjściowe).
Rozwiązania/przykłady: wymagane były zmiany w tych narzędziach do kompilacji:
- Kreator pliku NOTICE. Twórca pliku z uwagami został zmieniony na tworzenie które można odtworzyć. Zapoznaj się z listą zmian: https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64
- Java Android Compiler Kit (Jack). Łańcuch narzędzi Jack wymagał aktualizacji obsługuje sporadyczne zmiany kolejności generowanych konstruktorów. Deterministyczne metody dostępu dla Do łańcucha narzędzi zostały dodane konstruktory: https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b
- Kompilator ART AOT (dex2oat). Plik binarny kompilatora ART otrzymał aktualizację, która dodaliśmy opcję tworzenia deterministycznego obrazu: https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9
-
Plik libpac.so (V8) Każda kompilacja daje inny
/system/lib/libpac.so
, ponieważ zrzut V8 zmienia się w przypadku każdej kompilacji. rozwiązaniem było usunięcie zrzutu: https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29 - Pliki pre-dexopt aplikacji (.odex). pliki pre-dexopt (.odex), zawiera niezainicjowane dopełnienie w systemach 64-bitowych. To zostało poprawione: https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029
Korzystanie z narzędzia do tworzenia różnic
Gdy nie można wyeliminować zmian w plikach kompilacji, AOSP dołącza tag
narzędzie do tworzenia różnic,
target_files_diff.py
do porównania dwóch pakietów plików. To narzędzie wykonuje różnice rekurencyjne między dwoma
kompilacje, z wyłączeniem typowych zmian w plikach kompilacji, takich jak
- Spodziewane zmiany w danych wyjściowych kompilacji (np. ze względu na zmianę numeru kompilacji).
- Zmiany spowodowane znanymi problemami w obecnym systemie kompilacji.
Aby użyć narzędzia do tworzenia różnic, uruchom to polecenie:
target_files_diff.py dir1 dir2
dir1
i dir2
to katalogi podstawowe, które zawierają wyodrębnione miejsce docelowe
dla każdej kompilacji.
Zachowaj spójność przydziału blokad
Chociaż zawartość danego pliku w 2 kompilacjach jest taka sama, rzeczywiste bloki mogła się zmienić. W związku z tym aktualizator musi wykonać niepotrzebne operacje wejścia-wyjścia aby przeprowadzić aktualizację OTA.
Podczas wirtualnej aktualizacji OTA niepotrzebne operacje wejścia-wyjścia mogą znacznie zwiększyć wymagane miejsce na dane. do przechowywania zrzutu skopiowania przy zapisie. w przypadku aktualizacji OTA inną niż A/B przesunięcie bloków Aktualizacja OTA przyczynia się do wydłużenia czasu aktualizacji, ponieważ z powodu przenoszenia bloków występuje więcej operacji wejścia-wyjścia.
Aby rozwiązać ten problem, w Androidzie 7.0 rozszerzyliśmy narzędzie make_ext4fs
na:
z zachowaniem spójności przydzielania bloków przez kompilacje. Narzędzie make_ext4fs
akceptuje
opcjonalną flagę -d base_fs
, która próbuje przydzielić pliki do tych samych bloków.
podczas generowania obrazu ext4
. Możesz wyodrębnić pliki mapowania bloków (takie jak
base_fs
plików mapy) z plików docelowych poprzedniej kompilacji .zip. Dla każdej wartości
ext4
, w.map
IMAGES
(np. IMAGES/system.map
odpowiada katalogowi
system
partycja). Te base_fs
pliki będzie można następnie zameldować i
określony za pomocą metody PRODUCT_<partition>_BASE_FS_PATH
, jak w tym przykładzie:
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
Chociaż nie pomaga to w zmniejszeniu ogólnego rozmiaru pakietu OTA, usprawnia aktualizację OTA. dzięki zmniejszeniu liczby operacji wejścia-wyjścia. W przypadku wirtualnych aktualizacji A/B znacząco zmniejsza ilość miejsca potrzebna do zastosowania aktualizacji OTA.
Unikanie aktualizowania aplikacji
Oprócz minimalizacji różnic w kompilacji możesz zmniejszyć rozmiar aktualizacji OTA, wykluczając aktualizacje w przypadku aplikacji, które otrzymują aktualizacje ze sklepów z aplikacjami. Pliki APK często stanowią znaczną część różne partycje na urządzeniu. Obejmuje to najnowsze wersje aplikacji, które są aktualizowane przez aplikację sklepów w aktualizacji OTA mogą mieć duży wpływ na pakiety OTA i nie będą korzyści. zanim użytkownicy otrzymają pakiet OTA, być może mają już zaktualizowaną aplikację. i kolejnych nowszych wersji, pobieranych bezpośrednio ze sklepów z aplikacjami.