Общий образ ядра

Android Общие Ядра (ACKs) являются основой для всех Android ядра продукта. Ядра поставщиков и устройств находятся после ACK. Поставщики добавляют поддержку SoC и периферийных устройств, изменяя исходный код ядра и добавляя драйверы устройств. Эти модификации могут быть обширными, до такой степени , что почти 50% кода , работающего на устройстве вне дерева кода (не из вышестоящего Linux или из общих ядер AOSP).

Таким образом, ядро ​​устройства состоит из:

  • Вверх по течению: ядро ​​Linux с kernel.org
  • AOSP: дополнительные патчи для Android из общих ядер AOSP
  • Производитель: SoC и исправления для включения и оптимизации периферийных устройств от поставщиков.
  • OEM / устройство: дополнительные драйверы устройств и настройки

Почти каждое устройство имеет собственное ядро. Это фрагментация ядра.

Иерархия ядра Android приводит к фрагментации

Рисунок 1. Android иерархии приводит к фрагментации ядра

Цена фрагментации

Фрагментация ядра имеет несколько негативных последствий для сообщества Android.

Обновления безопасности трудозатратны

Обновления безопасности цитируется в бюллетене для Android безопасности (АСБ) должны быть портированном в каждое из ядер устройств. Однако из-за фрагментации ядра распространять исправления безопасности на устройства Android в полевых условиях непомерно дорого.

Трудно объединить долгосрочные поддерживаемые обновления

Долгосрочный Поддерживаемый (LTS) выпуски включают исправления безопасности и другие важные исправления ошибок. Своевременное обновление выпусков LTS оказалось наиболее эффективным способом исправления ошибок. На устройствах Pixel было обнаружено, что 90% проблем безопасности ядра, о которых сообщалось в ASB, уже были исправлены для устройств, которые остаются в актуальном состоянии.

Однако со всеми пользовательскими модификациями в ядрах устройств сложно просто объединить исправления LTS в ядра устройств.

Запрещает обновление выпуска платформы Android

Фрагментация затрудняет внедрение новых функций Android, требующих внесения изменений ядра в устройства в полевых условиях. Код Android Framework должен предполагать, что поддерживается до пяти версий ядра и что никаких изменений ядра не было сделано для новой версии платформы (Android 10 поддерживает ядра 3.18, 4.4, 4.9, 4.14 и 4.19, которые в некоторых случаях не были улучшен новыми функциями с Android 8 в 2017 году).

Трудно внести изменения ядра обратно в вышестоящую версию Linux

Со всеми изменениями, внесенными в ядро, большинство флагманских устройств поставляются с версией ядра, которой уже не менее 18 месяцев. Так , например, 4,14 ядра было выпущено kernel.org в ноябре 2017 года и первых телефонах Android с использованием 4,14 ядер погруженных весной 2019 года.

Эта длительная задержка между выпуском ядра основной ветки разработки и продуктами затрудняет для сообщества Android ввод необходимых функций и драйверов в ядра исходной версии, поэтому решить проблему фрагментации сложно.

Исправление фрагментации: общий образ ядра

Родовое Kernel Image (ГКО) Проект направлен Kernel фрагментации пути объединения в ядро и перемещения SoC и поддержки доски из основного ядра в подгружаемые модули. ГКИ Kernel представляет стабильное ядро Интерфейсный модуль (КМИ) для модулей ядра, поэтому модули и ядро можно обновить самостоятельно.

ГКИ:

  • Сооружена из источников ACK.
  • Является одним ядро двоичного плюс связанного загружаемые модули в архитектуру, за выпуск LTS ( в настоящее время только arm64 для android11-5.4 и android12-5.4 ).
  • Протестирована со всеми выпусками Android платформы, которые поддерживаются для соответствующей ACK. Нет никаких устаревших функций на время существования версии ядра GKI.
  • Выставляет конюшню ОЙ для водителей в пределах данного LTS.
  • Не содержит SoC- или платы конкретного кода.

