O Android 9 inclui as seguintes mudanças na especificação do motivo de inicialização do carregador de inicialização:
Motivos da inicialização
Um carregador de inicialização usa recursos de hardware e memória disponíveis exclusivamente para determinar por que um dispositivo foi reiniciado e comunica essa determinação adicionando androidboot.bootreason=<reason>
à linha de comando do kernel do Android para a inicialização. Em seguida, o init
converte essa
linha de comando para se propagar para a propriedade do Android
bootloader_boot_reason_prop
(ro.boot.bootreason
).
Para dispositivos lançados com o Android 12 ou mais recente,
com o kernel versão 5.10 ou mais recente, 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 todas em letras minúsculas, incluíam alguns requisitos (como para relatar
kernel_panic
, watchdog
,
cold
/warm
/hard
) e que permitiam
permissões por outros motivos exclusivos. Essa especificação flexível resultou na proliferação de centenas de strings de motivos de inicialização personalizadas (e às vezes sem sentido), o que, por sua vez, levou a uma situação incontrolável. A partir da versão atual
do Android, o grande movimento 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 grande importância e não pode ser reescrito durante a execução. Portanto, todas as melhorias na especificação do motivo de inicialização precisam vir de interações com os desenvolvedores do carregador de inicialização e ajustes no sistema existente. Para isso, a equipe do Android está:
- Interagir com desenvolvedores de carregadores de inicialização para incentivá-los a:
- 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
- Adicionar uma fonte do
system_boot_reason_prop
(sys.boot.reason
) controlada e regravável durante a execução. 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 aguardar até que os dados do usuário sejam montados
antes de confiar no conteúdo na propriedade
system_boot_reason_prop
do motivo de inicialização do sistema.
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 a necessidade
porque representa informações imprecisas, não analisáveis e não canônicas.
Na maioria das situações, apenas desenvolvedores com profundo conhecimento do sistema de inicialização precisam acessar essas informações. Uma API refinada, analisável e canônica por motivo de inicialização com system_boot_reason_prop
pode ser selecionada de maneira confiável e precisa somente após a ativação dos dados do usuário.
Especificamente:
- Antes dos dados do usuário serem montados,
system_boot_reason_prop
conterá o valor debootloader_boot_reason_prop
. - Depois que os dados do usuário forem ativados,
system_boot_reason_prop
poderá ser atualizado para ficar em conformidade ou relatar informações mais precisas.
Por esse motivo, o Android 9 estende o período antes que o motivo de inicialização possa ser adquirido oficialmente, mudando de ser imediatamente preciso na inicialização (com bootloader_boot_reason_prop
) para disponível somente depois que os dados do usuário forem montados (com system_boot_reason_prop
).
A lógica de inicialização depende de um bootloader_boot_reason_prop
mais informativo e em conformidade. Quando essa propriedade usa um formato previsível, ela melhora a precisão de todos os cenários de reinicialização e encerramento controlados, o que, por sua vez, refina e expande a precisão e o significado de system_boot_reason_prop
.
Formato do motivo de inicialização canônico
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 (usar sublinhado)
- Todos os caracteres para impressão
reason
,subreason
e uma ou mais instâncias dedetail
separadas por vírgulas.- Um
reason
obrigatório que representa o motivo de maior prioridade que levou o dispositivo a ser reinicializado ou encerrado. - Um
subreason
opcional que representa um breve resumo do motivo pelo qual o dispositivo teve que ser reinicializado ou desligado (ou quem o reinicializou ou desligou). - Um ou mais valores
detail
opcionais. Umdetail
pode apontar para um subsistema para ajudar a determinar qual sistema específico resultou nasubreason
. É possível especificar vários valores dedetail
, que geralmente precisam seguir uma hierarquia de importância. No entanto, também é aceitável informar vários valores dedetail
de mesma importância.
- Um
Um valor vazio para bootloader_boot_reason_prop
é considerado ilegal, porque isso permite que outros agentes injetem um motivo de inicialização após o fato.
Requisitos de motivo
O valor fornecido para reason
(primeiro período, antes do encerramento ou
da vírgula) precisa ser do seguinte conjunto dividido por motivos de kernel, forte e
contundente:
- conjunto de kernels:
- "
watchdog"
"kernel_panic"
- "
- conjunto forte:
"recovery"
"bootloader"
- sem corte:
"cold"
. Geralmente, indica uma redefinição completa de todos os dispositivos, incluindo a memória."hard"
: geralmente indica que o hardware foi redefinido e oramoops
precisa reter conteúdo persistente."warm"
: geralmente indica que a memória e os dispositivos retêm algum estado, e o armazenamento de apoioramoops
(consulte o driverpstore
no kernel) contém conteúdo persistente."shutdown"
"reboot"
: geralmente significa que o estado doramoops
é desconhecido e o do hardware é desconhecido. Esse valor é abrangente, porque 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 reason
de conjunto contundente.
É altamente recomendável fornecer um subreason
se isso puder ser
determinado. Por exemplo, uma tecla liga/desliga pressionada, que pode ou não ter o backup ramoops
, teria o motivo de inicialização "reboot,longkey"
.
Nenhum reason
do primeiro período pode fazer parte de subreason
ou
detail
. No entanto, como os motivos do conjunto de kernel não podem ser produzidos pelo
espaço do usuário, "watchdog"
pode ser reutilizado após um motivo de definição contundente,
com um detalhe da origem (por exemplo,
"reboot,watchdog,service_manager_unresponsive"
ou
"reboot,software,watchdog"
).
Os motivos da inicialização não podem exigir conhecimento interno especializado para decifrar e/ou
precisam ser legíveis por humanos com um relatório intuitivo. Exemplos:
"shutdown,vbxd"
(ruim), "shutdown,uv"
(melhor),
"shutdown,undervoltage"
(preferencial).
Combinações de motivo/submotivo
O Android reserva um conjunto de combinações reason
-subreason
que não pode ser sobrecarregada no uso normal, mas que pode ser usada
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 saber mais, consulte kBootReasonMap
em system/core/bootstat/bootstat.cpp
e o histórico do registro de alterações do git associado no repositório de origem do Android.
Relatar motivos de inicialização
Todos os motivos de inicialização, sejam do carregador de inicialização ou gravados no motivo canônico, precisam ser registrados na seção kBootReasonMap
de
system/core/bootstat/bootstat.cpp
. A lista
kBootReasonMap
é uma combinação de motivos em conformidade e
incompatíveis legados. Os desenvolvedores de carregadores de inicialização precisam registrar apenas novos
motivos de conformidade aqui (e não podem registrar motivos de não conformidade, a menos que
o produto já tenha sido enviado e não possa ser alterado).
É altamente recomendável usar as entradas atuais e compatíveis em
system/core/bootstat/bootstat.cpp
e praticar a restrição antes
de usar uma string não compatível. A diretriz é:
- OK para informar
"kernel_panic"
do carregador de inicialização, já quebootstat
pode inspecionarramoops
parakernel_panic signatures
a fim de refinar os submotivos nosystem_boot_reason_prop
canônico. - Não OK para informar uma string que não está em conformidade em
kBootReasonMap
(como"panic")
do carregador de inicialização, porque isso vai interromper a capacidade de refinar oreason
).
Por exemplo, se kBootReasonMap
contiver "wdog_bark"
,
um 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 umsubreason
mais significativo está disponível.
Verificar a conformidade do motivo de inicialização
No momento, o Android não oferece um teste de CTS ativo que possa acionar ou inspecionar com precisão todos os motivos de inicialização possíveis que um carregador de inicialização poderia fornecer. Os parceiros ainda podem tentar executar um teste passivo para determinar a compatibilidade.
Como resultado, a conformidade com o carregador de inicialização exige que os desenvolvedores sigam voluntariamente as regras e diretrizes descritas acima.
Incentivamos esses desenvolvedores a contribuir com o AOSP (especificamente para o
system/core/bootstat/bootstat.cpp
) e usar essa oportunidade como um
fórum para discussões sobre problemas na inicialização.