Spostamento di Fastboot in Userspace

Android 10 e versioni successive supportano partizioni ridimensionabili trasferendo l'implementazione di avvio rapido dal bootloader allo spazio utente. Questo riposizionamento consente di spostare il codice lampeggiante in una posizione comune gestibile e testabile con solo le parti di fastboot specifiche del fornitore implementate da un livello di astrazione hardware (HAL). Inoltre, Android 12 e versioni successive supportano il flashing dei ramdisk tramite un comando fastboot aggiunto.

Unificazione di avvio rapido e ripristino

Poiché l'avvio rapido e il ripristino dello spazio utente sono simili, è possibile unirli in un'unica partizione o binario. Ciò offre vantaggi come l'utilizzo di meno spazio, un minor numero di partizioni complessive e la condivisione del kernel e delle librerie da parte dell'avvio rapido e del ripristino.

Per supportare fastbootd , il bootloader deve implementare un nuovo comando BCB (boot control block) di boot-fastboot . Per accedere alla modalità fastbootd , il bootloader scrive boot-fastboot nel campo di comando del messaggio BCB e lascia invariato il campo recovery di BCB (per consentire il riavvio di eventuali attività di ripristino interrotte). Anche i campi status , stage e reserved rimangono invariati. Il bootloader carica e si avvia nell'immagine di ripristino quando vede boot-fastboot nel campo del comando BCB. Il ripristino quindi analizza il messaggio BCB e passa alla modalità fastbootd .

Comandi dell'ADB

Questa sezione descrive il comando adb per l'integrazione fastbootd . Il comando produce risultati diversi, a seconda che venga eseguito dal sistema o dal ripristino.

Comando Descrizione
reboot fastboot
  • Si riavvia in fastbootd (sistema).
  • Entra direttamente in fastbootd senza riavvio (ripristino).

Comandi di avvio rapido

Questa sezione descrive i comandi fastboot per l'integrazione fastbootd , inclusi nuovi comandi per il flashing e la gestione delle partizioni logiche. Alcuni comandi hanno risultati diversi, a seconda che siano stati eseguiti dal bootloader o da fastbootd .

Comando Descrizione
reboot recovery
  • Si riavvia in modalità di ripristino (bootloader).
  • Entra direttamente nel ripristino senza riavvio ( fastbootd ).
reboot fastboot Si riavvia in fastbootd .
getvar is-userspace
  • Restituisce yes ( fastbootd ).
  • Restituisce no (bootloader).
getvar is-logical: <partition> Restituisce yes se la partizione specificata è una partizione logica, no altrimenti. Le partizioni logiche supportano tutti i comandi elencati di seguito.
getvar super-partition-name Restituisce il nome della super partizione. Il nome include il suffisso dello slot corrente se la super partizione è una partizione A/B (di solito non lo è).
create-logical-partition <partition> <size> Crea una partizione logica con il nome e la dimensione specificati. Il nome non deve già esistere come partizione logica.
delete-logical-partition <partition> Elimina la partizione logica specificata (cancella efficacemente la partizione).
resize-logical-partition <partition> <size> Ridimensiona la partizione logica alla nuova dimensione senza modificarne il contenuto. Fallisce se non c'è abbastanza spazio disponibile per eseguire il ridimensionamento.
update-super <partition> Unisce le modifiche ai metadati della super partizione. Se un'unione non è possibile (ad esempio, il formato sul dispositivo è una versione non supportata), questo comando non riesce. Un parametro wipe opzionale sovrascrive i metadati del dispositivo, anziché eseguire un'unione.
flash <partition> [ <filename> ] Scrive un file su una partizione flash. Il dispositivo deve essere nello stato sbloccato.
erase <partition> Cancella una partizione (non necessaria per la cancellazione sicura). Il dispositivo deve essere nello stato sbloccato.
getvar <variable> | all Visualizza una variabile del bootloader o tutte le variabili. Se la variabile non esiste, restituisce un errore.
set_active <slot>

Imposta lo slot di avvio A/B specificato come active . Al successivo tentativo di avvio, il sistema si avvia dallo slot specificato.

