На этой странице описана схема версий для универсальных образов ядра (GKI). Обобщенный образ ядра (GKI) имеет уникальный идентификатор, который называется версией ядра. Версия ядра состоит из версии интерфейса модуля ядра (KMI) и подуровня. Версия ядра относится к конкретному образу, а версия KMI – к интерфейсу, на основе которого создан образ. Одна версия KMI может поддерживать несколько версий ядра. Версия ядра связана только с одной версией KMI. Если интерфейс модуля ядра все же придется изменить, будет создана новая версия KMI.
Краткое изложение условий
В таблице ниже приведены важные термины, используемые на этой странице и в обновлениях GKI.
| Название | Символ | Пример | Описание |
|---|---|---|---|
| Версия ядра | w.x.y-zzz-k-suffix | 5.4.42-android12-0-foo | Уникальный идентификатор выпуска GKI. Это значение, возвращаемое функцией uname. |
| Версия KMI | w.x-zzz-k | 5.4-android12-0 | Описывает интерфейс модуля ядра (KMI) между GKI и динамически загружаемыми модулями ядра (DLKM). |
| Подуровень | y | 42 | Описывает порядок выпуска ядер в рамках одной версии KMI. |
В таблице ниже приведены другие связанные термины.
| Название | Символ | Пример | Описание |
|---|---|---|---|
| w.x.y | w.x.y | 5.4.42 |
Подробную информацию можно найти в документации по файлам Makefile для ядра Linux (выполните поиск по запросу KERNELRELEASE). В этом документе используется версия w.x.y. Его также называют трехкомпонентным номером версии. Термин, используемый в VINTF, версия ядра, может быть спутан с другими терминами, особенно с w. В libkver эта переменная называется kernel_version_tuple. Это значение нельзя уменьшать при обновлении, в том числе при обновлении по воздуху или через основной модуль. |
| Ветвь ядра | zzz-w.x | android12-5.4 | Этот термин используется в разделе Распространенные типы веток ядра. |
| Версия | w | 5 | Этот термин не используется в документе. В libkver эта переменная называется version. |
| Уровень исправления | x | 4 | Этот термин не используется в документе. В libkver эта переменная называется patch_level. |
| Версия Android | zzz | android12 |
Номер версии Android, с которой связано ядро.
При сравнении поля Номер версии Android не должен уменьшаться при обновлении, в том числе при обновлении по воздуху или через основной модуль. |
| Генерация KMI | k | 0 |
Это дополнительный номер, который может понадобиться в маловероятных ситуациях. Если для исправления ошибки безопасности требуется изменить KMI в рамках одного выпуска Android, поколение KMI увеличивается. Номер поколения KMI начинается с 0. |
Дизайн версий
Версия ядра
Определение
Для устройств с GKI выпуск ядра определяется следующим образом:
KernelRelease :=
Version.PatchLevel.SubLevel-AndroidRelease-KmiGeneration-suffix
w .x .y -zzz -k -something
Подробнее о том, как определить версию ядра на устройстве…
Ниже приведен пример выпуска ядра.
5.4.42-android12-0-00544-ged21d463f856
Описание
Версия ядра – это уникальный идентификатор релиза GKI. Если у двух двоичных файлов GKI одинаковая версия ядра, они должны быть идентичны побайтно.
Выпуск ядра состоит из версии KMI, подуровня и суффикса. В этом документе суффикс, добавляемый после создания KMI, игнорируется.
Версия KMI
Определение
Версия KMI определяется следующим образом:
KmiVersion :=
Version.PatchLevel-AndroidRelease-KmiGeneration
w .x -zzz -k
Обратите внимание, что подуровень y не является частью версии KMI. В примере из раздела Выпуск ядра версия KMI будет следующей:
5.4-android12-0
Описание
Версия KMI описывает интерфейс модуля ядра (KMI) между GKI и динамически загружаемыми модулями ядра (DLKM).
Если у двух версий ядра одинаковая версия KMI, они реализуют один и тот же интерфейс модуля ядра. DLKM, совместимые с одним из них, также совместимы с другим.
Версия KMI не должна понижаться при беспроводном обновлении.
Подуровень
Подуровень y описывает порядок выпуска ядер в рамках одной версии KMI.
Для двух версий ядра с одинаковой версией KMI, но разными дополнительными уровнями Y1 и Y2:
- Если Y1 меньше или равно Y2, устройство с версией Y1 может получить обновление до версии Y2.
- Если Y1 больше Y2, устройство с версией Y1 нельзя обновить до версии Y2.
То есть если версия KMI не меняется, уровень защиты не должен понижаться при беспроводном обновлении.
Как определить версию ядра на устройстве
Полную версию ядра можно узнать, выполнив команду uname -r или
uname(2)
с помощью следующего фрагмента кода:
std::string get_kernel_release() {
struct utsname buf;
return uname(&buf) == 0 ? buf.release : "";
}
Пример выходных данных:
5.4.42-android12-0-00544-ged21d463f856
В этом документе при извлечении информации о ядре все, что следует за генерацией KMI, игнорируется. Если говорить более формально, выходные данные uname -r анализируются с помощью следующего регулярного выражения (предполагается, что zzz всегда начинается с "android"):
^(?P<w>\d+)[.](?P<x>\d+)[.](?P<y>\d+)-(?P<z>android\d+)-(?P<k>\d+).*$
Игнорируемая информация может включать номер сборки ci.android.com, количество исправлений поверх базового ядра и хеши SHA коммита git.
libkver
Библиотека libkver предоставляет интерфейс C++ для анализа строки версии выпуска ядра или KMI. Список API, которые предоставляет libkver, можно найти в packages/modules/Gki/libkver/include/kver.
Проверки VINTF
В Android 11 и более ранних версиях часть версии KMI, относящаяся к выпуску Android, указывается производителями устройств вручную в манифесте устройства. Подробнее о правилах соответствия ядра VINTF…
Начиная с Android S, часть версии KMI, относящуюся к выпуску Android, можно извлечь из ядра и внедрить в манифест устройства во время сборки.
Поскольку требования к конфигурации ядра обычно не меняются, нет необходимости кодировать k в матрице совместимости. Однако в маловероятном случае, когда конфигурацию ядра все же нужно изменить, убедитесь, что:
- Соответствующее требование удаляется из матрицы совместимости.
- Добавлены дополнительные тесты VTS для проверки новых требований, зависящих от поколения KMI.
Версия загрузочного образа в метаданных OTA
Даже если загрузочный образ обновляется по беспроводной сети, он должен быть упакован в формат полезной нагрузки OTA, payload.bin. Полезная нагрузка OTA кодирует поле version для каждого раздела. При обработке полезной нагрузки OTA update_engine сравнивает это поле, чтобы убедиться, что раздел не понижен.
Чтобы избежать путаницы, поле version для загрузочного раздела в метаданных OTA называется boot image version.
Поскольку ramdisk всегда создается с нуля, для описания всего загрузочного образа достаточно использовать ramdisk timestamp. Нет необходимости кодировать версию ядра в версии загрузочного образа, если только вы не планируете в будущем объединять старый загрузочный образ с новым двоичным файлом ядра.
Перед беспроводным обновлением клиент OTA проверяет версию образа загрузки так же, как и любого другого раздела.