Esquema de controle de versões do GKI

Nesta página, descrevemos o esquema de controle de versão para imagens genéricas do kernel (GKIs, na sigla em inglês). Uma imagem genérica do kernel (GKI) tem um identificador exclusivo chamado de lançamento do kernel. A versão do kernel consiste na versão da interface do módulo do kernel (KMI) e no subnível. A versão do kernel é específica para a imagem que está sendo lançada, enquanto a versão do KMI representa a interface em que um lançamento é criado. Uma versão da KMI pode ser compatível com várias versões do kernel. Um lançamento do kernel está vinculado a apenas uma versão da KMI. No caso improvável de que a interface do módulo do kernel precise ser alterada, a geração do KMI será repetida para refletir a mudança na versão do KMI.

Resumo dos termos

A tabela a seguir resume termos importantes usados nesta página e para atualizações do GKI.

Nome Símbolo Exemplo Descrição
Versão do kernel w.x.y-zzz-k-suffix 5.4.42-android12-0-foo Identificador exclusivo de uma versão do GKI. Esse é o valor retornado por uname.
Versão do KMI w.x-zzz-k 5.4-android12-0 Descreve a interface do módulo do kernel (KMI) entre a GKI e os módulos do kernel carregáveis dinamicamente (DLKM).
Subnível y 42 Descreve a ordem de lançamento das versões do kernel na mesma versão da KMI.

A tabela a seguir lista outros termos relacionados como referência.

Nome Símbolo Exemplo Descrição
w.x.y w.x.y 5.4.42

Para mais detalhes, consulte Makefiles do kernel do Linux (pesquise "KERNELRELEASE").

w.x.y é usado diretamente em todo este documento. Isso também é conhecido como número de versão de três partes. O termo usado no VINTF, versão do kernel, pode causar confusão com outros termos, especialmente w.

Essa variável é chamada de kernel_version_tuple em libkver.

Essa tupla não pode ser reduzida por nenhuma atualização, incluindo OTA ou principal.

Ramificação do kernel zzz-w.x android12-5.4 Esse termo é usado em Tipos comuns de ramificação do kernel.
Versão w 5 Esse termo não é usado neste documento. Essa variável é chamada de version em libkver.
Nível do patch x 4 Esse termo não é usado neste documento. Essa variável é chamada de patch_level em libkver.
Versão do Android zzz android12

Esse é o número da versão do Android (sobremesa) associada ao kernel.

Ao comparar o campo AndroidRelease, a parte numérica é extraída da string para comparação.

O número da versão do Android não pode ser reduzido por nenhuma atualização, incluindo OTA ou mainline.

Geração de KMI k 0

Esse é um número adicional adicionado para lidar com eventos improváveis. Se uma correção de bug de segurança exigir mudanças na KMI na mesma versão do Android, uma geração de KMI será aumentada.

O número de geração do KMI começa com 0.

Design de controle de versões

Versão do kernel

Definição

Para dispositivos enviados com GKI, a versão do kernel é definida da seguinte maneira:

KernelRelease :=
Version.PatchLevel.SubLevel-AndroidRelease-KmiGeneration-suffix
w      .x         .y       -zzz           -k            -something

Para mais informações, consulte Determinar a versão do kernel de um dispositivo.

Confira a seguir um exemplo de lançamento do kernel.

5.4.42-android12-0-00544-ged21d463f856

Descrição

A versão do kernel é o ID exclusivo de uma versão da GKI. Se dois binários GKI tiverem a mesma versão do kernel, eles precisarão ser idênticos byte a byte.

Uma versão do kernel consiste em uma versão da KMI, um subnível e um sufixo. Para os fins deste documento, o sufixo após a geração do KMI é ignorado.

Versão do KMI

Definição

A versão do KMI é definida da seguinte maneira:

KmiVersion :=
Version.PatchLevel-AndroidRelease-KmiGeneration
w      .x         -zzz           -k