Вот как выглядит устройство Android с реализованным GKI.

Архитектура GKI

Архитектура Рисунок 2. ГКИ

GKI - это сложное изменение, которое будет внедряться в несколько этапов, начиная с ядер v5.4 в выпуске платформы Android 11.

GKI 1.0 - требования совместимости с GKI

Для некоторых устройств, запускаемых с версией платформы Android 11, совместимость Treble требует тестирования GKI для устройств с ядром v5.4.

Разделы для тестирования совместимости с GKI

Рисунок 3. Перегородки для тестирования совместимости ГКИ

ГКИ средства совместимости , что устройство проходит СДС и CTS-на-GSI тестов + ГКИ с изображением Generic системы (ГСИ) и ГКИ ядра , установленного миганием загрузочный образ ГКИ в boot раздел и GSI образа системы в system разделе. Устройства могут поставляться с различным ядром продукта и могут использовать загружаемые модули , которые ГКО не предоставляет. Однако, как продукт и ядра ГКИ необходимо загрузить модули из одних и тех же vendor_boot и vendor разделов. Следовательно, все ядра продукта должны иметь один и тот же двоичный интерфейс модуля ядра (KMI). Поставщики могут расширять KMI для ядер продуктов, пока он остается совместимым с GKI KMI. В GKI 1.0 не требуется, чтобы модули поставщика были выгружаемы.

Голы ГКИ 1.0

  • Не вводите регрессии в VTS или CTS, когда ядро ​​продукта заменяется ядром GKI.
  • Снизьте бремя обслуживания ядра для OEM-производителей и поставщиков, чтобы быть в курсе последних достижений общих ядер AOSP.
  • Включите основные изменения Android в ядра независимо от того, обновлено ли устройство до новой версии платформы Android или выпущено недавно.
  • Никогда не нарушайте пользовательское пространство Android.
  • Отделяйте аппаратно-зависимые компоненты от ядра ядра как загружаемые модули.

GKI 2.0 - продукты GKI

Некоторые устройства, запуск с Android 12 (2021) платформа релиз с использованием версии ядра v5.10 или выше , необходимые для судна с ядром ГКО. Сертифицированные загрузочные образы будут доступны и регулярно обновляются с LTS и исправлениями критических ошибок. Поскольку для KMI будет сохранена бинарная стабильность, эти загрузочные образы можно установить без изменений в образах поставщиков.

Голы ГКИ 2.0

  • Не вводите значительного снижения производительности или мощности с помощью GKI.
  • Разрешите OEM-производителям доставлять исправления безопасности ядра и исправления ошибок (LTS) без участия поставщика.
  • Снижение затрат на обновление основной версии ядра для устройств (например, с версии 5.10 до ядра LTS 2021 года).
  • Поддерживайте только один двоичный файл ядра GKI на архитектуру, обновляя версии ядра с четким процессом обновления.

Интеграция с GKI 2.0 boot.img

Установить следующие переменные платы включить заверенную ГКИ boot.img в свой код. Настройка, показанная ниже, является лишь примером для настройки для каждого устройства.

# Uses a prebuilt boot.img
TARGET_NO_KERNEL := true
BOARD_PREBUILT_BOOTIMAGE := device/${company}/${board}/boot.img

# Enables chained vbmeta for the boot.img so it can be updated independently,
# without updating the vbmeta.img. The following configs are optional.
# When they're absent, the hash of the boot.img will be stored then signed in
# the vbmeta.img.
BOARD_AVB_BOOT_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem
BOARD_AVB_BOOT_ALGORITHM := SHA256_RSA4096
BOARD_AVB_BOOT_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_BOOT_ROLLBACK_INDEX_LOCATION := 2

ГКИ дизайн

Ветки ядра KMI

