Motif du démarrage canonique

Android 9 inclut les modifications suivantes apportées à la spécification du motif de démarrage du bootloader.

Motifs de démarrage

Un bootloader utilise des ressources matérielles et de mémoire à disponibilité unique pour déterminer pourquoi un appareil a redémarré, puis communique cette détermination en ajoutant androidboot.bootreason=<reason> à la ligne de commande du noyau Android pour son lancement. init traduit ensuite cette ligne de commande pour se propager dans la propriété Android bootloader_boot_reason_prop (ro.boot.bootreason). Pour les appareils équipés d'Android 12 ou version ultérieure et qui utilisent la version 5.10 ou une version ultérieure du noyau, androidboot.bootreason=<reason> est ajouté à bootconfig au lieu de la ligne de commande du noyau.

Spécifications du motif de démarrage

Les versions précédentes d'Android spécifiaient un format de motif de démarrage qui n'utilisait pas d'espaces, était tout en minuscules, incluait peu d'exigences (par exemple, pour signaler kernel_panic, watchdog, cold/warm/hard), et qui permettait d'utiliser d'autres raisons uniques. Cette spécification souple a entraîné la prolifération de centaines de chaînes de motif de démarrage personnalisées (et parfois insignifiantes), ce qui a conduit à une situation ingérable. Depuis la version actuelle d'Android, l'émergence de contenus quasi impossibles à analyser ou dénué de sens créés par le bootloader a créé des problèmes de conformité pour bootloader_boot_reason_prop.

Avec la version Android 9, l'équipe Android reconnaît que l'ancienne version bootloader_boot_reason_prop connaît un essor important et ne peut pas être réécrite au moment de l'exécution. Toute amélioration apportée à la spécification du motif de démarrage doit donc provenir d'interactions avec les développeurs de bootloaders et d'ajustements apportés au système existant. À cette fin, l'équipe Android est:

  • Interagir avec les développeurs de bootloaders pour les encourager à :
    • Indiquez des motifs canoniques, analysables et reconnaissables à bootloader_boot_reason_prop.
    • Participez à la liste system/core/bootstat/bootstat.cpp kBootReasonMap.
  • Ajout d'une source contrôlée et réinscriptible pour l'environnement d'exécution de system_boot_reason_prop (sys.boot.reason). Un ensemble limité d'applications système (telles que bootstat et init) peut réécrire cette propriété, mais toutes les applications peuvent obtenir des droits sepolicy pour la lire.
  • Informe les utilisateurs du motif d'attente jusqu'à l'installation des données utilisateur avant de faire confiance au contenu de la propriété system_boot_reason_prop du motif de démarrage du système.

Pourquoi si tard ? Bien que bootloader_boot_reason_prop soit disponible au début du démarrage, il est bloqué par les règles de sécurité Android au besoin, car il représente des informations inexactes, impossibles à analyser et non canoniques. Dans la plupart des cas, seuls les développeurs ayant une connaissance approfondie du système de démarrage devraient avoir accès à ces informations. Une API affinée, analysable et canonique pour un motif de démarrage avec system_boot_reason_prop ne peut être récupérée de manière fiable et précise qu'après l'installation des données utilisateur. Plus spécifiquement :

  • Avant l'installation des données utilisateur, system_boot_reason_prop contiendra la valeur de bootloader_boot_reason_prop.
  • Une fois les données utilisateur installées, system_boot_reason_prop peut être mis à jour pour être conforme ou pour signaler des informations plus précises.

Pour cette raison, Android 9 prolonge le délai avant que le motif de démarrage ne puisse être officiellement obtenu. Il est ainsi passé d'une précision immédiate au démarrage (avec bootloader_boot_reason_prop) à une disponibilité uniquement après l'installation des données utilisateur (avec system_boot_reason_prop).

La logique de Bootstat dépend d'un bootloader_boot_reason_prop plus informatif et conforme. Lorsque cette propriété utilise un format prévisible, elle améliore la précision de tous les scénarios de redémarrage et d'arrêt contrôlés, ce qui améliore et améliore la précision et la signification de system_boot_reason_prop.

Format du motif de démarrage canonique

Le format de motif de démarrage canonique pour bootloader_boot_reason_prop sous Android 9 utilise la syntaxe suivante:

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

