In questa pagina vengono descritte le modifiche aggiunte ad AOSP per ridurre le modifiche non necessarie ai file tra le build. Gli utenti che implementano i dispositivi che gestiscono i propri sistemi di build possono utilizzare queste informazioni come guida per ridurre le dimensioni degli aggiornamenti over-the-air (OTA).
Gli aggiornamenti OTA di Android a volte contengono file modificati che non corrispondono a modifiche al codice. In realtà sono artefatti di sistema di build. Ciò può verificarsi quando lo stesso codice, creato con da directory diverse o su macchine diverse produce un gran numero di . Un tale numero in eccesso aumenta le dimensioni di una patch OTA e ne complica l'individuazione quale codice è cambiato.
Per rendere più trasparenti i contenuti di una OTA, AOSP include modifiche al sistema di compilazione progettate per ridurre le dimensioni delle patch OTA. Sono state apportate modifiche non necessarie ai file tra le build eliminato e solo i file relativi alle patch sono contenuti negli aggiornamenti OTA. AOSP include anche build diff tool, che filtra i risultati più comuni relativi alla build modifiche al file per ottenere un diff del file di build più chiaro e una strumento di mappatura a blocchi, che consente di mantenere l'allocazione dei blocchi coerente.
Un sistema di compilazione può creare patch inutilmente grandi in diversi modi. Per mitigare questo problema, Android 8.0 e versioni successive sono state implementate nuove funzionalità per ridurre le dimensioni delle patch per ogni diff. I miglioramenti apportati alle dimensioni ridotte dei pacchetti di aggiornamento OTA includono quanto segue:
-
Utilizzo di ZSTD, un algoritmo generico di compressione senza perdita di dati
immagini negli aggiornamenti del dispositivo non A/B. ZSTD può essere personalizzato per
i rapporti di compressione aumentando il livello di compressione. Il livello di compressione viene impostato durante OTA
e può essere impostato passando il flag
--vabc_compression_param=zstd,$COMPRESSION_LEVEL
-
Aumentare la dimensione della finestra di compressione utilizzata durante l'aggiornamento OTA. Le dimensioni massime della finestra di compressione
può essere impostato personalizzando il parametro di build nel file
.mk
di un dispositivo. Questo è impostata comePRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144
- Utilizzo della ricompressione Puffin, uno strumento di patch deterministico per deflate flussi, che gestisce le funzioni di compressione e diff per la generazione di aggiornamenti OTA A/B.
-
Modifiche all'utilizzo dello strumento di generazione delta, ad esempio il modo in cui
bsdiff
viene utilizzata per comprimere le patch. In Android 9 e versioni successive, Lo strumentobsdiff
seleziona l'algoritmo di compressione che restituisce la compressione migliore per una patch. -
Miglioramenti apportati a
update_engine
ha comportato un consumo inferiore della memoria quando vengono applicate le patch per gli aggiornamenti A/B dei dispositivi.
Le sezioni seguenti discutono i vari problemi che interessano le dimensioni degli aggiornamenti OTA, le relative soluzioni ed esempi di implementazione in AOSP.
Ordine dei file
Problema: i file system non garantiscono l'ordine dei file quando viene richiesto un elenco di
in una directory, sebbene di solito sia lo stesso per la procedura di pagamento. Strumenti come
ls
ordina i risultati per impostazione predefinita, ma la funzione con caratteri jolly utilizzata da comandi come
perché find
e make
non vengono ordinati. Prima di utilizzare questi strumenti, devi ordinare
gli output.
Soluzione: quando utilizzi strumenti come find
e
make
con la funzione carattere jolly, ordina l'output di questi comandi prima di utilizzare
che li rappresentano. Quando utilizzi $(wildcard)
o $(shell find)
in
Android.mk
file, ordinali anche tu. Alcuni strumenti, come Java, ordinano gli input,
prima di ordinare i file, verifica che lo strumento che stai utilizzando non l'abbia già fatto.
Esempi: molte istanze sono state corrette nel sistema di build principale utilizzando
integrata all-*-files-under
, che include
all-cpp-files-under
(poiché diverse definizioni erano distribuite in altri makefile).
Per maggiori dettagli, consulta quanto segue:
- 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
Directory di build
Problema. La modifica della directory in cui vengono creati gli elementi può causare
essere diversi. La maggior parte dei percorsi nella build Android sono percorsi relativi, quindi
__FILE__
in C/C++ non è un problema. Tuttavia, i simboli di debug codificano l'intero
per impostazione predefinita e .note.gnu.build-id
viene generato dall'hashing del
binario, che cambia se cambiano i simboli di debug.
Soluzione: AOSP ora rende relativi i percorsi di debug. Per maggiori dettagli, consulta CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02.
Timestamp
Problema: i timestamp nell'output della build comportano modifiche non necessarie al file. È probabile che questo si verifichi nelle seguenti situazioni:
__DATE__/__TIME__/__TIMESTAMP__
macro nel codice C o C++.- Timestamp incorporati in archivi basati su zip.
Soluzioni/esempi: per rimuovere i timestamp dall'output della build, utilizza il metodo le istruzioni riportate di seguito __DATE__/__TIME__/__TIMESTAMP__ in C/C++. e Timestamp incorporati negli archivi.
__DATE__/__TIME__/__TIMESTAMP__ in C/C++
Queste macro producono sempre output diversi per build diverse, quindi non usarle. Qui sono disponibili alcune opzioni per l'eliminazione di queste macro:
- Rimuovile. Per un esempio, consulta https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f.
- Per identificare in modo univoco il programma binario in esecuzione, leggi il valore build-id dall'intestazione ELF.
-
Per sapere quando è stato creato il sistema operativo, leggi il
ro.build.date
(funziona per tutto tranne le build incrementali, che potrebbero non essere aggiornate in questa data). Per un esempio, consulta a https://android.googlesource.com/platform/external/libchrome/+/8b7977ebb94f6b3a3896cd13b4aeacbfa1e0f84.
Timestamp incorporati negli archivi (zip, jar)
Android 7.0 ha risolto il problema dei timestamp incorporati negli archivi ZIP aggiungendo
-X
a tutti gli utilizzi del comando zip
. Questa operazione ha rimosso l'UID/GID del
Builder e il timestamp Unix esteso dal file ZIP.
Un nuovo strumento, ziptime
(disponibile in
/platform/build/+/main/tools/ziptime/
) reimposta i normali timestamp nelle intestazioni dei file zip. Per maggiori dettagli, consulta
File README.
Lo strumento signapk
imposta i timestamp per i file APK, che possono variare a seconda del
fuso orario del server. Per maggiori dettagli, consulta
https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028.
Lo strumento signapk
imposta i timestamp per i file APK, che possono variare a seconda del
fuso orario del server. Per maggiori dettagli, consulta
https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028.
Stringhe delle versioni
Problema: alle stringhe della versione dell'APK spesso veniva aggiunto il BUILD_NUMBER
alle relative versioni impostate come hardcoded. Anche se in un APK non sono state apportate altre modifiche, di conseguenza l'APK
sarebbe comunque diverso.
Soluzione: rimuovi il numero di build dalla stringa di versione dell'APK.
Esempi:
- https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27
- https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c
Attiva il calcolo della verifica sul dispositivo
Se dm-verity sia attivata sul tuo dispositivo, gli strumenti OTA acquisiranno automaticamente la configurazione della verifica e attivare il calcolo della verifica sul dispositivo. Consente di calcolare i blocchi di verifica su Android anziché essere archiviati come byte non elaborati nel pacchetto OTA. I blocchi di verifica possono utilizzare di circa 16 MB per una partizione da 2 GB.
Tuttavia, la verifica del computing sul dispositivo può richiedere molto tempo. In particolare, il modello
Il codice di correzione degli errori può richiedere molto tempo. Sui dispositivi Pixel, tendono a impiegare fino a 10
minuti. Sui dispositivi di fascia bassa potrebbe richiedere più tempo. Se vuoi disattivare la verifica sul dispositivo
di calcolo, ma abilitare comunque la dm-verity, passando
--disable_fec_computation
allo strumento ota_from_target_files
quando
generando un aggiornamento OTA. Questo flag disabilita il calcolo della verifica sul dispositivo durante gli aggiornamenti OTA.
Riduce i tempi di installazione delle OTA, ma aumenta le dimensioni del pacchetto OTA. Se il tuo dispositivo non
hanno dm-verity abilitato, il passaggio di questo flag non ha effetto.
Strumenti di creazione coerenti
Problema: gli strumenti che generano file installati devono essere coerenti (una data deve produrre sempre lo stesso output).
Soluzioni/esempi: erano necessarie modifiche ai seguenti strumenti di creazione:
- Creatore file AVVISO. L'autore del file NOTA è stato modificato raccolte di avvisi riproducibili. Fai riferimento a CL: https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64.
- Jack (Compiler Kit) Java per Android. La toolchain Jack ha richiesto un aggiornamento per gestire le modifiche occasionali nell'ordine dei costruttori generato. Funzioni di accesso deterministiche per constructors è stato aggiunto alla toolchain: https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b.
- Compilatore ART AOT (dex2oat). Il file binario del compilatore ART ha ricevuto un aggiornamento è stata aggiunta un'opzione per creare un'immagine deterministica: https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9.
-
Il file libpac.so (V8). Ogni build crea
/system/lib/libpac.so
perché lo snapshot V8 cambia per ogni build. La è stata quella di rimuovere lo snapshot: https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29. - File pre-dexopt (.odex) delle applicazioni. I file pre-dexopt (.odex) contenevano spaziatura interna non inizializzata sui sistemi a 64 bit. Questo problema è stato corretto: https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029.
Utilizza lo strumento diff di build
Per i casi in cui non sia possibile eliminare le modifiche ai file correlati alla build, AOSP include una
lo strumento Crea diff,
target_files_diff.py
per il confronto di due pacchetti di file. Questo strumento esegue una differenza ricorsiva tra due
build, escluse le modifiche comuni ai file correlati alle build, come
- Modifiche previste nell'output della build (ad esempio, a causa di una modifica al numero di build).
- Modifiche dovute a problemi noti nell'attuale sistema di build.
Per utilizzare lo strumento build diff, esegui questo comando:
target_files_diff.py dir1 dir2
dir1
e dir2
sono directory di base che contengono la destinazione estratta
per ogni build.
Mantieni coerente l'allocazione dei blocchi
Per un determinato file, anche se il suo contenuto rimane lo stesso tra due build, i blocchi effettivi che contengono i dati potrebbero essere cambiate. Di conseguenza, il programma di aggiornamento deve eseguire I/O non necessari per spostare gli elementi necessari per un aggiornamento OTA.
In un aggiornamento OTA A/B virtuale, I/O non necessari possono aumentare notevolmente lo spazio di archiviazione richiesto per archiviare lo snapshot copia alla scrittura. In un aggiornamento OTA non A/B, spostare gli elementi per ottenere L'aggiornamento OTA contribuisce ai tempi di aggiornamento poiché c'è più I/O a causa degli spostamenti dei blocchi.
Per risolvere questo problema, in Android 7.0 Google ha esteso lo strumento make_ext4fs
per
mantenendo l'allocazione dei blocchi coerente tra le build. Lo strumento make_ext4fs
accetta
un flag -d base_fs
facoltativo che tenta di allocare file agli stessi blocchi
quando generi un'immagine ext4
. Puoi estrarre i file di mapping a blocchi (come
i base_fs
file di mappa) dai file di destinazione di una build precedente' .zip. Per ogni
partizione ext4
, è presente un file .map
nella
IMAGES
(ad esempio, IMAGES/system.map
corrisponde alla directory
system
). Puoi quindi fare il check-in di base_fs
file e
specificato tramite PRODUCT_<partition>_BASE_FS_PATH
, come in questo esempio:
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
Sebbene ciò non aiuti a ridurre le dimensioni complessive del pacchetto OTA, migliora l'aggiornamento delle prestazioni riducendo la quantità di I/O. Per gli aggiornamenti A/B virtuali, riduce drasticamente di spazio di archiviazione necessario per applicare l'OTA.
Evitare di aggiornare le app
Oltre a ridurre al minimo le differenze nelle build, puoi ridurre le dimensioni degli aggiornamenti OTA escludendo gli aggiornamenti per le app che ricevono aggiornamenti tramite store. Spesso gli APK comprendono una parte significativa a varie partizioni di un dispositivo. Sono incluse le ultime versioni delle app che vengono aggiornate per app di negozi in un aggiornamento OTA può avere un grande impatto sulle dimensioni dei pacchetti OTA e fornire vantaggio. Quando gli utenti ricevono un pacchetto OTA, potrebbero già disporre dell'app aggiornata. una versione ancora più recente, ricevuta direttamente dagli store.