Motivo de arranque canónico

Android 9 incluye los siguientes cambios en la especificación del motivo de inicio del gestor de arranque.

Razones de arranque

Un gestor de arranque utiliza recursos de memoria y hardware disponibles de forma única para determinar por qué se reinició un dispositivo y luego comunica esa determinación agregando androidboot.bootreason=<reason> a la línea de comando del kernel de Android para su inicio. init luego traduce esta línea de comando para propagarla a la propiedad de Android bootloader_boot_reason_prop ( ro.boot.bootreason ). Para dispositivos que se inician con Android 12 o posterior, usando la versión del kernel 5.10 o superior, se agrega androidboot.bootreason=<reason> a bootconfig en lugar de a la línea de comando del kernel.

Especificaciones del motivo de arranque

Las versiones anteriores de Android especificaban un formato de motivo de arranque que no utilizaba espacios, estaba todo en minúsculas, incluía pocos requisitos (como informar kernel_panic , watchdog , cold / warm / hard ) y tenía en cuenta otras razones únicas. Esta especificación laxa resultó en la proliferación de cientos de cadenas de motivos de arranque personalizadas (y a veces sin sentido), lo que a su vez condujo a una situación inmanejable. A partir de la versión actual de Android, el gran impulso del contenido casi imposible de analizar o sin sentido presentado por el gestor de arranque ha creado problemas de cumplimiento para bootloader_boot_reason_prop .

Con el lanzamiento de Android 9, el equipo de Android reconoce que el bootloader_boot_reason_prop heredado tiene un impulso sustancial y no se puede reescribir en tiempo de ejecución. Por lo tanto, cualquier mejora en la especificación del motivo de arranque debe provenir de interacciones con los desarrolladores del gestor de arranque y ajustes en el sistema existente. Para ello el equipo de Android es:

  • Colaborar con los desarrolladores de gestores de arranque para animarlos a:
    • Proporcione razones canónicas, analizables y reconocibles para bootloader_boot_reason_prop .
    • Participe en la lista system/core/bootstat/bootstat.cpp kBootReasonMap .
  • Agregar una fuente controlada y reescribible en tiempo de ejecución de system_boot_reason_prop ( sys.boot.reason ). Un conjunto limitado de aplicaciones del sistema (como bootstat e init ) pueden reescribir esta propiedad, pero a todas las aplicaciones se les pueden otorgar derechos de política para leerla.
  • Informar a los usuarios del motivo de inicio para que esperen hasta que se monten los datos del usuario antes de confiar en el contenido de la propiedad del motivo de inicio del sistema system_boot_reason_prop .

¿Por qué tan tarde? Si bien bootloader_boot_reason_prop está disponible al principio del arranque, la política de seguridad de Android lo bloquea según sea necesario porque representa información inexacta, no analizable y no canónica. En la mayoría de las situaciones, sólo los desarrolladores con un conocimiento profundo del sistema de arranque deberían necesitar acceder a esta información. Una API refinada, analizable y canónica para el motivo de arranque a través de system_boot_reason_prop se puede seleccionar de manera confiable y precisa solo después de que se hayan montado los datos del usuario. Específicamente:

  • Antes de que se hayan montado los datos del usuario, system_boot_reason_prop contendrá el valor de bootloader_boot_reason_prop .
  • Una vez que se hayan montado los datos del usuario, system_boot_reason_prop se puede actualizar para cumplir con las normas o para brindar información más precisa.

Por esta razón, Android 9 extiende el período de tiempo antes de que el motivo de arranque pueda adquirirse oficialmente, cambiando su precisión inmediata en el arranque (con bootloader_boot_reason_prop ) a estar disponible solo después de que los datos del usuario se hayan montado (con system_boot_reason_prop ).

La lógica de Bootstat depende de un bootloader_boot_reason_prop más informativo y compatible. Cuando esa propiedad utiliza un formato predecible, mejora la precisión de todos los escenarios de reinicio y apagado controlados, lo que a su vez refina y amplía la precisión y el significado de system_boot_reason_prop .

Formato de motivo de arranque canónico

El formato canónico del motivo de arranque para bootloader_boot_reason_prop en Android 9 utiliza la siguiente sintaxis:

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

Reglas de formato:

  • Minúscula
  • Sin espacios en blanco (use subrayado)
  • Todos los personajes imprimibles
  • reason , subreason y uno o más detail separados por comas.
    • Un reason obligatorio que representa el motivo de mayor prioridad por el que el dispositivo tuvo que reiniciarse o apagarse.
    • Un subreason opcional que representa un breve resumen de por qué el dispositivo tuvo que reiniciarse o apagarse (o quién reinició o apagó el dispositivo).
    • Uno o más valores detail opcionales. Un detail puede señalar un subsistema para ayudar a determinar qué sistema específico dio lugar a la subreason . Puede especificar varios valores detail , que generalmente deben seguir una jerarquía de importancia. Sin embargo, también es aceptable informar múltiples valores detail de igual importancia.