O subnível, y, não faz parte da versão da KMI. No exemplo em Tipo do kernel, a versão da KMI é:

5.4-android12-0

Descrição

A versão da KMI descreve a interface do módulo do kernel (KMI) entre a GKI e os módulos do kernel carregáveis dinamicamente (DLKM, na sigla em inglês).

Se duas versões do kernel tiverem a mesma versão de KMI, elas vão implementar a mesma interface de módulo do kernel. As DLKMs compatíveis com uma também são compatíveis com a outra.

A versão do KMI não pode ser reduzida por nenhuma atualização OTA.

Subnível

O subnível, y, descreve a ordem de lançamento das versões do kernel na mesma versão da KMI.

Para duas versões do kernel com a mesma versão da KMI, mas com sublevels Y1 e Y2, respectivamente:

  • Se Y1 for menor ou igual a Y2, um dispositivo executando Y1 poderá receber uma atualização para Y2.
  • Se Y1 for maior que Y2, um dispositivo com Y1 não poderá ser atualizado para Y2.

Ou seja, se a versão da KMI não mudar, o subnível não poderá ser reduzido por nenhuma atualização OTA.

Determinar a versão do kernel de um dispositivo

Para encontrar a versão completa do kernel, execute uname -r ou uname(2) com o seguinte snippet de código:

std::string get_kernel_release() {
  struct utsname buf;
  return uname(&buf) == 0 ? buf.release : "";
}

Um exemplo de saída é:

5.4.42-android12-0-00544-ged21d463f856

Para os fins deste documento, tudo após a geração do KMI é ignorado ao extrair informações do kernel. De maneira mais formal, a saída de uname -r é analisada com a seguinte expressão regular (supondo que zzz sempre comece com "android"):

^(?P<w>\d+)[.](?P<x>\d+)[.](?P<y>\d+)-(?P<z>android\d+)-(?P<k>\d+).*$

As informações ignoradas podem incluir o número do build ci.android.com, o número de patches no kernel de referência e os hashes SHA do commit do Git.

libkver

A biblioteca libkver fornece uma interface C++ para analisar a versão do kernel ou uma string de versão do KMI. Para conferir uma lista de APIs que a libkver expõe, consulte packages/modules/Gki/libkver/include/kver.

Verificações do VINTF

No Android 11 ou versões anteriores, a parte de lançamento do Android da versão KMI é especificada manualmente no manifesto do dispositivo pelos fabricantes. Para mais detalhes, consulte Regras de correspondência do kernel VINTF.

A partir do Android S, a parte de lançamento do Android da versão KMI pode ser extraída do kernel e injetada no manifesto do dispositivo durante a compilação.

Como os requisitos de configuração do kernel geralmente não mudam, não é necessário codificar k na matriz de compatibilidade. No entanto, no caso improvável de ser necessário mudar o requisito de configuração do kernel, verifique o seguinte:

  • O requisito correspondente da matriz de compatibilidade é removido.
  • Outros testes do VTS são adicionados para verificar os novos requisitos condicionais na geração de KMI.

Versão da imagem de inicialização nos metadados OTA

Mesmo que a imagem de inicialização seja atualizada por uma atualização OTA, ela precisa ser encapsulada no formato de payload OTA, payload.bin. O payload da OTA codifica um campo version para cada partição. Quando o update_engine processa uma carga útil OTA, ele compara esse campo para garantir que a partição não seja reduzida.

Para evitar confusão, o campo version da partição de inicialização nos metadados da OTA é chamado de boot image version.

Como o ramdisk é sempre criado do zero, usar o ramdisk timestamp é suficiente para descrever toda a imagem de inicialização. Não é necessário codificar a versão do kernel na versão da imagem de inicialização, a menos que você esteja combinando uma imagem de inicialização antiga com um novo binário do kernel no futuro.

Antes de uma atualização OTA, o cliente OTA verifica a versão da imagem de inicialização da mesma forma que qualquer outra partição.