Riduci dimensioni OTA

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 come PRODUCT_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 strumento bsdiff 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:

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:

di Gemini Advanced.

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:

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:

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.