O Android 9 inclui as seguintes mudanças na especificação do motivo de inicialização do carregador de inicialização.
Motivos de inicialização
Um carregador de inicialização usa recursos de hardware e memória disponíveis exclusivamente para
determinar por que um dispositivo foi reinicializado e comunica essa determinação
adicionando androidboot.bootreason=<reason>
à linha de comando do kernel
do Android para o lançamento. init
traduz essa linha de comando para propagar à propriedade do Android bootloader_boot_reason_prop
(ro.boot.bootreason
). Para dispositivos lançados com o Android 12 ou versões mais recentes, usando a versão 5.10 ou mais recente do kernel, androidboot.bootreason=<reason>
é adicionado ao bootconfig em vez da linha de comando do kernel.
Especificações do motivo de inicialização
As versões anteriores do Android especificavam um formato de motivo de inicialização que não usava espaços, era todo em minúsculas, incluía poucos requisitos (como para informar kernel_panic
, watchdog
, cold
/warm
/hard
) e permitia outros motivos exclusivos. Essa especificação solta resultou na
proliferação de centenas de strings de motivo de inicialização personalizadas (e às vezes sem sentido),
o que, por sua vez, levou a uma situação incontrolável. Na versão atual do Android, o grande volume de conteúdo quase impossível de analisar ou sem sentido enviado pelo carregador de inicialização criou problemas de conformidade para o bootloader_boot_reason_prop
.
Com o lançamento do Android 9, a equipe do Android reconhece que o bootloader_boot_reason_prop
legado tem um impulso substancial e não pode ser reescrito durante a execução. Portanto, as melhorias na especificação do motivo de inicialização precisam vir de interações com desenvolvedores de carregadores de inicialização e ajustes no sistema atual. Para isso, a equipe do Android:
- Interagir com desenvolvedores de carregadores de inicialização para incentivar que eles:
- Forneça motivos canônicos, analisáveis e reconhecíveis para
bootloader_boot_reason_prop
. - Participe da lista
system/core/bootstat/bootstat.cpp
kBootReasonMap
.
- Forneça motivos canônicos, analisáveis e reconhecíveis para
- Adição de uma fonte controlada e reescrevível em tempo de execução do
system_boot_reason_prop
(sys.boot.reason
). Um conjunto limitado de apps do sistema (comobootstat
einit
) pode reescrever essa propriedade, mas todos os apps podem receber direitos de sepolicy para lê-la. - Informar aos usuários o motivo da inicialização para esperar até que os dados do usuário sejam montados
antes de confiar no conteúdo da propriedade do motivo da inicialização do sistema
system_boot_reason_prop
.
Por que tão tarde? Embora o bootloader_boot_reason_prop
esteja disponível no início
da inicialização, ele é bloqueado pela política de segurança do Android conforme necessário
porque representa informações imprecisas, não analisáveis e não canônicas.
Na maioria das situações, apenas desenvolvedores com conhecimento profundo do sistema de inicialização
precisam acessar essas informações. Uma API refinada, analisável e canônica
para o motivo da inicialização com system_boot_reason_prop
pode ser capturada de forma confiável
e precisa somente depois que os dados do usuário forem montados.
Especificamente:
- Antes da montagem de userdata,
system_boot_reason_prop
vai conter o valor debootloader_boot_reason_prop
. - Depois que os dados do usuário forem montados, o
system_boot_reason_prop
poderá ser atualizado para estar em conformidade ou para informar dados mais precisos.
Por isso, o Android 9 estende o período de
tempo antes que o motivo da inicialização possa ser adquirido oficialmente, mudando de
imediatamente preciso na inicialização (com bootloader_boot_reason_prop
)
para estar disponível somente depois que os dados do usuário forem montados (com
system_boot_reason_prop
).
A lógica do Bootstat depende de um bootloader_boot_reason_prop
mais informativo e compatível. Quando essa propriedade usa um formato previsível, ela melhora a precisão de todos os cenários de reinicialização e desligamento controlados, o que, por sua vez, refina e expande a precisão e o significado de system_boot_reason_prop
.
Formato canônico do motivo de inicialização
O formato canônico do motivo de inicialização para bootloader_boot_reason_prop
no Android 9 usa a seguinte sintaxe:
<reason>,<subreason>,<detail>…
Regras de formatação:
- Letra minúscula
- Sem espaços em branco (use sublinhado)
- Todos os caracteres para impressão
reason
esubreason
separados por vírgulas e uma ou mais instâncias dedetail
.- Um
reason
obrigatório que representa o motivo de maior prioridade pelo qual o dispositivo precisou ser reiniciado ou desligado. - Um
subreason
opcional que representa um breve resumo de por que o dispositivo precisou ser reiniciado ou desligado (ou quem reiniciou ou desligou o dispositivo). - Um ou mais valores
detail
opcionais. Umdetail
pode apontar para um subsistema e ajudar a determinar qual sistema específico resultou nosubreason
. É possível especificar vários valores dedetail
, que geralmente seguem uma hierarquia de importância. No entanto, também é aceitável informar vários valores dedetail
de igual importância.
- Um
Um valor vazio para bootloader_boot_reason_prop
é considerado ilegal, já que permite que outros agentes injetem um motivo de inicialização depois do fato.
Requisitos de motivo
O valor fornecido para reason
(primeiro intervalo, antes do encerramento ou da vírgula) precisa ser do seguinte conjunto dividido em motivos principais, fortes e diretos:
- kernel set:
- "
watchdog"
"kernel_panic"
- "
- strong set:
"recovery"
"bootloader"
- blunt set:
"cold"
. Geralmente indica uma redefinição completa de todos os dispositivos, incluindo a memória."hard"
. Geralmente indica que o hardware teve o estado redefinido e queramoops
deve reter o conteúdo persistente."warm"
. Geralmente indica que a memória e os dispositivos mantêm algum estado, e o armazenamento de apoioramoops
(consulte o driverpstore
no kernel) contém conteúdo persistente."shutdown"
"reboot"
. Geralmente significa que o estadoramoops
é desconhecido, assim como o estado do hardware. Esse valor é um coringa, já que os valorescold
,hard
ewarm
fornecem pistas sobre a profundidade da redefinição do dispositivo.
Os carregadores de inicialização precisam fornecer um conjunto de kernel ou um conjunto de reason
, e é altamente recomendável que forneçam um subreason
se for possível determinar. Por exemplo, um toque longo na tecla liga/desliga que pode ou não ter
um backup ramoops
teria o motivo da inicialização
"reboot,longkey"
.
Nenhum reason
do primeiro intervalo pode fazer parte de um subreason
ou
detail
. No entanto, como os motivos de definição do kernel não podem ser produzidos pelo espaço do usuário, "watchdog"
pode ser reutilizado após um motivo de definição simples, junto com um detalhe da origem (por exemplo, "reboot,watchdog,service_manager_unresponsive"
ou "reboot,software,watchdog"
).
Os motivos de inicialização não devem exigir conhecimento interno especializado para serem decifrados e/ou precisam ser legíveis para humanos com um relatório intuitivo. Exemplos:
"shutdown,vbxd"
(ruim), "shutdown,uv"
(melhor),
"shutdown,undervoltage"
(preferido).
Combinações de motivo e submotivo
O Android reserva um conjunto de combinações de reason
-subreason
que não devem ser sobrecarregadas no uso normal, mas podem ser usadas caso a caso se a combinação refletir com precisão a condição
associada. Exemplos de combinações reservadas:
"reboot,userrequested"
"shutdown,userrequested"
"shutdown,thermal"
(dethermald
)"shutdown,battery"
"shutdown,battery,thermal"
(deBatteryStatsService
)"reboot,adb"
"reboot,shell"
"reboot,bootloader"
"reboot,recovery"
Para mais detalhes, consulte kBootReasonMap
em
system/core/bootstat/bootstat.cpp
e o histórico de
changelog do Git associado no repositório de origem do Android.
Informar motivos de inicialização
Todos os motivos de inicialização, do carregador de inicialização ou registrados no motivo de inicialização canônico, precisam ser registrados na seção kBootReasonMap
de system/core/bootstat/bootstat.cpp
. A lista kBootReasonMap
é uma mistura de motivos de compliance e de não compliance legados. Os desenvolvedores de bootloader só devem registrar motivos novos e
em conformidade aqui. Não registre motivos em não conformidade, a menos que
o produto já tenha sido enviado e não possa ser alterado.
Recomendamos usar entradas compatíveis em system/core/bootstat/bootstat.cpp
e ter moderação antes de usar uma string incompatível. Como diretriz, ele é:
- OK para informar
"kernel_panic"
do bootloader, já quebootstat
pode inspecionarramoops
parakernel_panic signatures
e refinar os submotivos nosystem_boot_reason_prop
canônico. - Não OK para informar uma string não compatível em
kBootReasonMap
(como"panic")
do bootloader, já que isso vai prejudicar a capacidade de refinar oreason
.
Por exemplo, se kBootReasonMap
contiver "wdog_bark"
,
um desenvolvedor de carregador de inicialização precisa:
- Mude para
"watchdog,bark"
e adicione à lista emkBootReasonMap
. - Considere o que
"bark"
significa para quem não conhece a tecnologia e determine se umsubreason
mais significativo está disponível.
Verificar a conformidade do motivo de inicialização
No momento, o Android não oferece um teste do CTS ativo que possa acionar ou inspecionar com precisão todos os possíveis motivos de inicialização que um carregador de inicialização pode fornecer. Os parceiros ainda podem tentar executar um teste passivo para determinar a compatibilidade.
Como resultado, a conformidade do carregador de inicialização exige que os desenvolvedores
aderiram voluntariamente ao espírito das regras e diretrizes descritas acima.
Incentivamos esses desenvolvedores a contribuir com o AOSP (especificamente com
system/core/bootstat/bootstat.cpp
) e usar essa oportunidade como um
fórum para discussões sobre problemas de motivo de inicialização.