Un valor vacío para bootloader_boot_reason_prop se considera ilegal (ya que esto permite a otros agentes inyectar un motivo de arranque después del hecho).

Requisitos de motivo

El valor dado por reason (primer intervalo, antes de la terminación o coma) debe ser del siguiente conjunto dividido en motivos básicos, fuertes y contundentes:

  • conjunto de núcleos:
    • " watchdog"
    • "kernel_panic"
  • conjunto fuerte:
    • "recovery"
    • "bootloader"
  • conjunto contundente:
    • "cold" . Generalmente indica un reinicio completo de todos los dispositivos, incluida la memoria.
    • "hard" . Generalmente indica que el hardware ha reiniciado su estado y ramoops debe retener contenido persistente.
    • "warm" . Generalmente indica que la memoria y los dispositivos conservan algún estado, y que el almacén de respaldo ramoops (consulte el controlador pstore en el kernel) contiene contenido persistente.
    • "shutdown"
    • "reboot" . Generalmente significa que se desconoce el estado ramoops y el estado del hardware. Este valor es general ya que los valores cold , hard y warm proporcionan pistas sobre la profundidad del reinicio del dispositivo.

Los cargadores de arranque deben proporcionar un conjunto de núcleos o un reason de conjunto contundente y se les recomienda encarecidamente que proporcionen un subreason si se puede determinar. Por ejemplo, una pulsación prolongada de la tecla de encendido que puede tener o no una copia de seguridad ramoops tendría el motivo de inicio "reboot,longkey" .

Ningún reason de primer tramo puede formar parte de ningún subreason o detail . Sin embargo, debido a que el espacio del usuario no puede generar los motivos establecidos por el kernel, se puede reutilizar "watchdog" después de un motivo definido contundente, junto con un detalle de la fuente (por ejemplo "reboot,watchdog,service_manager_unresponsive" o "reboot,software,watchdog" ).

Los motivos de arranque no deberían requerir conocimientos internos expertos para descifrarlos y/o deberían ser legibles por humanos con un informe intuitivo. Ejemplos: "shutdown,vbxd" (malo), "shutdown,uv" (mejor), "shutdown,undervoltage" (preferido).

Combinaciones razón-subrazón

Android se reserva un conjunto de combinaciones de reason y subreason que no deben sobrecargarse en el uso normal, pero que se pueden utilizar caso por caso si la combinación refleja con precisión la condición asociada. Ejemplos de combinaciones reservadas incluyen:

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

Para obtener más detalles, consulte kBootReasonMap en system/core/bootstat/bootstat.cpp y el historial de registro de cambios de git asociado en el repositorio de origen de Android.

Informar motivos de arranque

Todos los motivos de arranque, ya sea desde el gestor de arranque o registrados en el motivo de arranque canónico, deben registrarse en la sección kBootReasonMap de system/core/bootstat/bootstat.cpp . La lista kBootReasonMap es una combinación de motivos de cumplimiento y de incumplimiento heredados. Los desarrolladores de cargadores de arranque deben registrar aquí solo nuevos motivos de cumplimiento (y no deben registrar motivos de no cumplimiento a menos que el producto ya se haya enviado y no se pueda cambiar).

Recomendamos encarecidamente utilizar entradas compatibles existentes en system/core/bootstat/bootstat.cpp y actuar con moderación antes de utilizar una cadena que no cumpla. A modo de pauta, es:

  • Está bien informar "kernel_panic" desde el gestor de arranque, ya que bootstat puede inspeccionar ramoops en busca de kernel_panic signatures para refinar las subrazones en el canónico system_boot_reason_prop .
  • No está bien informar una cadena no compatible en kBootReasonMap (como "panic") desde el gestor de arranque, ya que esto en última instancia interrumpirá la capacidad de refinar el reason .

Por ejemplo, si kBootReasonMap contiene "wdog_bark" , un desarrollador de gestor de arranque debería:

  • Cambie a "watchdog,bark" y agréguelo a la lista en kBootReasonMap .
  • Considere lo que significa "bark" para quienes no están familiarizados con la tecnología y determine si hay disponible una subreason más significativa.

Verificar el cumplimiento del motivo de arranque

En este momento, Android no proporciona una prueba CTS activa que pueda activar o inspeccionar con precisión todos los posibles motivos de arranque que podría proporcionar un gestor de arranque; Los socios aún pueden intentar ejecutar una prueba pasiva para determinar la compatibilidad.

Como resultado, el cumplimiento del gestor de arranque requiere que los desarrolladores del mismo se adhieran voluntariamente al espíritu de las reglas y pautas descritas anteriormente. Instamos a dichos desarrolladores a contribuir a AOSP (específicamente a system/core/bootstat/bootstat.cpp ) y aprovechar esta oportunidad como foro para discusiones sobre problemas de motivos de arranque.