Esquema de control de versiones de GKI

En esta página, se describe el esquema de control de versiones de las imágenes genéricas del kernel (GKIs). Una imagen genérica de kernel (GKI) tiene un identificador único llamado versión del kernel. La versión del kernel consta de la versión de la interfaz de módulo de kernel (KMI) y el subnivel. La versión del kernel es específica de la imagen que se lanza, mientras que la versión de KMI representa la interfaz a partir de la cual se compila una versión. Una versión de KMI puede admitir varios lanzamientos de kernel. Una versión del kernel está vinculada a una sola versión de KMI. En el caso poco probable de que se deba cambiar la interfaz del módulo del kernel, se itera la generación de la KMI para reflejar el cambio en la versión de la KMI.

Resumen de las condiciones

En la siguiente tabla, se resumen los términos importantes que se usan en esta página y para las actualizaciones de GKI.

Nombre Símbolo Ejemplo Descripción
Lanzamiento de kernel w.x.y-zzz-k-sufijo 5.4.42-android12-0-foo Es el identificador único de una versión de GKI. Este es el valor que muestra uname.
Versión de KMI w.x-zzz-k 5.4-android12-0 Describe la interfaz del módulo de kernel (KMI) entre GKI y los módulos de kernel de carga dinámica (DLKM).
Subnivel y 42 Describe el orden de lanzamiento de las versiones del kernel dentro de la misma versión de KMI.

En la siguiente tabla, se incluyen otros términos relacionados como referencia.

Nombre Símbolo Ejemplo Descripción
w.x.y w.x.y 5.4.42

Para obtener más información, consulta Makefiles del kernel de Linux (busca "KERNELRELEASE").

w.x.y se usa directamente en este documento. Por lo general, también se denomina número de versión de tres partes. El término que se usa en VINTF, versión del kernel, puede causar confusión con otros términos, en especial w.

Esta variable se conoce como kernel_version_tuple en libkver.

Esta tupla no se debe reducir con ninguna actualización, incluidas las actualizaciones inalámbricas o de línea principal.

Rama del kernel zzz-w.x android12-5.4 Este término se usa en los tipos de rama de kernel común.
Versión w 5 Este término no se usa en este documento. Esta variable se denomina version en libkver.
Nivel de parche x 4 Este término no se usa en este documento. Esta variable se conoce como patch_level en libkver.
Versión de Android zzz android12

Este es el número de versión de Android (postre) con el que se asocia el kernel.

Cuando se compara el campo AndroidRelease, la parte numérica se extrae de la cadena para la comparación.

El número de versión de Android no debe disminuir con ninguna actualización, incluidas las actualizaciones OTA o principales.

Generación de KMI k 0

Es un número adicional que se agrega para controlar eventos poco probables. Si una corrección de errores de seguridad requiere cambios en el KMI dentro de la misma versión de Android, se aumenta una generación de KMI.

El número de generación de KMI comienza con 0.

Diseño del control de versiones

Lanzamiento de kernel

Definición

En el caso de los dispositivos que se envían con GKI, la versión del kernel se define de la siguiente manera:

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

Para obtener más información, consulta Cómo determinar la versión del kernel de un dispositivo.

El siguiente es un ejemplo de una versión de kernel.

5.4.42-android12-0-00544-ged21d463f856

Descripción

La versión del kernel es el ID único de una versión de GKI. Si dos objetos binarios de GKI tienen la misma versión de kernel, deben ser idénticos en cuanto a bytes.

Una versión de kernel consta de una versión de KMI, un subnivel y un sufijo. A los efectos de este documento, se ignora el sufijo después de la generación de KMI.

Versión de KMI

Definición

La versión de KMI se define de la siguiente manera:

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

Ten en cuenta que el subnivel, y, no forma parte de la versión de KMI. En el ejemplo de lanzamiento de kernel, la versión de KMI es la siguiente:

5.4-android12-0

Descripción

La versión de KMI describe la interfaz del módulo de kernel (KMI) entre GKI y los módulos de kernel de carga dinámica (DLKM).

Si dos versiones del kernel tienen la misma versión de KMI, implementan la misma interfaz de módulo del kernel. Los DLKM que son compatibles con uno también son compatibles con el otro.

Las actualizaciones OTA no deben disminuir la versión de KMI.

Subnivel

El subnivel, y, describe el orden de lanzamiento de las versiones de kernel dentro de la misma versión de KMI.

Para dos versiones de kernel que tienen la misma versión de KMI, pero tienen los subniveles Y1 y Y2, respectivamente, haz lo siguiente:

  • Si Y1 es menor o igual que Y2, un dispositivo que ejecuta Y1 puede recibir una actualización a Y2.
  • Si el año 1 es mayor que el año 2, un dispositivo que ejecuta el año 1 no se puede actualizar al año 2.

Es decir, si la versión de KMI no cambia, ninguna actualización OTA debe disminuir el subnivel.

Cómo determinar la versión de kernel desde un dispositivo

Para encontrar la versión completa del kernel, ejecuta uname -r o uname(2) con el siguiente fragmento de código:

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

Este es un resultado de ejemplo:

5.4.42-android12-0-00544-ged21d463f856

A los efectos de este documento, se ignora todo lo que se genera después de la generación de KMI cuando se extrae información del kernel. De forma más formal, el resultado de uname -r se analiza con la siguiente regex (suponiendo que zzz siempre comienza con "android"):

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

La información omitida puede incluir información como el número de compilación de ci.android.com, la cantidad de parches sobre el kernel de referencia y los valores hash SHA de la confirmación de git.

libkver

La biblioteca, libkver, proporciona una interfaz C++ para analizar la versión del kernel o una cadena de versión de KMI. Para obtener una lista de las APIs que expone libkver, consulta packages/modules/Gki/libkver/include/kver.

Verificaciones de VINTF

En el caso de Android 11 o versiones anteriores, los fabricantes de dispositivos especifican manualmente la versión de Android de la versión de KMI en el manifiesto del dispositivo. Para obtener más detalles, consulta Reglas de coincidencia del kernel de VINTF.

A partir de Android S, la parte de Android de la versión de KMI se puede extraer del kernel e insertarse en el manifiesto del dispositivo en el tiempo de compilación.

Como los requisitos de configuración del kernel generalmente no cambian, no es necesario codificar k dentro de la matriz de compatibilidad. Sin embargo, en el caso improbable de que se deba cambiar el requisito de configuración del kernel, asegúrate de lo siguiente:

  • Se quita el requisito correspondiente de la matriz de compatibilidad.
  • Se agregan pruebas de VTS adicionales para verificar los nuevos requisitos condicionales en la generación de KMI.

Versión de la imagen de arranque en los metadatos OTA

Incluso si la imagen de inicio se actualiza a través de una actualización OTA, se debe unir en el formato de carga útil OTA, payload.bin. La carga útil OTA codifica un campo version para cada partición. Cuando update_engine controla una carga útil inalámbrica, compara este campo para garantizar que la partición no cambie a una versión inferior.

Para evitar confusiones, el campo version de la partición de inicio en los metadatos de OTA se llama boot image version.

Como el ramdisk siempre se compila desde cero, usar la marca de tiempo de ramdisk es suficiente para describir toda la imagen de arranque. No es necesario codificar la versión del kernel en la versión de la imagen de inicio, a menos que en el futuro una imagen de inicio anterior a una nueva imagen binaria del kernel.

Antes de una actualización OTA, el cliente OTA verifica la versión de la imagen de inicio de la misma manera que cualquier otra partición.