Un bootloader è un'immagine proprietaria del fornitore responsabile dell'avvio del kernel su un dispositivo. Il bootloader protegge lo stato del dispositivo ed è responsabile
dell'inizializzazione del Trusted Execution Environment (TEE)
e del binding della sua radice di attendibilità. Il bootloader verifica anche l'integrità delle partizioni boot e recovery prima di spostare l'esecuzione sul kernel.
Esempio di flusso del bootloader
Ecco un esempio di flusso del bootloader:
Carica e inizializza la memoria.
Verifica il dispositivo in base al flusso di Avvio verificato.
Verifica le partizioni di avvio, tra cui
boot,dtbo,init_boot, erecovery, in base al flusso di Avvio verificato. Nell'ambito di questo passaggio, controlla la versione dell'intestazione dell'immagine di avvio e analizza l'intestazione di conseguenza.Se vengono utilizzati gli aggiornamenti A/B, determina lo slot corrente da avviare.
Determina se deve essere avviata la modalità di ripristino. Per saperne di più, consulta Supportare gli aggiornamenti OTA.
Carica le immagini di avvio, ad esempio
boot.img,vendor_boot.img,init_boot.img, e altre immagini di avvio proprietarie del fornitore. Queste immagini di avvio contengono le immagini del kernel e del ramdisk.Carica il kernel in memoria come binario compresso autoeseguibile. Il kernel si decomprime e inizia l'esecuzione in memoria.
Carica i ramdisk e la sezione bootconfig in memoria per creare
initramfs.
Altre funzionalità correlate al bootloader
Di seguito è riportato un elenco di altre funzionalità correlate al bootloader che puoi implementare:
Overlay di Device Tree (DTO). Un overlay di Device Tree consente al bootloader di supportare diverse configurazioni hardware. Un DTO viene compilato in un blob dell'albero dei dispositivi (DTB) utilizzato dal bootloader.
Randomizzazione dell'indirizzo virtuale dell'immagine del kernel. Il bootloader supporta la randomizzazione dell'indirizzo virtuale in cui viene caricata l'immagine del kernel. Per randomizzare l'indirizzo, imposta
RANDOMIZE_BASEsutruenella configurazione del kernel. Il bootloader deve fornire entropia passando un valore u64 casuale nel nodo dell'albero dei dispositivi/chosen/kaslr-seed.Avvio verificato. L'avvio verificato consente al bootloader di assicurarsi che tutto il codice eseguito provenga da una fonte attendibile.
Configurazione di avvio. La configurazione di avvio è disponibile in Android 12 e versioni successive ed è un meccanismo per passare i dettagli di configurazione dalla compilazione e dal bootloader al sistema operativo. Prima di Android 12, vengono utilizzati i parametri della riga di comando del kernel con il prefisso
androidboot.Aggiornamenti OTA (over-the-air). I dispositivi Android sul campo possono ricevere e installare aggiornamenti OTA per il sistema, il software delle app e le regole del fuso orario. Questa funzionalità ha implicazioni sull'implementazione del bootloader. Per informazioni generali sugli aggiornamenti OTA, consulta Aggiornamenti OTA. Per i dettagli di implementazione OTA specifici del bootloader, consulta Supportare gli aggiornamenti OTA.
Binding della versione. Il binding della versione associa le chiavi di sicurezza alla versione del sistema operativo e al livello di patch. Il binding della versione garantisce che un malintenzionato che scopre una vulnerabilità in una versione precedente del sistema o del software TEE non possa eseguire il rollback di un dispositivo alla versione vulnerabile e utilizzare le chiavi create con la versione più recente. Il bootloader deve fornire determinate informazioni per supportare il binding della versione. Per ulteriori informazioni, consulta Informazioni sulla versione nelle proprietà AVB.
Riga di comando del kernel
Concatena la riga di comando del kernel dalle seguenti posizioni:
Riga di comando del bootloader: insieme di parametri statici e dinamici determinati dal bootloader
Device Tree: dal nodo
chosen/bootargsdefconfig: daCONFIG_CMDLINEboot.img: dalla riga di comando (per offset e dimensioni, consultasystem/core/mkbootimg/bootimg.h
A partire da Android 12, per i parametri androidboot.* che
dobbiamo passare allo spazio utente Android, possiamo utilizzare
bootconfig anziché la riga di comando del kernel.