I fornitori di SoC e OEM che vogliono implementare gli aggiornamenti di sistema A/B devono assicurarsi che il bootloader implementi l'HAL boot_control e passi i parametri corretti al kernel.
Implementa l'HAL boot control
I bootloader compatibili con A/B devono implementare l'HAL boot_control in
hardware/libhardware/include/hardware/boot_control.h. Puoi testare le implementazioni utilizzando l'
system/extras/bootctl
utility e
system/extras/tests/bootloader/.
Devi anche implementare la macchina a stati mostrata di seguito:
Configura il kernel
Per implementare gli aggiornamenti di sistema A/B:
-
Seleziona le seguenti serie di patch del kernel (se necessario):
- Se esegui l'avvio senza ramdisk e utilizzi "boot as recovery", seleziona android-review.googlesource.com/#/c/158491/.
- Per configurare dm-verity senza ramdisk, seleziona android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18.
-
Assicurati che gli argomenti della riga di comando del kernel contengano i seguenti argomenti extra:
... dove il valoreskip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity <public-key-id> <path-to-system-partition>"<public-key-id>è l'ID della chiave pubblica utilizzata per verificare la firma della tabella di integrità (per maggiori dettagli, consulta dm-verity). -
Aggiungi il certificato .X509 contenente la chiave pubblica al portachiavi di sistema:
-
Copia il certificato .X509 formattato in formato
.dernella directory principale dikernelSe il certificato .X509 è formattato come un.pemfile, utilizza il seguenteopensslcomando per convertire da.pema.derformato:openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
-
Crea
zImageper includere il certificato come parte del portachiavi di sistema. Per verificare,controlla la voceprocfs(richiedeKEYS_CONFIG_DEBUG_PROC_KEYSda abilitare): L'inclusione riuscita del certificato .X509 indica la presenza della chiave pubblica nel portachiavi di sistema (l'evidenziazione indica l'ID della chiave pubblica).angler:/# cat /proc/keys 1c8a217e I------ 1 perm 1f010000 0 0 asymmetri Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f [] 2d454e3e I------ 1 perm 1f030000 0 0 keyring .system_keyring: 1/4
-
Sostituisci lo spazio con
#e passalo come<public-key-id>nella riga di comando del kernel. Ad esempio, passaAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40fal posto di<public-key-id>.
-
Copia il certificato .X509 formattato in formato
Imposta le variabili di build
I bootloader compatibili con A/B devono soddisfare i seguenti criteri per le variabili di build:
| Deve essere definito per la destinazione A/B |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk. Facoltativamente, puoi eseguire il passaggio dex2oat post-install (ma pre-riavvio) descritto in
Compilazione.
|
|---|---|
| Vivamente consigliato per la destinazione A/B |
|
| Non può essere definito per la destinazione A/B |
|
| Facoltativo per le build di debug | PRODUCT_PACKAGES_DEBUG += update_engine_client |
Imposta le partizioni (slot)
I dispositivi A/B non hanno bisogno di una partizione di ripristino o di una partizione della cache perché Android non utilizza più
queste partizioni. La partizione dei dati viene ora utilizzata per il pacchetto OTA scaricato e il
codice dell'immagine di ripristino si trova nella partizione di avvio. Tutte le partizioni A/B devono essere denominate
come segue (gli slot sono sempre denominati a, b, e così via): boot_a,
boot_b, system_a, system_b, vendor_a,
vendor_b.
Cache
Per gli aggiornamenti non A/B, la partizione della cache veniva utilizzata per archiviare i pacchetti OTA scaricati e per memorizzare temporaneamente i blocchi durante l'applicazione degli aggiornamenti. Non esisteva un modo efficace per dimensionare la partizione della cache: le dimensioni necessarie dipendevano dagli aggiornamenti che volevi applicare. Nel peggiore dei casi, la partizione della cache sarebbe stata grande quanto l'immagine di sistema. Con gli aggiornamenti A/B non è necessario memorizzare i blocchi (perché scrivi sempre in una partizione non attualmente in uso) e con lo streaming A/B non è necessario scaricare l'intero pacchetto OTA prima di applicarlo.
Ripristino
Il disco RAM di ripristino è ora contenuto nel file boot.img. Quando si passa al
ripristino, il bootloader non può inserire l'opzione skip_initramfs nella riga di comando del kernel.
Per gli aggiornamenti non A/B, la partizione di ripristino contiene il codice utilizzato per applicare gli aggiornamenti. Gli aggiornamenti A/B
vengono applicati da update_engine in esecuzione nell'immagine di sistema avviata regolarmente.
Esiste ancora una modalità di ripristino utilizzata per implementare il ripristino dei dati di fabbrica e il sideloading dei pacchetti di aggiornamento (da cui deriva il nome "ripristino"). Il codice e i dati per la modalità di ripristino
vengono archiviati nella partizione di avvio normale in un disco RAM; per eseguire l'avvio nell'immagine di sistema, il
bootloader indica al kernel di ignorare il disco RAM (altrimenti il dispositivo si avvia in modalità di ripristino
mode. La modalità Recovery [Recovery mode] è piccola (e gran parte era già nella partizione di avvio), quindi le dimensioni della partizione di avvio
non aumentano.
Fstab
L'argomento slotselect deve essere presente nella riga delle partizioni A/B. Ad esempio:
<path-to-block-device>/vendor /vendor ext4 ro wait,verify=<path-to-block-device>/metadata,slotselect
Nessuna partizione deve essere denominata vendor. Verrà invece selezionata e montata la partizione vendor_a o
vendor_b nel punto di montaggio /vendor.
Argomenti dello slot del kernel
Il suffisso dello slot corrente deve essere passato tramite un nodo specifico dell'albero dei dispositivi (DT)
(/firmware/android/slot_suffix) o tramite la
androidboot.slot_suffix riga di comando del kernel o l'argomento bootconfig.
Per impostazione predefinita, fastboot esegue il flash dello slot corrente su un dispositivo A/B. Se il pacchetto di aggiornamento contiene anche immagini per l'altro slot non corrente, fastboot esegue il flash anche di queste immagini. Le opzioni disponibili includono:
-
--slot SLOT. Esegue l'override del comportamento predefinito e richiede a fastboot di eseguire il flash dello slot passato come argomento. -
--set-active [SLOT]. Imposta lo slot come attivo. Se non viene specificato alcun argomento facoltativo viene specificato, lo slot corrente viene impostato come attivo. fastboot --help. Ottieni dettagli sui comandi.
Se il bootloader implementa fastboot, deve supportare il comando
set_active <slot> che imposta lo slot attivo corrente sullo slot specificato (questo
deve anche cancellare il flag non avviabile per quello slot e reimpostare il numero di tentativi sui valori predefiniti
). Il bootloader deve supportare anche le seguenti variabili:
-
has-slot:<partition-base-name-without-suffix>. Restituisce "yes" se la partizione specificata supporta gli slot, "no" in caso contrario. current-slot. Restituisce il suffisso dello slot da cui verrà eseguito l'avvio successivo.-
slot-count. Restituisce un numero intero che rappresenta il numero di slot disponibili. Al momento sono supportati due slot, quindi questo valore è2. -
slot-successful:<slot-suffix>. Restituisce "yes" se lo slot specificato è stato contrassegnato come avviato correttamente, "no" in caso contrario. -
slot-unbootable:<slot-suffix>. Restituisce "yes" se lo slot specificato è contrassegnato come non avviabile, "no" in caso contrario. -
slot-retry-count:<slot-suffix>. Numero di tentativi rimanenti per tentare di avviare lo slot specificato.
Per visualizzare tutte le variabili, esegui
fastboot getvar all.
Genera pacchetti OTA
Gli strumenti per i pacchetti OTA seguono gli stessi comandi dei
comandi per i dispositivi non A/B. Il file target_files.zip deve essere generato definendo le variabili di build per la destinazione A/B. Gli strumenti per i pacchetti OTA identificano
e generano automaticamente i pacchetti nel formato per l'aggiornamento A/B.
Esempi:
-
Per generare un OTA completo:
./build/make/tools/releasetools/ota_from_target_files \ dist_output/tardis-target_files.zip \ ota_update.zip -
Per generare un OTA incrementale:
./build/make/tools/releasetools/ota_from_target_files \ -i PREVIOUS-tardis-target_files.zip \ dist_output/tardis-target_files.zip \ incremental_ota_update.zip
Configura le partizioni
update_engine può aggiornare qualsiasi coppia di partizioni A/B definite nello stesso disco.
Una coppia di partizioni ha un prefisso comune (ad esempio system o boot)
e un suffisso per slot (ad esempio _a). L'elenco delle partizioni per cui il generatore di payload
definisce un aggiornamento è configurato dalla variabile make AB_OTA_PARTITIONS.
Ad esempio, se sono incluse una coppia di partizioni bootloader_a e
booloader_b (_a e _b sono i suffissi dello slot
), puoi aggiornare queste partizioni specificando quanto segue nella configurazione del prodotto o della scheda:
AB_OTA_PARTITIONS := \ boot \ system \ bootloader
Tutte le partizioni aggiornate da update_engine non devono essere modificate dal resto del
sistema. Durante gli aggiornamenti incrementali o delta gli aggiornamenti, i dati binari dello slot corrente vengono
utilizzati per generare i dati nel nuovo slot. Qualsiasi modifica può causare la mancata verifica dei nuovi dati dello slot durante la procedura di aggiornamento e, di conseguenza, l'aggiornamento non andrà a buon fine.
Configura la post-installazione
Puoi configurare il passaggio di post-installazione in modo diverso per ogni partizione aggiornata utilizzando un insieme di
coppie chiave-valore. Per eseguire un programma che si trova in /system/usr/bin/postinst in una nuova
immagine, specifica il percorso relativo alla radice del file system nella partizione di sistema.
Ad esempio, usr/bin/postinst è system/usr/bin/postinst (se non
utilizzi un disco RAM). Inoltre, specifica il tipo di file system da passare alla
mount(2) chiamata di sistema. Aggiungi quanto segue ai file
.mk del prodotto o del dispositivo (se applicabile):
AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=usr/bin/postinst \ FILESYSTEM_TYPE_system=ext4
Compila le app
Le app possono essere compilate in background prima del riavvio con la nuova immagine di sistema. Per compilare app in background, aggiungi quanto segue alla configurazione del dispositivo del prodotto (nel file device.mk del prodotto):
-
Includi i componenti nativi nella build per assicurarti che lo script di compilazione e i file binari vengano
compilati e inclusi nell'immagine di sistema.
# A/B OTA dexopt package PRODUCT_PACKAGES += otapreopt_script
-
Collega lo script di compilazione a
update_enginein modo che venga eseguito come passaggio di post-installazione.# A/B OTA dexopt update_engine hookup AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=system/bin/otapreopt_script \ FILESYSTEM_TYPE_system=ext4 \ POSTINSTALL_OPTIONAL_system=true
Per assistenza sull'installazione dei file preottimizzati nella seconda partizione di sistema inutilizzata, consulta Installazione al primo avvio dei file DEX_PREOPT.