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, em seguida, comunica essa determinação
adicionando androidboot.bootreason=<reason> à linha de comando do kernel
do Android para o lançamento. O init traduz essa
linha de comando para propagá-la à propriedade
bootloader_boot_reason_prop (ro.boot.bootreason) do Android.
Para dispositivos iniciados com o Android 12 ou versões mais recentes,
usando a versão 5.10 ou mais recente do kernel, o androidboot.bootreason=<reason>
é adicionado ao bootconfig em vez da linha de comando do kernel.
Especificações do motivo de inicialização
Versões anteriores do Android especificavam um formato de motivo de inicialização que não usava
espaços, era todo em letras 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 personalizadas (e às vezes sem sentido) de motivos de inicialização,
o que, por sua vez, levou a uma situação incontrolável. A partir da versão
atual do Android, o grande volume de conteúdo quase não analisável ou sem sentido
registrado pelo carregador de inicialização criou problemas de conformidade para
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 grande impulso e não pode ser reescrito no momento da execução. Portanto, qualquer melhoria na
especificação do motivo de inicialização precisa vir de interações com
desenvolvedores de carregador de inicialização e ajustes no sistema atual. Para isso, a
equipe do Android está:
- Envolver os desenvolvedores de carregador de inicialização para incentivar:
- Forneça motivos canônicos, analisáveis e reconhecíveis para
bootloader_boot_reason_prop. - Participe da lista
system/core/bootstat/bootstat.cppkBootReasonMap.
- Forneça motivos canônicos, analisáveis e reconhecíveis para
- Adição de uma fonte controlada e reescrita no momento de execução do
system_boot_reason_prop(sys.boot.reason). Um conjunto limitado de apps do sistema (comobootstateinit) 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 a userdata seja montada
antes de confiar no conteúdo na propriedade do motivo da inicialização do sistema
system_boot_reason_prop.
Por que tão tarde? Embora 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 pará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, que pode ser analisada e canônica
para o motivo de inicialização com system_boot_reason_prop só pode ser detectada
de forma confiável e precisa depois da montagem de userdata.
Especificamente:
- Antes de a userdata ser montada,
system_boot_reason_propvai conter o valor debootloader_boot_reason_prop. - Depois que o userdata for montado,
system_boot_reason_proppoderá ser atualizado para estar em conformidade ou informar informações mais precisas.
Por esse motivo, o Android 9 estende o período
de tempo antes que o motivo de inicialização possa ser oficialmente adquirido, mudando de
preciso imediatamente na inicialização (com bootloader_boot_reason_prop)
para disponível somente depois que o userdata for montado (com
system_boot_reason_prop).
A lógica de 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 refina e amplia a precisão e o significado
de system_boot_reason_prop.
Formato do motivo de inicialização canônico
O formato do motivo de inicialização canônico 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 imprimíveis
reason,subreasone uma ou mais instâncias dedetailseparadas por vírgulas.- Um
reasonobrigatório que representa o motivo de maior prioridade para a reinicialização ou desligamento do dispositivo. - Um
subreasonopcional que representa um breve resumo de por que o dispositivo teve que reiniciar ou desligar (ou quem reiniciou ou desligou o dispositivo). - Um ou mais valores
detailopcionais. Umdetailpode apontar para um subsistema para ajudar a determinar qual sistema específico resultou nasubreason. É 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 dedetailde 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 após o fato.
Requisitos do motivo
O valor fornecido para reason (primeiro período, antes do encerramento ou
vírgula) precisa ser do conjunto a seguir, dividido em motivos principais, fortes e contundentes:
- kernel set:
- "
watchdog" "kernel_panic"
- "
- Conjunto forte:
"recovery""bootloader"
- Conjunto de pontas embotadas:
"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 eramoopsprecisa manter o conteúdo persistente."warm": geralmente indica que a memória e os dispositivos retêm algum estado, e o armazenamento de suporteramoops(consulte o driverpstoreno kernel) contém conteúdo persistente."shutdown""reboot". Geralmente significa que o estado deramoopsé desconhecido e o estado do hardware é desconhecido. Esse valor é um coletor, já que os valorescold,hardewarmfornecem dicas sobre a profundidade da redefinição do dispositivo.
Os boot loaders precisam fornecer um conjunto de kernel ou um conjunto reason, e
é altamente recomendável fornecer um subreason se ele puder ser
determinado. Por exemplo, um toque longo no botão liga/desliga que pode ou não ter
backup de ramoops teria o motivo de inicialização
"reboot,longkey".
Nenhum reason de primeira extensão pode fazer parte de nenhum subreason ou
detail. No entanto, como os motivos de conjunto do kernel não podem ser produzidos pelo
espaço do usuário, o "watchdog" pode ser reutilizado após um motivo de conjunto brusco,
junto com um detalhe da fonte (por exemplo,
"reboot,watchdog,service_manager_unresponsive" ou
"reboot,software,watchdog").
Os motivos de inicialização não devem exigir conhecimento interno de especialistas para decifrar e/ou
devem ser legíveis por 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 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. Confira alguns 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 mudanças
do git associado no repositório de origem do Android.
Relatar 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 legados. Os desenvolvedores de gerenciadores de inicialização precisam registrar apenas novos
motivos compatíveis aqui (e não podem registrar motivos incompatíveis, a menos que
o produto já tenha sido enviado e não possa ser alterado).
Recomendamos o uso de entradas existentes e compatíveis em
system/core/bootstat/bootstat.cpp e a restrição de uso de uma string que não esteja em conformidade. Como diretriz, ele é:
- OK para informar
"kernel_panic"do carregador de inicialização, já quebootstatpode inspecionarramoopsparakernel_panic signaturesrefinar as subrazões nasystem_boot_reason_propcanônica. - Não é aceitável informar uma string que não está em conformidade no
kBootReasonMap(como"panic")do carregador de inicialização), porque isso acaba com a capacidade de refinar oreason.
Por exemplo, se kBootReasonMap contiver "wdog_bark",
o desenvolvedor do carregador de inicialização precisará:
- Mude para
"watchdog,bark"e adicione à lista emkBootReasonMap. - Considere o que
"bark"significa para quem não conhece a tecnologia e determine se umsubreasonmais significativo está disponível.
Verificar a conformidade do motivo de inicialização
No momento, o Android não oferece um teste CTS ativo que possa acionar ou inspecionar com precisão todos os possíveis motivos de inicialização que um carregador de inicialização possa 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
adiram voluntariamente ao espírito das regras e diretrizes descritas acima.
Pedimos que esses desenvolvedores contribuam com o AOSP (especificamente com
system/core/bootstat/bootstat.cpp) e usem essa oportunidade como um
fórum para discussões sobre problemas de motivo de inicialização.