ГКИ ядра построены из ветвей ядра ACK КХ, которые подробно описаны в Android Common ядрах . КМИ однозначно идентифицируется по версии ядра и выпуска Android платформы, поэтому ветви называют <androidRelease>-<kernel version> . Например, 5,4 ОЕ ядро ветви для Android 11 называется android11-5.4. Ожидается , что для Android 12 (не совершала и показаны только чтобы продемонстрировать , как новая модель ветвление будет развиваться в будущем) будет две дополнительные КМИ ядер, android12-5.4 и второе ядро на основе 5.10 LTS ядра, выпущенный в декабре 2020.

Иерархия ядра KMI

На рисунке 4 показана иерархия ветвей для ядер KMI 5.10. android12-5.10 является ядром ОГО , соответствующее Android 12 и android13-5.10 соответствует Android T (AOSP экспериментальных) (не совершали и показана только для демонстрации того, как новая модель ветвления будет развиваться в будущем).

Иерархия ядра KMI для 5.10

Рисунок 4. Ядро ОЙ иерархия 5.10

Как показано на фиг.4, КЕ ветви цикл через три фазы: развитие (DEV), стабилизация (удар), и замораживает. Эти этапы подробно описаны в Android Common ядрах .

После замораживания ядра KMI никакие изменения, нарушающие KMI, не принимаются, если не выявлена ​​серьезная проблема безопасности, которую нельзя устранить, не затрагивая стабильный KMI. Ветка остается замороженной на протяжении всего срока службы.

Исправления ошибок и партнерские функции могут быть приняты в замороженную ветку, если существующий KMI не нарушен. KMI может быть расширен новыми экспортированными символами при условии, что интерфейсы, составляющие текущий KMI, не затронуты. Когда в KMI добавляются новые интерфейсы, они сразу становятся стабильными и не могут быть нарушены будущими изменениями.

Например, изменение, которое добавляет поле в структуру, используемую интерфейсом KMI, не допускается, потому что оно изменяет определение интерфейса:

struct foo {
  int original_field1;
  int original_field2;
  int new_field; // Not allowed
};

int do_foo(struct foo &myarg)
{
  do_something(myarg);
}
EXPORT_SYMBOL_GPL(do_foo);

Однако можно добавить новую функцию:

struct foo_ext {
  struct foo orig_foo;
  int new_field;
};

int do_foo2(struct foo_ext &myarg)
{
  do_something_else(myarg);
}
EXPORT_SYMBOL_GPL(do_foo2);

KMI стабильность

Для реализации целей GKI критически важно поддерживать стабильный KMI для водителей. Ядро GKI построено и поставляется в двоичной форме, но загружаемые производителями модули построены в отдельном дереве. Полученное в результате ядро ​​и модули GKI должны работать так, как если бы они были собраны вместе. Для тестирования совместимости с GKI загрузочный образ, содержащий ядро, заменяется загрузочным образом, содержащим ядро ​​GKI, а загружаемые модули в образе поставщика должны правильно работать с любым ядром.

KMI не включает все символы в ядре или даже все 30 000+ экспортированных символов. Вместо этого символы, которые могут использоваться модулями, явно перечислены в наборе файлов списков символов, общедоступных в корне дерева ядра. Объединение всех символов во всех файлах списка символов определяет набор символов KMI, поддерживаемый как стабильный. Пример список символов файл abi_gki_aarch64_db845c , который объявляет символы , необходимые для DragonBoard 845c .

Только символы, перечисленные в списке символов, а также связанные с ними структуры и определения считаются частью KMI. Вы можете публиковать изменения в списках символов, если нужных вам символов нет. После того, как новые интерфейсы находятся в списке символов и, следовательно, являются частью описания KMI, они сохраняются как стабильные и не должны удаляться из списка символов или изменяться после замораживания ветви.

Каждое дерево ядра KMI имеет собственный набор списков символов. Не предпринимается никаких попыток обеспечить стабильность ABI между различными ветвями ядра KMI. Например, КЙ для android11-5.4 является полностью независимым от ОГО для android12-5.4 .

