Sposta fastboot nello spazio utente

Fastboot è il nome di un modulo e di una modalità del bootloader. Android 10 e versioni successive supportano le partizioni ridimensionabili spostando l'implementazione di Fastboot dal bootloader allo spazio utente. Questa rilocazione consente di spostare il codice di aggiornamento in una posizione comune manutenibile 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 delle ramdisk tramite un comando fastboot aggiunto.

Unificare fastboot e recovery

Poiché il fastboot e il recupero nello spazio utente sono simili, puoi unirli in una sola partizione o in un unico file binario. Ciò offre vantaggi come l'utilizzo di meno spazio, un numero inferiore di partizioni complessive e la condivisione del kernel e delle librerie tra fastboot e recovery.

Fastbootd è il nome di un demone e di una modalità nello spazio utente. 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 del BCB (per consentire il riavvio di eventuali attività di recupero interrotte). Anche i campi status, stage e reserved rimangono invariati. Il bootloader si carica e avvia l'immagine di ripristino quando viene visualizzato boot-fastboot nel campo del comando BCB. Il recupero analizza quindi il messaggio BCB e passa alla modalità fastbootd.

Comandi ADB

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

Comando Descrizione
reboot fastboot
  • Riavvia in fastbootd (sistema).
  • Accede direttamente a fastbootd senza riavvio (recupero).

Comandi Fastboot

Questa sezione descrive i comandi fastboot per l'integrazione di fastbootd, inclusi i 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
  • Riavvia in modalità di ripristino (bootloader).
  • Accedi direttamente alla modalità di ripristino senza riavvio (fastbootd).
reboot fastboot 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 partizione super è una partizione A/B (di solito non lo è).
create-logical-partition <partition> <size> Crea una partizione logica con il nome e le dimensioni specificati. Il nome non deve già esistere come partizione logica.
delete-logical-partition <partition> Consente di eliminare la partizione logica specificata (in pratica la cancella).
resize-logical-partition <partition> <size> Modifica le dimensioni della partizione logica in base alle nuove dimensioni senza modificarne i contenuti. Non va a buon fine se non è disponibile spazio sufficiente per eseguire il ridimensionamento.
flash <partition><filename> ] Scrive un file in una partizione flash. Il dispositivo deve essere sbloccato.
erase <partition> Resetta una partizione (non è necessario che sia un'eliminazione sicura). Il dispositivo deve essere in stato sbloccato.
getvar <variable> | all Mostra una variabile del bootloader o tutte le variabili. Se la variabile non esiste, viene restituito 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 insiemi duplicati di partizioni che possono essere avviate 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 Il dispositivo si riavvia normalmente.
reboot-bootloader (o reboot bootloader) Riavvia il dispositivo nel bootloader.
fastboot fetch vendor_boot <out.img>

Da utilizzare in Android 12 e versioni successive per supportare il flashing dei ramdisk del fornitore.

Recupera le dimensioni dell'intera partizione e quelle del chunk. Recupera i dati per ogni blocco, poi li unisce per <out.img>

Per maggiori dettagli, vedi fastboot fetch vendor_boot <out.img>.

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

Da utilizzare in Android 12 e versioni successive per supportare il flashing dei ramdisk del fornitore.

Si tratta di una variante speciale del comando flash. Esegue una funzione di immagine fetch vendor_boot, come se fosse stata chiamata fastboot fetch. La nuova immagine vendor_boot che lampeggia dipende dal fatto che la versione dell'intestazione del bootloader sia 3 o 4.

Per maggiori dettagli, consulta fastboot flash vendor_boot:default <vendor-ramdisk.img>.

fastboot flash vendor_boot:<foo> <vendor-ramdisk.img> Da utilizzare in Android 12 e versioni successive per supportare il flashing dei ramdisk del fornitore.

Recupera l'immagine vendor_boot. Restituisce un errore se l'intestazione di avvio del fornitore è la versione 3. Se si tratta della versione 4, viene trovato il frammento del ramdisk del fornitore corretto (se disponibile). Lo sostituisce con l'immagine specificata, ricalcola le dimensioni e gli offset e lampeggia il nuovo vendor_boot image.

Per maggiori dettagli, vedi fastboot flash vendor_boot:<foo> <vendor-ramdisk.img>

Fastboot e bootloader

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

Comando Descrizione
download Scarica l'immagine da eseguire in flash.
flash recovery <image>/ flash boot <image>/ flash bootloader <image>/ Esegue il flashing della partizione recovery/boot e del bootloader.
reboot Riavvia il dispositivo.
reboot fastboot Si riavvia in fastboot.
reboot recovery Riavvia in modalità di ripristino.
getvar Recupera una variabile del bootloader necessaria per il flashing dell'immagine di recupero/boot (ad esempio current-slot e max-download-size).
oem <command> Comando definito dall'OEM.

Partizioni dinamiche

Il bootloader non deve consentire il flashing o l'eliminazione delle partizioni dinamiche e deve restituire un errore se vengono tentate queste operazioni. Per i dispositivi con partizione dinamica sottoposta a retrofit, lo strumento fastboot (e il bootloader) supporta una modalità forzata per eseguire il flashing diretto di una partizione dinamica in modalità bootloader. Ad esempio, se system è una partizione dinamica sul dispositivo sottoposto a retrofit, l'utilizzo del comando fastboot --force flash system consente al bootloader (anziché a fastbootd) di eseguire il flashing della partizione.

Ricarica in modalità off

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

Fastboot OEM HAL

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

La definizione di HAL fastboot è 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);

};