Règles de mise en forme:

  • Tout en minuscules
  • Pas de blancs (trait de soulignement)
  • Tous les caractères imprimables
  • Séparés par des virgules reason, subreason, et une ou plusieurs instances detail.
    • Un élément reason obligatoire qui représente la priorité la plus élevée pour laquelle l'appareil a dû redémarrer ou s'arrêter.
    • subreason facultatif qui représente un bref résumé de la raison pour laquelle l'appareil a dû redémarrer ou s'arrêter (ou qui a redémarré ou arrêté l'appareil).
    • Une ou plusieurs valeurs detail facultatives. Un detail peut pointer vers un sous-système pour aider à déterminer quel système spécifique a généré l'subreason. Vous pouvez spécifier plusieurs valeurs detail, qui doivent généralement suivre une hiérarchie d'importance. Toutefois, il est également possible de signaler plusieurs valeurs detail d'importance égale.

Une valeur vide pour bootloader_boot_reason_prop est considérée comme illégale (car cela permet aux autres agents d'injecter un motif de démarrage après coup).

Exigences concernant les motifs

La valeur donnée pour reason (premier segment, avant l'arrêt ou la virgule) doit être de l'ensemble suivant, divisée en raisons de noyau, de forte et de priorité:

  • noyau défini :
    • "watchdog"
    • "kernel_panic"
  • fort :
    • "recovery"
    • "bootloader"
  • émoussée :
    • "cold" : indique généralement une réinitialisation complète de tous les appareils, mémoire comprise.
    • "hard" : indique généralement que l'état du matériel a été réinitialisé et que ramoops doit conserver un contenu persistant.
    • "warm" : indique généralement que la mémoire et les appareils conservent un certain état, et que le magasin de sauvegarde ramoops (voir le pilote pstore dans le noyau) contient du contenu persistant.
    • "shutdown"
    • "reboot". Cela signifie généralement que l'état ramoops est inconnu et que l'état du matériel est inconnu. Cette valeur est un collectif, car les valeurs cold, hard et warm fournissent des indices sur la profondeur de la réinitialisation de l'appareil.

Les chargeurs de démarrage doivent fournir un ensemble de noyau ou un reason à ensemble contondant, et nous vous recommandons vivement de fournir un subreason s'il peut être déterminé. Par exemple, un appui prolongé sur le bouton Marche/Arrêt pouvant ou non contenir une sauvegarde ramoops aura le motif de démarrage "reboot,longkey".

Aucun élément reason de premier délai ne peut faire partie d'un élément subreason ou detail. Toutefois, comme les motifs d'ensemble du noyau ne peuvent pas être produits par l'espace utilisateur, "watchdog" peut être réutilisé après un motif d'ensemble arrondi, avec un détail de la source (par exemple, "reboot,watchdog,service_manager_unresponsive" ou "reboot,software,watchdog").

Les motifs de démarrage ne doivent pas nécessiter de connaissances internes spécialisées pour déchiffrer et/ou doivent être lisibles par l'humain avec un rapport intuitif. Exemples : "shutdown,vbxd" (mauvais), "shutdown,uv" (mieux), "shutdown,undervoltage" (recommandé).

Combinaisons motif/sous-motif

Android réserve un ensemble de combinaisons reason-subreason qui ne doivent pas être surchargées dans l'utilisation normale, mais qui peuvent être utilisées au cas par cas si la combinaison reflète avec précision la condition associée. Exemples de combinaisons réservées:

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

Pour en savoir plus, consultez kBootReasonMap dans system/core/bootstat/bootstat.cpp et l'historique du journal des modifications Git associé dans le dépôt source Android.

Signaler les motifs de démarrage

Tous les motifs de démarrage, qu'ils proviennent du bootloader ou enregistrés dans le motif de démarrage canonique, doivent être enregistrés dans la section kBootReasonMap de system/core/bootstat/bootstat.cpp. La liste kBootReasonMap combine des motifs de conformité et d'anciens non-conformités. Les développeurs de bootloaders ne doivent enregistrer que les nouveaux motifs de conformité ici (et ne doivent pas enregistrer de motifs de non-conformité, sauf si le produit a déjà été expédié et ne peut pas être modifié).

Nous vous recommandons vivement d'utiliser des entrées existantes conformes dans system/core/bootstat/bootstat.cpp et de faire preuve de restriction avant d'utiliser une chaîne non conforme. À titre indicatif:

  • OK pour signaler "kernel_panic" à partir du bootloader, car bootstat peut inspecter ramoops pour kernel_panic signatures afin d'affiner les sous-raisons dans le system_boot_reason_prop canonique.
  • N'accepte pas de signaler une chaîne non conforme dans kBootReasonMap (telle que "panic") depuis le bootloader), car cela interromprait la possibilité d'affiner le reason.

Par exemple, si kBootReasonMap contient "wdog_bark", le développeur d'un bootloader doit:

  • Remplacez "watchdog,bark" et ajoutez à la liste dans kBootReasonMap.
  • Réfléchissez à ce que signifie "bark" pour ceux qui ne la connaissent pas et déterminez si une subreason plus pertinente est disponible.

Vérifier la conformité du motif de démarrage

Pour le moment, Android ne fournit pas de test CTS actif capable de déclencher ou d'inspecter avec précision toutes les raisons de démarrage possibles d'un bootloader. Les partenaires peuvent toujours essayer d'exécuter un test passif pour déterminer la compatibilité.

Par conséquent, la conformité avec le bootloader exige que les développeurs de bootloaders adhèrent volontairement à l'esprit des règles et des consignes décrites ci-dessus. Nous invitons ces développeurs à contribuer à AOSP (en particulier à system/core/bootstat/bootstat.cpp) et à profiter de cette opportunité comme forum de discussion sur les problèmes liés au démarrage.