O Android 9 inclui as seguintes alterações 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 exclusivamente disponíveis 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 sua inicialização. init
então traduz esta linha de comando para propagar para a propriedade do Android bootloader_boot_reason_prop
( ro.boot.bootreason
). Para dispositivos iniciados com Android 12 ou posterior, usando kernel versão 5.10 ou superior, androidboot.bootreason=<reason>
é adicionado ao bootconfig em vez da linha de comando do kernel.
Especificações do motivo da 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 letras minúsculas, incluía poucos requisitos (como para relatar kernel_panic
, watchdog
, cold
/ warm
/ hard
) e que 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. A partir da versão atual do Android, o grande impulso de conteúdo quase não analisável ou sem sentido arquivado pelo bootloader 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 impulso substancial e não pode ser reescrito em tempo de execução. Quaisquer melhorias na especificação do motivo da inicialização devem, portanto, vir de interações com os desenvolvedores do carregador de inicialização e ajustes no sistema existente. Para isso, a equipe do Android é:
- Envolver-se com desenvolvedores de bootloader 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
- Adicionando uma fonte controlada e regravável em tempo de execução do
system_boot_reason_prop
(sys.boot.reason
). Um conjunto limitado de aplicativos do sistema (comobootstat
einit
) pode reescrever essa propriedade, mas todos os aplicativos podem receber direitos de sepolicy para lê-la. - Informando os usuários sobre o motivo da inicialização para esperar até que userdata seja montado antes de confiar no conteúdo na propriedade de 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 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 devem precisar acessar essas informações. Uma API refinada, analisável e canônica para motivo de inicialização via system_boot_reason_prop
pode ser selecionada de maneira confiável e precisa somente após a montagem de userdata. Especificamente:
- Antes que userdata seja montado,
system_boot_reason_prop
conterá o valor debootloader_boot_reason_prop
. - Após a montagem de userdata,
system_boot_reason_prop
pode ser atualizado para ser compatível ou para relatar informações mais precisas.
Por esse motivo, o Android 9 estende o período de tempo antes que o motivo da inicialização possa ser adquirido oficialmente, alterando-o de ser imediatamente preciso na inicialização (com bootloader_boot_reason_prop
) para estar disponível somente após a montagem de userdata (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 do motivo da inicialização canônica
O formato de 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:
- Minúsculas
- Sem espaços em branco (use sublinhado)
- Todos os caracteres imprimíveis
-
reason
separada por vírgula ,subreason
e um ou maisdetail
.- Um
reason
obrigatório que representa o motivo de maior prioridade pelo qual o dispositivo teve que ser reinicializado ou desligado. - Um
subreason
opcional que representa um breve resumo do motivo pelo qual o dispositivo teve que reinicializar ou desligar (ou quem reinicializou ou desligou o dispositivo). - Um ou mais valores de
detail
opcionais. Umdetail
pode apontar para um subsistema para ajudar a determinar qual sistema específico resultou nasubreason
. Você pode especificar vários valores dedetail
, que geralmente devem seguir uma hierarquia de importância. No entanto, também é aceitável relatar vários valores dedetail
de igual importância.
- Um
Um valor vazio para bootloader_boot_reason_prop
é considerado ilegal (já que isso permite que outros agentes injetem um motivo de inicialização após o fato).
Requisitos de motivo
O valor dado para reason
(primeiro intervalo, antes da terminação ou vírgula) deve ser do seguinte conjunto dividido em motivos kernel, fortes e contundentes:
- conjunto de núcleos:
- "
watchdog"
-
"kernel_panic"
- "
- conjunto forte:
-
"recovery"
-
"bootloader"
-
- conjunto sem corte:
-
"cold"
. Geralmente indica uma reinicialização completa de todos os dispositivos, incluindo a memória. -
"hard"
. Geralmente indica que o hardware tem seu estado redefinido eramoops
deve reter conteúdo persistente. -
"warm"
. Geralmente indica que a memória e os dispositivos retêm algum estado, e o armazenamento de suporteramoops
(consulte o driverpstore
no kernel) contém conteúdo persistente. -
"shutdown"
-
"reboot"
. Geralmente significa que o estadoramoops
é desconhecido e o estado do hardware é desconhecido. Esse valor é abrangente, pois os valorescold
,hard
ewarm
fornecem pistas sobre a profundidade da redefinição do dispositivo.
-
Os carregadores de inicialização devem fornecer um conjunto de kernel ou um reason
de conjunto sem corte e são fortemente encorajados a fornecer um subreason
se puder ser determinado. Por exemplo, um pressionamento longo da tecla liga / desliga que pode ou não ter o backup do ramoops
teria o motivo da inicialização "reboot,longkey"
.
Nenhum reason
do primeiro período pode fazer parte de qualquer subreason
ou detail
. No entanto, como os motivos do conjunto do kernel não podem ser produzidos pelo espaço do usuário, "watchdog"
pode ser reutilizado após um motivo definido, juntamente 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 especializado para decifrar e/ou devem ser legíveis por humanos com um relatório intuitivo. Exemplos: "shutdown,vbxd"
(ruim), "shutdown,uv"
(melhor), "shutdown,undervoltage"
(preferencial).
Combinações Razão-Sub-razão
O Android reserva um conjunto de combinações de reason
e subreason
que não devem ser sobrecarregados em uso normal, mas podem ser usados caso a caso se a combinação refletir com precisão a condição associada. Exemplos de combinações reservadas incluem:
-
"reboot,userrequested"
-
"shutdown,userrequested"
-
"shutdown,thermal"
(dethermald
) -
"shutdown,battery"
-
"shutdown,battery,thermal"
(deBatteryStatsService
) -
"reboot,adb"
-
"reboot,shell"
-
"reboot,bootloader"
-
"reboot,recovery"
Para obter mais detalhes, consulte kBootReasonMap
em system/core/bootstat/bootstat.cpp
e o histórico associado do git changelog no repositório de origem do Android.
Relatando motivos de inicialização
Todos os motivos de inicialização, sejam do carregador de inicialização ou registrados no motivo de inicialização canônico, devem ser registrados na seção kBootReasonMap
de system/core/bootstat/bootstat.cpp
. A lista kBootReasonMap
é uma mistura de motivos de conformidade e não conformidade herdados. Os desenvolvedores de bootloader devem registrar apenas novos motivos de conformidade aqui (e não devem 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 entradas existentes e compatíveis em system/core/bootstat/bootstat.cpp
e exercer restrição antes de usar uma string não compatível. Como orientação, é:
- OK para relatar
"kernel_panic"
do bootloader, pois obootstat
pode inspecionarramoops
parakernel_panic signatures
para refinar as sub-razões no sistema canônicosystem_boot_reason_prop
. - Não há problema em relatar uma string não compatível no
kBootReasonMap
(como"panic")
do carregador de inicialização, pois isso acabará interrompendo a capacidade de refinar oreason
.
Por exemplo, se kBootReasonMap
contém "wdog_bark"
, um desenvolvedor de bootloader deve:
- Mude para
"watchdog,bark"
e adicione à lista emkBootReasonMap
. - Considere o que
"bark"
significa para aqueles que não estão familiarizados com a tecnologia e determine se umasubreason
mais significativa está disponível.
Verificando a conformidade do motivo da inicialização
No momento, o Android não fornece 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 pode fornecer; os parceiros ainda podem tentar executar um teste passivo para determinar a compatibilidade.
Como resultado, a conformidade com o bootloader exige que os desenvolvedores do bootloader adiram voluntariamente ao espírito das regras e diretrizes descritas acima. Pedimos que esses desenvolvedores contribuam para o AOSP (especificamente para system/core/bootstat/bootstat.cpp
) e usem esta oportunidade como um fórum para discussões sobre problemas de motivo de inicialização.