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 sublevel. 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). |
Sublevel | 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 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 sublevel, 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 sublevel, 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.
Sublevel
The sublevel, 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 sublevel 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 can't be updated to Y2.
That is, if the KMI version doesn't change, the sublevel must not be decreased by any OTA update.
Determine 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.