В целом, сообщество Linux уже нахмурилась на понятии в ядре стабильности ABI для ядра магистральный. Перед лицом различных наборов инструментов, конфигураций и постоянно развивающегося основного ядра Linux невозможно поддерживать стабильный KMI в основной ветке. Однако это возможно в сильно ограниченной среде GKI. Ограничения:

  • КМИ является единственным стабильным в пределах одного ядра LTS (например, android11-5.4 ).
    • Стабильность Нет АЯ поддерживаются для android-mainline .
  • Только конкретный Clang Набор инструментов поставляются в AOSP и определена для соответствующей отрасли используются для построения ядра и модулей.
  • Только символы, о которых известно, что они используются модулями, как указано в списке символов, проверяются на стабильность и считаются символами KMI.
    • Следствие состоит в том, что модули должны использовать только символы KMI. Это обеспечивается ошибкой загрузки модуля, если требуются символы, отличные от KMI.
  • После того, как ветка KMI заморожена, никакие изменения не могут нарушить работу KMI, в том числе:
    • Изменения конфигурации
    • Изменения кода ядра
    • Изменения в инструментальной цепочке (включая обновления)

КМИ мониторинг

Инструменты мониторинга ABI контроль стабильности ОЙ во время presubmit тестирования. Изменения, нарушающие KMI, не проходят предварительное тестирование и должны быть переработаны для обеспечения совместимости. Эти инструменты доступны партнерам и общественности для интеграции в их процессы сборки. Команда ядра Android использует эти инструменты для поиска сбоев KMI во время разработки и при слиянии выпусков LTS. Если во время слияния LTS обнаруживается сбой KMI, KMI сохраняется либо путем удаления проблемных исправлений, либо путем рефакторинга исправлений для обеспечения совместимости.

KMI считается сломанным, если существующий символ KMI изменен несовместимым образом. Примеры:

  • В функцию KMI добавлен новый аргумент
  • Новое поле добавлено в структуру, используемую функцией KMI
  • Добавлено новое значение перечисления, которое изменяет значения перечислений, используемых функцией KMI
  • Изменение конфигурации, изменяющее присутствие элементов данных, влияющих на KMI

Добавление новых символов не обязательно нарушает KMI, но новые используемые символы должны быть добавлены в список символов и в представление ABI. В противном случае будущие изменения в этой части KMI не будут признаны.

Ожидается, что партнеры будут использовать инструменты мониторинга ABI для сравнения KMI между их ядром продукта и ядром GKI и убедиться, что они совместимы.

Последний android11-5.4 двоичный ГКИ ядро можно загрузить с ci.android.com ( kernel_aarch64 сборки).

Единый компилятор

Изменение компилятора может изменить структуру внутренней структуры данных ядра, которая влияет на ABI. Поскольку крайне важно поддерживать стабильность KMI, набор инструментов, используемый для создания ядра GKI, должен быть полностью совместим с набором инструментов, используемым для создания модулей поставщика. Ядро GKI построено с помощью инструментария LLVM, включенного в AOSP.

Начиная с Android 10, все ядра Android должны быть построены с использованием набора инструментов LLVM. При использовании GKI цепочка инструментов LLVM, используемая для создания ядер продуктов и модулей поставщиков, должна генерировать тот же ABI, что и цепочка инструментов LLVM от AOSP, и партнеры должны гарантировать, что KMI совместим с ядром GKI.

Документация Android сборки ядра описывается , как строится ядро ссылки ГКА. В частности, задокументированная процедура гарантирует, что для сборки ядра используются правильные набор инструментов и конфигурация. Нижестоящим партнерам рекомендуется использовать тот же инструментарий для создания окончательного ядра, чтобы избежать несовместимости, вызванной набором инструментов или другими зависимостями во время сборки.

Конфиги ядра

Ядро ГКО построено с использованием arch/arm64/configs/gki_defconfig . Поскольку эти конфигурации влияют на KMI, конфигурациями GKI управляют очень тщательно. Для замороженных ядер KMI конфиги могут быть добавлены или удалены только в том случае, если это не повлияет на KMI.

