GKI Versioning

This page describes the versioning scheme for Generic Kernel Images (GKIs). A Generic Kernel Image (GKI) has a unique identifier called the kernel release. The kernel release consists of the kernel module interface (KMI) version and the sub-level. The kernel release is specific to the image being released, whereas the KMI version represents the interface that a release is built from. A KMI version can support multiple kernel releases. A kernel release is tied to only one KMI version. In the unlikely event where the kernel module interface has to be changed, the KMI generation is iterated to reflect the change in KMI version.

Summary of terms

The following table summarizes important terms used on this page and for GKI updates.

Name Symbol Example Description
Kernel release w.x.y-zzz-k-suffix 5.4.42-android12-0-foo Unique identifier for a GKI release. This is the value returned by uname.
KMI version w.x-zzz-k 5.4-android12-0 Describes the kernel module interface (KMI) between GKI and dynamically loadable kernel modules (DLKM).
Sub-level y 42 Describes the release order of kernel releases within the same KMI version.

The following table lists other related terms as a reference.

Name Symbol Example Description
w.x.y w.x.y 5.4.42

For details, see Linux Kernel Makefiles (search for "KERNELRELEASE").

w.x.y is used directly throughout this document. This is also commonly referred to as the three-part version number. The term used in VINTF, kernel version, might cause confusion with other terms, especially w.

This variable is referred to as kernel_version_tuple in libkver.

This tuple must not be decreased by any updates, including OTA or mainline.

Kernel branch zzz-w.x android12-5.4 This term is used in Common kernel branch types.
Version w 5 This term is not used in this document. This variable is referred to as version in libkver.
Patch level x 4 This term is not used in this document. This variable is referred to as patch_level in libkver.
Android release zzz android12

This is the Android (dessert) release number that the kernel is associated with.

When comparing the AndroidRelease field, the numeric part is extracted from the string for comparison.

The Android release number must not be decreased by any updates, including OTA or mainline.

KMI generation k 0

This is an additional number added to deal with unlikely events. If a security bug fix requires changes to the KMI within the same Android release, a KMI generation is increased.

The KMI generation number starts with 0.

Versioning design

Kernel release

Definition

For devices that ship with GKI, the kernel release is defined as follows:

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

For more information, see Determining kernel release from a device.

The following is an example of a kernel release.

5.4.42-android12-0-00544-ged21d463f856

Description

The kernel release is the unique ID of a GKI release. If two GKI binaries have the same kernel release, they must be byte-wise identical.

A kernel release consists of a KMI version, a sub-level, and a suffix. For the purposes of this document, the suffix after KMI generation is ignored.

KMI version

Definition

The KMI version is defined as follows:

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

Note that the sub-level, y isn't part of the KMI version. For the example in Kernel release, the KMI version is:

5.4-android12-0

Description

The KMI version describes the kernel module interface (KMI) between GKI and dynamically loadable kernel modules (DLKM).

If two kernel releases have the same KMI version, they implement the same kernel module interface. The DLKMs that are compatible with one are also compatible with the other.

The KMI version must not be decreased by any OTA updates.

Sub-level

The sub-level, y, describes the release order of kernel releases within the same KMI version.

For two kernel releases that have the same KMI version but have sub-level Y1 and Y2 respectively:

  • If Y1 is less than or equal to Y2, a device running Y1 can receive an update to Y2.
  • If Y1 is greater than Y2, a device running Y1 cannot be updated to Y2.

That is, if the KMI version doesn't change, the sub-level must not be decreased by any OTA update.

Determining kernel release from a device

The full kernel release can be found by executing uname -r, or uname(2) with the following code snippet:

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

An example output is:

5.4.42-android12-0-00544-ged21d463f856

For the purpose of this document, anything after the KMI generation is ignored when extracting kernel information. More formally, the output of uname -r is parsed with the following regex (assuming zzz always starts with "android"):

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

The ignored information can include information such as the ci.android.com build number, number of patches on top of the baseline kernel, and SHA hashes of the git commit.

libkver

The library, libkver, provides a C++ interface to parse the kernel release or a KMI version string. For a list of APIs that libkver exposes, see packages/modules/Gki/libkver/include/kver.

VINTF checks

For Android 11 or lower, the Android release part of the KMI version is specified manually in the device manifest by device manufacturers. For details, see VINTF kernel match rules.

From Android S, the Android release part of the KMI version can be extracted from the kernel and injected into the device manifest at build time.

Because kernel configuration requirements generally don't change, there's no need to encode k within the compatibility matrix. However, in the unlikely case where the kernel configuration requirement does need to be changed, ensure the following:

  • The corresponding requirement from the compatibility matrix is removed.
  • Additional VTS tests are added to check the new requirements conditional on KMI generation.

Boot image version in OTA metadata

Even if the boot image is updated through OTA an update, it must be wrapped in the OTA payload format, payload.bin. The OTA payload encodes a version field for each partition. When update_engine handles an OTA payload, it compares this field to ensure the partition is not downgraded.

To avoid confusion, the version field for the boot partition in the OTA metadata is called boot image version.

Because the ramdisk is always built from scratch, using the ramdisk timestamp is sufficient to describe the whole boot image. There's no need to encode kernel release in the boot image version, unless you are stitching an old boot image to a new kernel binary in the future.

Before an OTA update, the OTA client checks the boot image version in the same way as any other partition.