Per il supporto A/B, gli slot sono set duplicati di partizioni da cui è possibile eseguire l'avvio in modo indipendente. Gli slot sono denominati a , b e così via e differenziati aggiungendo i suffissi _a , _b e così via al nome della partizione.

reboot Riavvia normalmente il dispositivo.
reboot-bootloader (o reboot bootloader ) Riavvia il dispositivo nel bootloader.
fastboot fetch vendor_boot <out.img>

Utilizzare in Android 12 e versioni successive per supportare i ramdisk del fornitore lampeggiante.

Ottiene la dimensione dell'intera partizione e la dimensione del blocco. Ottiene i dati per ogni blocco, quindi unisce i dati in <out.img>

Per i dettagli, vedere fastboot fetch vendor_boot <out.img> .

fastboot flash vendor_boot:default <vendor-ramdisk.img>

Utilizzare in Android 12 e versioni successive per supportare i ramdisk del fornitore lampeggiante.

Questa è una variante speciale del comando flash. Esegue una funzione fetch vendor_boot , come se fosse chiamato fastboot fetch . La nuova immagine vendor_boot che lampeggia dipende dal fatto che la versione dell'intestazione di avvio sia la versione 3 o la versione 4.

Per i dettagli, vedere fastboot flash vendor_boot:default <vendor-ramdisk.img> .

fastboot flash vendor_boot: <foo> <vendor-ramdisk.img> Utilizzare in Android 12 e versioni successive per supportare i ramdisk del fornitore lampeggiante.

Recupera l'immagine vendor_boot . Restituisce un errore se l'intestazione di avvio del fornitore è la versione 3. Se è la versione 4, trova il frammento ramdisk del fornitore corretto (se disponibile). La sostituisce con l'immagine specificata, ricalcola le dimensioni e gli offset e esegue il flashing della nuova vendor_boot image .

Per i dettagli, vedere fastboot flash vendor_boot: <foo> <vendor-ramdisk.img>

Avvio rapido e bootloader

Il bootloader esegue il flashing delle partizioni bootloader , radio e boot/recovery , dopodiché il dispositivo si avvia in fastboot (spazio utente) e esegue il flashing di tutte le altre partizioni. Il bootloader dovrebbe supportare i seguenti comandi.

Comando Descrizione
download Scarica l'immagine in flash.
flash recovery <image> / flash boot <image> / flash bootloader <image> / Lampeggia la partizione recovery/boot e il bootloader.
reboot Riavvia il dispositivo.
reboot fastboot Riavvia in avvio rapido.
reboot recovery Si riavvia in ripristino.
getvar Ottiene una variabile del bootloader necessaria per il flashing dell'immagine di ripristino/avvio (ad esempio, current-slot e max-download-size ).
oem <command> Comando definito dall'OEM.

Partizioni dinamiche

Il bootloader non deve consentire il flashing o la cancellazione di partizioni dinamiche e deve restituire un errore se vengono tentate queste operazioni. Per i dispositivi con partizione dinamica retrofittati, lo strumento fastboot (e bootloader) supporta una modalità forzata per eseguire il flashing diretto di una partizione dinamica mentre si è in modalità bootloader. Ad esempio, se system è una partizione dinamica sul dispositivo retrofittato, utilizzando il comando fastboot --force flash system si consente al bootloader (invece di fastbootd ) di eseguire il flashing della partizione.

Ricarica in modalità off

Se un dispositivo supporta la ricarica in modalità off o altrimenti si avvia automaticamente in una modalità speciale quando viene applicata l'alimentazione, un'implementazione del comando fastboot oem off-mode-charge 0 deve ignorare queste modalità speciali, in modo che il dispositivo si avvii come se l'utente avesse premuto il pulsante di accensione.

HAL OEM di avvio rapido

Per sostituire completamente il fastboot del bootloader, fastboot deve gestire tutti i comandi fastboot esistenti. Molti di questi comandi provengono da OEM e sono documentati ma richiedono un'implementazione personalizzata. Molti comandi specifici dell'OEM non sono documentati. Per gestire tali comandi, l'HAL di avvio rapido specifica i comandi OEM richiesti. Gli OEM possono anche implementare i propri comandi.

