Motivo di avvio canonico

Android 9 include le seguenti modifiche alla specifica del motivo di avvio del bootloader.

Motivi di avvio

Un bootloader utilizza risorse hardware e di memoria disponibili in modo univoco per determinare il motivo del riavvio di un dispositivo, quindi comunica tale determinazione aggiungendo androidboot.bootreason=<reason> alla riga di comando del kernel Android per il suo avvio. init quindi traduce questa riga di comando per propagarla alla proprietà Android bootloader_boot_reason_prop ( ro.boot.bootreason ). Per i dispositivi che si avviano con Android 12 o versioni successive, utilizzando la versione del kernel 5.10 o successiva, androidboot.bootreason=<reason> viene aggiunto a bootconfig anziché alla riga di comando del kernel.

Specifiche del motivo di avvio

Le versioni precedenti di Android specificavano un formato del motivo di avvio che non utilizzava spazi, era tutto in lettere minuscole, includeva pochi requisiti (come la segnalazione di kernel_panic , watchdog , cold / warm / hard ) e che teneva conto di altri motivi unici. Questa specifica approssimativa ha portato alla proliferazione di centinaia di stringhe di motivi di avvio personalizzate (e talvolta prive di significato), che a loro volta hanno portato a una situazione ingestibile. A partire dall'attuale versione di Android, l'enorme quantità di contenuti quasi non analizzabili o privi di significato archiviati dal bootloader ha creato problemi di conformità per bootloader_boot_reason_prop .

Con la versione Android 9, il team Android riconosce che il legacy bootloader_boot_reason_prop ha uno slancio sostanziale e non può essere riscritto in fase di esecuzione. Qualsiasi miglioramento alla specifica del motivo di avvio deve quindi derivare dalle interazioni con gli sviluppatori del bootloader e dalle modifiche al sistema esistente. A tal fine il team Android è:

  • Coinvolgere gli sviluppatori di bootloader per incoraggiarli a:
    • Fornire ragioni canoniche, analizzabili e riconoscibili a bootloader_boot_reason_prop .
    • Partecipa all'elenco kBootReasonMap system/core/bootstat/bootstat.cpp .
  • Aggiunta di un'origine controllata e riscrivibile in fase di esecuzione di system_boot_reason_prop ( sys.boot.reason ). Un insieme limitato di applicazioni di sistema (come bootstat e init ) può riscrivere questa proprietà, ma a tutte le applicazioni possono essere concessi diritti sepolicy per leggerla.
  • Informare gli utenti del motivo di avvio di attendere fino al montaggio di userdata prima di considerare attendibile il contenuto nella proprietà del motivo di avvio del sistema system_boot_reason_prop .

Perchè così tardi? Sebbene bootloader_boot_reason_prop sia disponibile nelle prime fasi dell'avvio, viene bloccato dalla policy di sicurezza Android in base alle necessità perché rappresenta informazioni imprecise, non analizzabili e non canoniche. Nella maggior parte dei casi, solo gli sviluppatori con una conoscenza approfondita del sistema di avvio dovrebbero accedere a queste informazioni. Un'API raffinata, analizzabile e canonica per il motivo di avvio tramite system_boot_reason_prop può essere raccolta in modo affidabile e accurato solo dopo il montaggio di userdata. Nello specifico:

  • Prima che userdata venga montato, system_boot_reason_prop conterrà il valore di bootloader_boot_reason_prop .
  • Dopo che i dati utente sono stati montati, system_boot_reason_prop potrebbe essere aggiornato per essere conforme o per riportare informazioni più accurate.

Per questo motivo, Android 9 estende il periodo di tempo prima che il motivo di avvio possa essere acquisito ufficialmente, modificandolo dall'essere immediatamente accurato all'avvio (con bootloader_boot_reason_prop ) a essere disponibile solo dopo il montaggio di userdata (con system_boot_reason_prop ).

La logica di Bootstat dipende da un bootloader_boot_reason_prop più informativo e conforme. Quando tale proprietà utilizza un formato prevedibile, migliora la precisione di tutti gli scenari di riavvio e arresto controllati, che a sua volta perfeziona ed espande la precisione e il significato di system_boot_reason_prop .

Formato del motivo di avvio canonico

Il formato canonico del motivo di avvio per bootloader_boot_reason_prop in Android 9 utilizza la seguente sintassi:

<reason>,<subreason>,<detail>…

Regole di formattazione:

  • Minuscolo
  • Nessuno spazio (usa la sottolineatura)
  • Tutti i caratteri stampabili
  • reason separato da virgole, subreason e uno o più detail .
    • Un reason obbligatorio che rappresenta il motivo con la massima priorità per cui è stato necessario riavviare o arrestare il dispositivo.
    • Un subreason secondario facoltativo che rappresenta un breve riepilogo del motivo per cui è stato necessario riavviare o spegnere il dispositivo (o chi ha riavviato o spento il dispositivo).
    • Uno o più valori detail facoltativi. Un detail può puntare a un sottosistema per aiutare a determinare quale sistema specifico ha prodotto il subreason . È possibile specificare più valori detail , che generalmente dovrebbero seguire una gerarchia di importanza. Tuttavia, è anche accettabile riportare più valori detail di pari importanza.

