Motivo de arranque canónico

Android 9 incluye los siguientes cambios en la especificación del motivo de arranque del cargador 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, luego comunica esa determinación agregando androidboot.bootreason=<reason> a la línea de comandos del kernel de Android para su lanzamiento. init luego traduce esta línea de comando para propagarla a la propiedad de Android bootloader_boot_reason_prop ( ro.boot.bootreason ). Para los dispositivos que se inician con Android 12 o posterior, que utilizan la versión 5.10 o posterior del kernel, se androidboot.bootreason=<reason> a bootconfig en lugar de la línea de comandos del kernel.

Especificaciones del motivo de arranque

Las versiones anteriores de Android especificaban un formato de motivo de arranque que no usaba espacios, estaba todo en minúsculas, incluía pocos requisitos (como informar sobre kernel_panic , watchdog , cold / warm / hard ) y que tenía en cuenta otras razones únicas. Esta especificación laxa resultó en la proliferación de cientos de cadenas de razones de arranque personalizadas (ya 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 archivado por el cargador 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 volver a escribir 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 cargador de arranque y ajustes en el sistema existente. Con ese fin, el equipo de Android es:

  • Interactuar con los desarrolladores de cargadores de arranque para alentarlos a:
    • Proporcione motivos canónicos, 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 ) puede reescribir esta propiedad, pero todas las aplicaciones pueden recibir derechos de política para leerla.
  • Informar a los usuarios del motivo de arranque para esperar hasta que se monten los datos de usuario antes de confiar en el contenido de la propiedad system_boot_reason_prop del motivo de arranque del sistema.

¿Por qué tan tarde? Si bien bootloader_boot_reason_prop está disponible desde el principio, 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, solo 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 por razones de arranque a través 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 de usuario, system_boot_reason_prop contendrá el valor de bootloader_boot_reason_prop .
  • Después de que se hayan montado los datos de usuario, system_boot_reason_prop se puede actualizar para que cumpla con los requisitos o para brindar información más precisa.

Por esta razón, Android 9 amplía el período de tiempo antes de que se pueda adquirir oficialmente el motivo de arranque, cambiándolo de ser inmediatamente preciso en el arranque (con bootloader_boot_reason_prop ) a estar disponible solo después de que se hayan montado los datos de usuario (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 usa 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 de motivo de arranque canónico para bootloader_boot_reason_prop en Android 9 usa la siguiente sintaxis:

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

Reglas de formato:

  • Minúscula
  • Sin espacios en blanco (usar 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 de detail opcionales. Un detail puede apuntar a un subsistema para ayudar a determinar qué sistema específico resultó en la subreason . Puede especificar varios valores de detail , que generalmente deben seguir una jerarquía de importancia. Sin embargo, también es aceptable informar múltiples valores de detail de igual importancia.

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

Requisitos de la razón

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

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

Los cargadores de arranque deben proporcionar un conjunto de kernel o un reason de conjunto contundente, y se recomienda enfáticamente 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 de ramoops tendría el motivo de arranque "reboot,longkey" .

Ninguna reason de primer tramo puede ser parte de ninguna subreason o detail . Sin embargo, debido a que el espacio del usuario no puede generar motivos de configuración del kernel "reboot,software,watchdog" "reboot,watchdog,service_manager_unresponsive" "watchdog" se puede reutilizar después de un motivo de conjunto contundente, junto con un detalle de la fuente (p. ).

Las razones de arranque no deben requerir conocimientos internos expertos para descifrar y/o deben ser legibles por humanos con un informe intuitivo. Ejemplos: "shutdown,vbxd" (malo), "shutdown,uv" (mejor), "shutdown,undervoltage" (preferido).

Combinaciones de Razón-Subrazón

Android se reserva un conjunto de combinaciones de reason y subreason que no se deben sobrecargar en el uso normal, pero que se pueden usar 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 cambios de git asociado en el repositorio fuente de Android.

Informar motivos de arranque

Todos los motivos de arranque, ya sea desde el cargador 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 de kBootReasonMap es una combinación de motivos de cumplimiento y de incumplimiento heredado. Los desarrolladores de cargadores de arranque deben registrar aquí solo nuevos motivos de cumplimiento (y no deben registrar motivos de incumplimiento a menos que el producto ya se haya enviado y no se pueda cambiar).

Recomendamos enfáticamente usar entradas compatibles existentes en system/core/bootstat/bootstat.cpp y actuar con moderación antes de usar una cadena no compatible. A modo orientativo, 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 system_boot_reason_prop canónico.
  • No está bien informar una cadena no compatible en kBootReasonMap (como "panic") desde el cargador de arranque, ya que esto finalmente 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 qué significa "bark" para aquellos que no están familiarizados con la tecnología y determine si hay una subreason más significativa disponible.

Verificación del cumplimiento del motivo de arranque

En este momento, Android no proporciona una prueba CTS activa que pueda activar o inspeccionar con precisión todas las posibles razones 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 cargador de arranque requiere que los desarrolladores del cargador de arranque se adhieran voluntariamente al espíritu de las reglas y pautas descritas anteriormente. Instamos a dichos desarrolladores a que contribuyan a AOSP (específicamente a system/core/bootstat/bootstat.cpp ) y utilicen esta oportunidad como un foro para discusiones sobre problemas de motivos de arranque.