La definizione di HAL di avvio rapido è la seguente:

import IFastbootLogger;

/**
 * IFastboot interface implements vendor specific fastboot commands.
 */
interface IFastboot {
    /**
     * Returns a bool indicating whether the bootloader is enforcing verified
     * boot.
     *
     * @return verifiedBootState True if the bootloader is enforcing verified
     * boot and False otherwise.
     */
    isVerifiedBootEnabled() generates (bool verifiedBootState);

    /**
     * Returns a bool indicating the off-mode-charge setting. If off-mode
     * charging is enabled, the device autoboots into a special mode when
     * power is applied.
     *
     * @return offModeChargeState True if the setting is enabled and False if
     * not.
     */
    isOffModeChargeEnabled() generates (bool offModeChargeState);

    /**
     * Returns the minimum battery voltage required for flashing in mV.
     *
     * @return batteryVoltage Minimum battery voltage (in mV) required for
     * flashing to be successful.
     */
    getBatteryVoltageFlashingThreshold() generates (int32_t batteryVoltage);

    /**
     * Returns the file system type of the partition. This is only required for
     * physical partitions that need to be wiped and reformatted.
     *
     * @return type Can be ext4, f2fs or raw.
     * @return result SUCCESS if the operation is successful,
     * FAILURE_UNKNOWN if the partition is invalid or does not require
     * reformatting.
     */
    getPartitionType(string partitionName) generates (FileSystemType type, Result result);

    /**
     * Executes a fastboot OEM command.
     *
     * @param oemCmd The oem command that is passed to the fastboot HAL.
     * @response result Returns the status SUCCESS if the operation is
     * successful,
     * INVALID_ARGUMENT for bad arguments,
     * FAILURE_UNKNOWN for an invalid/unsupported command.
     */
    doOemCommand(string oemCmd) generates (Result result);

};

Abilitazione fastboot

Per abilitare fastbootd su un dispositivo:

  1. Aggiungi fastbootd PRODUCT_PACKAGES in device.mk : PRODUCT_PACKAGES += fastbootd .

  2. Assicurarsi che l'HAL di avvio rapido, l'HAL di controllo di avvio e l'HAL di integrità siano inclusi nel pacchetto come parte dell'immagine di ripristino.

  3. Aggiungi eventuali autorizzazioni SEPolicy specifiche del dispositivo richieste da fastbootd . Ad esempio, fastbootd richiede l'accesso in scrittura a una partizione specifica del dispositivo per eseguire il flashing di quella partizione. Inoltre, l'implementazione dell'HAL di avvio rapido potrebbe richiedere anche autorizzazioni specifiche del dispositivo.

Per convalidare l'avvio rapido dello spazio utente, eseguire Vendor Test Suite (VTS) .

Ramdisk del fornitore lampeggianti

Android 12 e versioni successive forniscono supporto per il flashing dei ramdisk con un comando fastboot aggiunto che estrae l'immagine vendor_boot completa da un dispositivo. Il comando richiede allo strumento fastboot lato host di leggere l'intestazione di avvio del fornitore, reimmaginare ed eseguire il flashing della nuova immagine.

Per estrarre l'immagine vendor_boot completa, il comando fetch:vendor_boot è stato aggiunto sia al protocollo fastboot che all'implementazione fastbootd del protocollo in Android 12. Tieni presente che fastbootd lo implementa , ma il bootloader stesso potrebbe non farlo. Gli OEM possono aggiungere il comando fetch:vendor_boot all'implementazione del protocollo nel bootloader. Tuttavia, se il comando non viene riconosciuto in modalità bootloader, il flashing dei singoli ramdisk del fornitore in modalità bootloader non è un'opzione supportata dal fornitore.

Modifiche al bootloader

I comandi getvar:max-fetch-size e fetch:name sono implementati in fastbootd . Per supportare il flashing dei ramdisk del fornitore nel bootloader, è necessario implementare questi due comandi.

Modifiche al fastboot