Un valore vuoto per bootloader_boot_reason_prop è considerato illegale (poiché consente ad altri agenti di inserire un motivo di avvio dopo il fatto).

Requisiti della ragione

Il valore fornito per reason (primo intervallo, prima della terminazione o della virgola) deve essere del seguente insieme suddiviso in ragioni fondamentali, forti e schiette:

  • insieme del nocciolo:
    • " watchdog"
    • "kernel_panic"
  • insieme forte:
    • "recovery"
    • "bootloader"
  • set smussato:
    • "cold" . Generalmente indica un ripristino completo di tutti i dispositivi, inclusa la memoria.
    • "hard" . Generalmente indica che lo stato dell'hardware è stato reimpostato e ramoops dovrebbero conservare il contenuto persistente.
    • "warm" . Generalmente indica che la memoria e i dispositivi mantengono uno stato e che l'archivio di backup ramoops (vedere il driver pstore nel kernel) contiene contenuto persistente.
    • "shutdown"
    • "reboot" . Generalmente significa che lo stato ramoops è sconosciuto e lo stato dell'hardware è sconosciuto. Questo valore è generico poiché i valori cold , hard e warm forniscono indizi sulla profondità del ripristino del dispositivo.

I bootloader devono fornire un set di kernel o un reason del set semplice e sono fortemente incoraggiati a fornire un subreason se è possibile determinarlo. Ad esempio, una pressione prolungata del tasto di accensione che può o meno avere il backup ramoops avrebbe il motivo di avvio "reboot,longkey" .

Nessun reason del primo periodo può far parte di un subreason o detail . Tuttavia, poiché i motivi impostati dal kernel non possono essere prodotti dallo spazio utente, "watchdog" può essere riutilizzato dopo un motivo impostato in modo schietto, insieme a un dettaglio della fonte (ad esempio "reboot,watchdog,service_manager_unresponsive" o "reboot,software,watchdog" ).

I motivi di avvio non dovrebbero richiedere conoscenze interne di esperti per essere decifrati e/o dovrebbero essere leggibili dall'uomo con un report intuitivo. Esempi: "shutdown,vbxd" (cattivo), "shutdown,uv" (migliore), "shutdown,undervoltage" (preferito).

Combinazioni motivo-sottomotivo

Android riserva una serie di combinazioni reason - subreason che non devono essere sovraccaricate durante l'utilizzo normale ma possono essere utilizzate caso per caso se la combinazione riflette accuratamente la condizione associata. Esempi di combinazioni riservate includono:

  • "reboot,userrequested"
  • "shutdown,userrequested"
  • "shutdown,thermal" (da thermald )
  • "shutdown,battery"
  • "shutdown,battery,thermal" (da BatteryStatsService )
  • "reboot,adb"
  • "reboot,shell"
  • "reboot,bootloader"
  • "reboot,recovery"

Per maggiori dettagli, fare riferimento a kBootReasonMap in system/core/bootstat/bootstat.cpp e alla cronologia del log delle modifiche git associata nel repository di origine Android.

Segnalazione dei motivi di avvio

Tutti i motivi di avvio, dal bootloader o registrati nel motivo di avvio canonico, devono essere registrati nella sezione kBootReasonMap di system/core/bootstat/bootstat.cpp . L'elenco kBootReasonMap è un mix di motivi conformi e non conformi precedenti. Gli sviluppatori del bootloader dovrebbero registrare qui solo i nuovi motivi di conformità (e non dovrebbero registrare i motivi di non conformità a meno che il prodotto non sia già stato spedito e non possa essere modificato).

Consigliamo vivamente di utilizzare voci esistenti e conformi in system/core/bootstat/bootstat.cpp e di esercitare moderazione prima di utilizzare una stringa non conforme. Come linea guida, è:

  • OK per segnalare "kernel_panic" dal bootloader, poiché bootstat potrebbe essere in grado di ispezionare ramoops per kernel_panic signatures per perfezionare i sottomotivi nel canonico system_boot_reason_prop .
  • Non è consentito segnalare una stringa non conforme in kBootReasonMap (come "panic") dal bootloader, poiché ciò alla fine interromperà la capacità di perfezionare il reason .

Ad esempio, se kBootReasonMap contiene "wdog_bark" , uno sviluppatore del bootloader dovrebbe:

  • Passa a "watchdog,bark" e aggiungi all'elenco in kBootReasonMap .
  • Considera cosa significa "bark" per chi non ha familiarità con la tecnologia e determina se è disponibile una subreason più significativa.

Verifica della conformità del motivo di avvio

Al momento, Android non fornisce un test CTS attivo in grado di attivare o ispezionare con precisione tutti i possibili motivi di avvio che un bootloader potrebbe fornire; i partner possono comunque tentare di eseguire un test passivo per determinare la compatibilità.

Di conseguenza, la conformità del bootloader richiede che gli sviluppatori del bootloader aderiscano volontariamente allo spirito delle regole e delle linee guida sopra descritte. Invitiamo tali sviluppatori a contribuire ad AOSP (in particolare a system/core/bootstat/bootstat.cpp ) e a utilizzare questa opportunità come forum per discussioni sui problemi relativi ai motivi di avvio.