Attivare fastbootd

Per attivare fastbootd su un dispositivo:

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

  2. Assicurati che l'HAL fastboot, l'HAL di controllo dell'avvio e l'HAL di salute siano pacchettizzati nell'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 della partizione. Inoltre, l'implementazione dell'HAL di fastboot può anche richiedere autorizzazioni specifiche per il dispositivo.

Per convalidare il fastboot nello spazio utente, esegui la Vendor Test Suite (VTS).

Ramdisk del fornitore di Flash

Android 12 e versioni successive supportano il flashing delle ramdisk con un comando fastboot aggiuntivo che estrae l'immagine completavendor_boot da un dispositivo. Il comando chiede allo strumento fastboot sul lato host di leggere l'intestazione di avvio del fornitore, eseguire il reimaging e il flashing della nuova immagine.

Per estrarre l'immagine completa vendor_boot, il comando fetch:vendor_boot è stato aggiunto sia al protocollo fastboot sia all'implementazione del protocollo fastbootd in Android 12. Tieni presente che fastbootd implementa questa funzionalità, ma il bootloader stesso potrebbe non farlo. Gli OEM possono aggiungere il comando fetch:vendor_boot all'implementazione del bootloader del protocollo. Tuttavia, se il comando non viene riconosciuto in modalità bootloader, il flashing di 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 delle ramdisk del fornitore nel bootloader, devi implementare questi due comandi.

Modifiche a fastbootd

getvar:max-fetch-size è simile a max-download-size. Specifica la dimensione massima che il dispositivo può inviare in una risposta DATA. 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 condizioni riportate di seguito sono vere, il comando fetch:name[:offset[:size]] restituisce i dati:

  • Sul dispositivo è in esecuzione 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 nell'intervallo 0 < size <= max-fetch-size.

Una volta verificati, fetch:name[:offset[:size]] restituisce le dimensioni e l'offset della partizione. Nota:

  • 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 sono 0 e per size è il valore calcolato di partition_size - offset.

  • Offset specificato, dimensioni non specificate: size = partition_size - offset
  • Nessuno specificato: valori predefiniti utilizzati per entrambi, size = partition_size - 0.

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

Modifiche al conducente

Sono stati aggiunti comandi allo strumento fastboot per implementare le modifiche del driver. Ognuno è collegato alla relativa definizione completa nella tabella dei comandi Fastboot.

  • fastboot fetch vendor_boot out.img

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

    Si tratta di una variante speciale del comando flash. Recupera l'immagine vendor_boot, come se fosse stata chiamata fastboot fetch.

    • Se il boot del fornitore è la versione dell'intestazione 3, esegue quanto segue:
      • Sostituisce il ramdisk del fornitore con l'immagine specificata.
      • La nuova immagine vendor_boot lampeggia.
    • Se l'intestazione di avvio del fornitore è versione 4, esegue le seguenti operazioni:
      • Sostituisce l'intero ramdisk del fornitore con l'immagine specificata in modo che quest'ultima diventi l'unico frammento del ramdisk del fornitore nell'immagine vendor_boot.
      • Ricacula le dimensioni e l'offset nella tabella del ramdisk del fornitore.
      • La nuova immagine vendor_boot lampeggia.
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

    Recupera vendor_boot image, come se fosse stata chiamata fastboot fetch.

    • Se l'intestazione di avvio del fornitore è la versione 3, viene restituito 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 ramdisk_<var>&lt;foo></var>. Se non viene trovata alcuna corrispondenza o se sono presenti più corrispondenze, viene restituito un errore.
      • Sostituisce il frammento del ramdisk del fornitore con l'immagine specificata.
      • Ricacula ogni dimensione e offset nella tabella del ramdisk del fornitore.
      • La nuova immagine vendor_boot lampeggia.
    • Se <foo> non è specificato, viene cercato ramdisk_.

mkbootimg

Il nome default è riservato alla denominazione dei frammenti del ramdisk del fornitore in Android 12 e versioni successive. Anche se la semantica di flash vendor_boot:default rimane invariata, non devi assegnare ai frammenti del ramdisk il nome default.

Modifiche a SELinux

È stata apportata una modifica in fastbootd.te per supportare il flashing delle ramdisk del fornitore.