Ядро GKI должно быть настроено для работы на разнообразном наборе устройств. Следовательно, он должен иметь встроенную поддержку всех подсистем и опций, необходимых для всех этих устройств, за исключением загружаемых модулей, которые используются для включения оборудования. Партнеры должны запросить необходимые изменения конфигурации для Девых ядер.

Изменения при загрузке

Для облегчения четкого разделения между ГКА и поставщиками компонентами, то boot раздел содержит только общие компоненты, включая ядро и виртуальный диск с модулями ГКИ. Новая версия загрузочного заголовка (v3) определена для обозначения соответствия архитектуре GKI. Версия загрузочных образов для GKI предоставляется Google и заменяет версию загрузочного образа от поставщика при тестировании на совместимость с GKI.

Электронный диск для первой стадии init , recovery и fastbootd является initramfs изображения состоит из двух архивов CPIO , которые соединяются с помощью загрузчика. Первый архив CPIO приходит от нового vendor_boot раздела. Второй исходит из boot раздела.

Сводка изменений представлена ​​здесь. См Vendor загрузочный раздел для деталей.

Загрузочный раздел

boot раздел включает в себя заголовок, ядро и CPIO архив родовых частей загрузочного электронного диска.

Нет С v3 заголовка загрузки boot раздела, эти разделы предварительной boot раздела больше не присутствуют:

  • Загрузчик второго уровня: если устройство имеет загрузчик второго уровня, он должен храниться в его собственном разделе.
  • DTB: DTB хранится в загрузочном разделе Vendor .

boot раздел содержит архив CPIO с компонентами ГКИ:

  • Модули ядра ГКИ , расположенные в /lib/modules/
  • first_stage_init и библиотеки это зависит
  • fastbootd и recovery (используется в A / B и Virtual A / B устройство)

Загрузочным образ ГКИ обеспечивается Google и должен быть использован для тестирования совместимости ГКИ .

Последняя arm64 android11-5.4 boot.img можно загрузить с ci.android.com в aosp_arm64 сборки артефактов aosp-master филиала.

Последнее arm64 android11-5.4 образ ядра ( Image.gz ) можно загрузить с ci.android.com в kernel_aarch64 сборки артефактов aosp_kernel-common-android11-5.4 отрасли.

Загрузочный раздел производителя

vendor_boot раздел вводятся с ГКО. Это A / B'd с Virtual A / B и состоит из заголовка, виртуального диска поставщика и большого двоичного объекта дерева устройств. RAM-диск поставщика - это архив CPIO, который содержит модули поставщика, необходимые для загрузки устройства. Сюда входят модули для включения критически важных функций SoC, а также драйверы хранилища и дисплея, необходимые для загрузки устройства и отображения экранов-заставок.

Архив CPIO содержит:

  • Первая стадия init поставщика ядра модули расположены в /lib/modules/
  • modprobe конфигурационные файлы находятся в /lib/modules
  • modules.load файл , указывающий модули для загрузки во время первого этапа init

Требование загрузчика

Загрузчик должен загрузить общее электронный диск CPIO изображения (из boot раздела ) в память сразу после CPIO изображений поставщика электронного диска (от vendor_boot раздела ). После декомпрессии в результате получается общий RAM-диск, наложенный поверх файловой структуры RAM-диска поставщика.

Тестирование совместимости с GKI

Для платформы Android 11 устройства, запускаемые с ядром v5.4, должны запускать тесты VTS и CTS-on-GSI с использованием загрузочного образа GKI, предоставленного Google.

Вклад в ядро ​​GKI