getvar:max-fetch-size è simile a max-download-size . Specifica la dimensione massima che il dispositivo può inviare in una risposta DATI. Il driver non deve recuperare una dimensione maggiore di questo valore.

fetch:name[:offset[:size]] esegue una serie di controlli sul dispositivo. Se tutte le seguenti condizioni sono vere, il comando fetch:name[:offset[:size]] restituisce i dati:

  • Il dispositivo esegue una build di cui è possibile eseguire il debug.
  • Il dispositivo è sbloccato (stato di avvio arancione).
  • Il nome della partizione recuperata è vendor_boot .
  • Il valore size rientra tra 0 < size <= max-fetch-size .

Una volta verificati, fetch:name[:offset[:size]] restituisce la dimensione e l'offset della partizione. Tieni presente quanto segue:

  • fetch:name è equivalente a fetch:name:0 , che è equivalente a fetch:name:0:partition_size .
  • fetch:name:offset è equivalente a fetch:name:offset:(partition_size - offset)

Pertanto fetch:name[:offset[:size]] = fetch:name:offset:(partition_size - offset)

Quando offset o partition_size (o entrambi) non sono specificati, vengono utilizzati i valori predefiniti, che per offset è 0 e per size è il valore calcolato di partition_size - offset .

  • Offset specificato, dimensione non specificata: size = partition_size - offset
  • Nessuno dei due specificato: valori predefiniti utilizzati per entrambi, size = partition_size - 0.

Ad esempio, fetch:foo recupera l'intera partizione foo con offset 0.

Cambiamenti di conducente

Sono stati aggiunti comandi allo strumento fastboot per implementare le modifiche al driver. Ciascuno è linkato alla sua definizione completa nella tabella dei comandi Fastboot .

  • fastboot fetch vendor_boot out.img

    • Chiama getvar max-fetch-size per determinare la dimensione del blocco.
    • Chiama getvar partition-size:vendor_boot[_a] per determinare la dimensione dell'intera partizione.
    • Chiama fastboot fetch vendor_boot[_a]:offset:size per ogni blocco. (La dimensione del blocco è maggiore della dimensione del vendor_boot , quindi normalmente c'è solo un blocco.)
    • Unisce insieme i dati, in out.img .
  • fastboot flash vendor_boot:default vendor-ramdisk.img

    Questa è una variante speciale del comando flash. Recupera l'immagine vendor_boot , come se fosse chiamato fastboot fetch .

    • Se l'avvio del fornitore è l'intestazione versione 3 , esegue le seguenti operazioni:
      • Sostituisce il ramdisk del fornitore con l'immagine specificata.
      • Fa lampeggiare la nuova immagine vendor_boot .
    • Se l'intestazione di avvio del fornitore è la versione 4 , esegue le seguenti operazioni:
      • Sostituisce l'intero ramdisk del fornitore con l'immagine data in modo che l'immagine data diventi l'unico frammento del ramdisk del fornitore nell'immagine vendor_boot .
      • Ricalcola la dimensione e l'offset nella tabella ramdisk del fornitore.
      • Fa lampeggiare la nuova immagine vendor_boot .
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

    Recupera vendor_boot image , come se fosse stato chiamato fastboot fetch .

    • Se l'intestazione di avvio del fornitore è la versione 3, restituisce un errore.
    • Se l'intestazione di avvio del fornitore è la versione 4, esegue le seguenti operazioni:

      • Trova il frammento del ramdisk del fornitore con il nome foo . Se non viene trovato o se sono presenti più corrispondenze, restituisce un errore.
      • Sostituisce il frammento del ramdisk del fornitore con l'immagine specificata.
      • Ricalcola ciascuna dimensione e offset nella tabella ramdisk del fornitore.
      • Fa lampeggiare la nuova immagine vendor_boot .

mkbootimg

Il nome default è riservato alla denominazione dei frammenti del disco ram del fornitore in Android 12 e versioni successive. Sebbene la semantica di fastboot flash vendor_boot:default rimanga la stessa, non è necessario denominare i frammenti del ramdisk come default .

SELinux cambia

È stata apportata una modifica a fastbootd.te per supportare il flashing dei ramdisk del fornitore.