Android 9 incluye los siguientes cambios en la especificación del motivo de inicio del bootloader.
Motivos de inicio
Un bootloader usa hardware y recursos de memoria disponibles de manera única para determinar por qué se reinició un dispositivo y, luego, comunica esa determinación agregando androidboot.bootreason=<reason>
a la línea de comandos del kernel de Android para su lanzamiento. Luego, init
traduce esta línea de comandos para propagarla a la propiedad bootloader_boot_reason_prop
(ro.boot.bootreason
) de Android. Para los dispositivos que se inician con Android 12 o versiones posteriores, que usan la versión 5.10 del kernel o una posterior, androidboot.bootreason=<reason>
se agrega a bootconfig en lugar de la línea de comandos del kernel.
Especificaciones del motivo de inicio
Las versiones anteriores de Android especificaban un formato de motivo de inicio que no usaba espacios, estaba en minúsculas, incluía pocos requisitos (como para informar kernel_panic
, watchdog
, cold
/warm
/hard
) y admitía otros motivos únicos. Esta especificación laxa provocó la proliferación de cientos de cadenas de motivos de inicio personalizadas (y, a veces, sin sentido), lo que, a su vez, generó una situación inmanejable. A partir de la versión actual de Android, el gran impulso del contenido casi sin analizar o sin sentido que presentó el bootloader creó 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 durante el tiempo de ejecución. Por lo tanto, cualquier mejora en la especificación del motivo de inicio debe provenir de interacciones con los desarrolladores del bootloader y ajustes en el sistema existente. Para ello, el equipo de Android hace lo siguiente:
- Interacción con los desarrolladores de bootloader para alentarlos a hacer lo siguiente:
- Proporciona motivos canónicos, analizables y reconocibles a
bootloader_boot_reason_prop
. - Participar en la lista
system/core/bootstat/bootstat.cpp
kBootReasonMap
- Proporciona motivos canónicos, analizables y reconocibles a
- Agregar una fuente controlada y reescribible en el tiempo de ejecución de
system_boot_reason_prop
(sys.boot.reason
). Un conjunto limitado de apps del sistema (comobootstat
yinit
) puede reescribir esta propiedad, pero se pueden otorgar derechos de sepolicy a todas las apps para que la lean. - Informar a los usuarios del motivo del inicio para que esperen hasta que se monte el userdata antes de confiar en el contenido de la propiedad
system_boot_reason_prop
del motivo del inicio del sistema
¿Por qué tan tarde? Si bien bootloader_boot_reason_prop
está disponible al principio del inicio, la política de seguridad de Android lo bloquea según sea necesario, ya que representa información imprecisa, no analizable y no canónica.
En la mayoría de los casos, solo los desarrolladores con un conocimiento profundo del sistema de inicio deberían necesitar acceder a esta información. Una API refinada, analizable y canónica para el motivo de inicio con system_boot_reason_prop
se puede detectar de forma confiable y precisa solo después de que se haya activado el archivo userdata.
Más precisamente:
- Antes de que se monte userdata,
system_boot_reason_prop
contendrá el valor debootloader_boot_reason_prop
. - Después de que se activen los datos del usuario, es posible que se actualice
system_boot_reason_prop
para que cumpla con los requisitos o informe con información más precisa.
Por este motivo, Android 9 extiende el período antes de que se pueda adquirir oficialmente el motivo del inicio, de modo que pase de ser preciso de inmediato durante el inicio (con bootloader_boot_reason_prop
) a estar disponible solo después de que se haya activado el usuario de datos (con system_boot_reason_prop
).
La lógica de Bootstat depende de un bootloader_boot_reason_prop
más informativo y conforme. Cuando esa propiedad usa un formato predecible, mejora la precisión de todas las situaciones de reinicio y apagado controladas, lo que, a su vez, define mejor y expande la precisión y el significado de system_boot_reason_prop
.
Formato del motivo de inicio canónico
El formato de motivo de inicio 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 (usa subrayado)
- Todos los caracteres imprimibles
- Instancias de
reason
,subreason
y una o másdetail
separadas por comas.- Un
reason
obligatorio que representa el motivo de prioridad más alta por el que el dispositivo tuvo que reiniciarse o apagarse. - Un objeto
subreason
opcional que representa un breve resumen de por qué se tuvo que reiniciar o apagar el dispositivo (o quién reinició o apagó el dispositivo). - Uno o más valores
detail
opcionales. Undetail
puede apuntar a un subsistema para ayudar a determinar qué sistema específico generó elsubreason
. Puedes especificar varios valores dedetail
, que, por lo general, deberían seguir una jerarquía de importancia. Sin embargo, también se acepta informar varios valores dedetail
de igual importancia.
- Un
Un valor vacío para bootloader_boot_reason_prop
se considera ilegal (ya que permite que otros agentes inserten un motivo de inicio después de que se produce).
Requisitos de los motivos
El valor proporcionado para reason
(primer intervalo, antes de la terminación o la coma) debe ser del siguiente conjunto dividido en motivos de kernel, fuertes y contundentes:
- conjunto de kernels:
- "
watchdog"
"kernel_panic"
- "
- conjunto sólido:
"recovery"
"bootloader"
- conjunto contundente:
"cold"
. Por lo general, indica un restablecimiento completo de todos los dispositivos, incluida la memoria."hard"
: Por lo general, indica que se restableció el estado del hardware y queramoops
debe retener el contenido persistente."warm"
. Por lo general, indica que la memoria y los dispositivos retienen algún estado, y el almacenamiento en caché deramoops
(consulta el controladorpstore
en el kernel) contiene contenido persistente."shutdown"
"reboot"
. Por lo general, significa que se desconoce el estado deramoops
y el estado del hardware. Este valor es un comodín, ya que los valorescold
,hard
ywarm
proporcionan pistas sobre la profundidad del restablecimiento del dispositivo.
Los bootloaders deben proporcionar un conjunto de kernel o un conjunto reason
contundente, y se recomienda que proporcionen un subreason
si se puede determinar. Por ejemplo, si mantienes presionada la tecla de encendido que puede tener una copia de seguridad de ramoops
o no, el motivo de inicio es "reboot,longkey"
.
Ningún reason
de primer intervalo puede ser parte de ningún subreason
ni detail
. Sin embargo, como el espacio de usuario no puede producir los motivos de configuración del kernel, "watchdog"
se puede volver a usar después de un motivo de configuración contundente, junto con un detalle de la fuente (por ejemplo, "reboot,watchdog,service_manager_unresponsive"
o "reboot,software,watchdog"
).
Los motivos de inicio no deben requerir conocimientos internos de expertos para descifrarlos o deben ser legibles por humanos con un informe intuitivo. Ejemplos: "shutdown,vbxd"
(malo), "shutdown,uv"
(mejor), "shutdown,undervoltage"
(preferido).
Combinaciones de motivos y submotivos
Android reserva un conjunto de combinaciones reason
-subreason
que no deben sobrecargarse durante el uso normal, pero que se pueden usar caso por caso si la combinación refleja con exactitud la condición asociada. Estos son algunos ejemplos de combinaciones reservadas:
"reboot,userrequested"
"shutdown,userrequested"
"shutdown,thermal"
(dethermald
)"shutdown,battery"
"shutdown,battery,thermal"
(desdeBatteryStatsService
)"reboot,adb"
"reboot,shell"
"reboot,bootloader"
"reboot,recovery"
Para obtener más detalles, consulta kBootReasonMap
en system/core/bootstat/bootstat.cpp
y el historial de cambios de git asociado en el repositorio de código fuente de Android.
Cómo informar los motivos de inicio
Todos los motivos de inicio, ya sea del bootloader o registrados en el motivo de inicio 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 no cumplimiento heredados. Los desarrolladores del bootloader solo deben registrar aquí nuevos motivos de cumplimiento (y no deben registrar los de incumplimiento, a menos que el producto ya se haya enviado y no se pueda cambiar).
Te recomendamos que uses entradas existentes que cumplan con los requisitos en system/core/bootstat/bootstat.cpp
y que te muestres prudente antes de usar una cadena que no cumpla con los requisitos. A modo de lineamiento, debes cumplir con los siguientes requisitos:
- OK para informar
"kernel_panic"
desde el bootloader, ya quebootstat
puede inspeccionarramoops
para quekernel_panic signatures
defina mejor los submotivos en elsystem_boot_reason_prop
canónico. - No es aceptable informar una cadena que no cumpla con los requisitos en
kBootReasonMap
(como"panic")
del bootloader, ya que, en última instancia, se perderá la capacidad de definir mejorreason
.
Por ejemplo, si kBootReasonMap
contiene "wdog_bark"
, un desarrollador del bootloader debe hacer lo siguiente:
- Cambia a
"watchdog,bark"
y agrégalo a la lista enkBootReasonMap
. - Considera lo que significa
"bark"
para quienes no están familiarizados con la tecnología y determina si hay unsubreason
más significativo disponible.
Verifica el cumplimiento del motivo de inicio
En este momento, Android no proporciona una prueba de CTS activa que pueda activar o inspeccionar con precisión todos los motivos de inicio posibles que podría proporcionar un bootloader. Los socios aún pueden intentar ejecutar una prueba pasiva para determinar la compatibilidad.
Como resultado, el cumplimiento del bootloader requiere que los desarrolladores de bootloaders se adhieran de forma voluntaria al espíritu de las reglas y los lineamientos descritos anteriormente.
Instamos a esos desarrolladores a que contribuyan al AOSP (específicamente a system/core/bootstat/bootstat.cpp
) y a que usen esta oportunidad como foro para debatir sobre problemas con el motivo de inicio.