Ядро ГКО построено из AOSP общего ядра , начиная с android11-5.4 . Все представленные патчи должны соответствовать этим руководящим принципам взносов , которые документируют две стратегии:

  1. Лучше всего: Сделать все ваши изменения в вышестоящие Linux. Если возможно, сделайте резервную копию стабильных выпусков. Эти исправления автоматически объединяются в соответствующие общие ядра AOSP. Если патч уже находится в исходной версии Linux, опубликуйте резервную копию патча, который соответствует требованиям к патчу, приведенным ниже.
  2. Менее хорошо: Развивайте свои патчи из дерева (из вышестоящего Linux точки зрения). Если патчи фиксируя Android специфичную ошибку, они не очень вряд ли будет принято , если они не были согласованы с kernel-team@android.com .

Для партнеров, реализующих GKI, могут быть веские причины, по которым требуются внеплановые исправления (особенно, если есть планы микросхем, которые необходимо соблюдать). Для этих случаев, подать Buganizer вопрос.

Разместить изменения ГКИ через Геррит к android-mainline ветвям, а затем портированном в другие отрасли высвобождения по мере необходимости.

Исходный код, связанный с загружаемыми модулями, не обязательно должен быть добавлен в дерево исходных текстов ядра GKI, однако настоятельно рекомендуется отправлять все драйверы в вышестоящий Linux.

Запрос резервных копий из основной линии

Как правило, основные патчи, необходимые партнерам GKI, могут быть перенесены в ядра GKI. Загрузить патч к Герриту следуя руководящих принципов взносов .

Если патч был опубликован в апстриме, но еще не принят, рекомендуется дождаться его принятия. Если расписание не позволяет дождаться принятия исправления в восходящем направлении, сообщите об ошибке Buganizer.

Добавление и удаление конфигов GKI

Чтобы запросить добавление или удаление конфигов в arch/arm64/configs/gki_defconfig , подать вопрос Buganizer четко оговаривается просьба и обоснование. Если доступного проекта Buganizer нет, опубликуйте патч с изменением конфигурации в Gerrit и убедитесь, что в сообщении о фиксации четко указана причина, по которой требуется конфигурация.

Изменения конфигурации в замороженных ядрах KMI не должны влиять на KMI.

Изменение кода ядра ядра

Модификации кода ядра в общих ядрах AOSP не приветствуются. Сначала отправьте исправления в вышестоящий Linux, а затем выполните обратный перенос. Если есть веская причина для изменения ядра ядра, сообщите об ошибке Buganizer, четко указав запрос и обоснование. Никакие специфические для Android функции не принимаются без проблем с Buganizer. Отправить по электронной почте kernel-team@android.com если вы не можете создать проблему Buganizer.

Экспорт символов с помощью EXPORT_SYMBOL_GPL ()

Не отправляйте вверх по течению патчи, которые содержат только экспорт символов. Для рассмотрения на входе Linux, дополнения EXPORT_SYMBOL_GPL() требуется модульный драйвер в дерево , которое использует символ, поэтому включить новый драйвер или изменения в существующий драйвер в том же патчсета как экспорт.

При отправке патчей вверх по течению сообщение о фиксации должно содержать четкое обоснование того, почему патч необходим и полезен для сообщества. Включение экспорта в пользу драйверов или функциональности вне дерева не является убедительным аргументом для разработчиков.

Если по какой-то причине патч не может быть отправлен вверх по течению, сообщите об ошибке Buganizer и объясните, почему патч не может быть отправлен вверх по течению. Как правило, символы, которые являются поддерживаемым интерфейсом подсистемы ядра, скорее всего, будут приняты как экспортируемые. Однако случайные внутренние вспомогательные функции вряд ли будут приняты, и вам будет предложено реорганизовать код, чтобы избежать их использования.

Добавление символа в список символов KMI

Списки символов KMI должны быть обновлены символами ядра GKI, используемыми модулями поставщика. Поскольку только символы KMI поддерживаются как стабильные, GKI не позволяет модулям загружаться, если они полагаются на символы, отличные от KMI.

extract_symbols сценарий извлекает соответствующие символы из сборки ядра дерева и может быть использован для обновления списка символов ОГО. Обратитесь к документации символа листинга для получения более подробной информации.