Поддержка модулей ядра

В общем образе ядра (GKI) может не быть поддержки драйверов, необходимых для монтирования разделов. Чтобы устройство могло подключать разделы и продолжать загрузку, init первого этапа улучшен для загрузки модулей ядра, присутствующих на электронном диске. Диск RAM разделен на общий и диск RAM поставщика. Модули ядра поставщика хранятся на виртуальном диске поставщика. Порядок загрузки модулей ядра можно настроить.

Расположение модуля

Ramdisk – это файловая система для первого этапа init, и для образа recovery/fastbootd на устройствах с A/B и виртуальным A/B. Это файл initramfs, состоящий из двух архивов cpio, которые объединяются загрузчиком. Первый архив cpio, который хранится как ramdisk поставщика в разделе vendor-boot, содержит следующие компоненты:

  • Модули ядра поставщика на первом этапе init, расположенные в каталоге /lib/modules/.
  • Файлы конфигурации modprobe, расположенные в /lib/modules/: modules.dep, modules.softdep, modules.alias, modules.options.
  • Файл modules.load, в котором указано, какие модули нужно загрузить на первом этапе инициализации и в каком порядке, в /lib/modules/.
  • Модули ядра восстановления поставщика для устройств с поддержкой A/B и виртуального A/B в /lib/modules/
  • modules.load.recovery – указывает, какие модули и в каком порядке нужно загрузить для устройств с A/B-обновлениями и виртуальными A/B-обновлениями в /lib/modules.

Второй архив cpio, который поставляется с GKI в качестве ramdisk файла boot.img и применяется поверх первого, содержит first_stage_init и библиотеки, от которых он зависит.

Загрузка модуля на первом этапе инициализации

На первом этапе init считывает файлы конфигурации modprobe из /lib/modules/ на виртуальном диске. Затем он считывает список модулей, указанных в /lib/modules/modules.load (или в случае восстановления – в /lib/modules/modules.load.recovery), и пытается загрузить каждый из этих модулей по порядку, следуя конфигурации, указанной в ранее загруженных файлах. Порядок выполнения может быть изменен, чтобы удовлетворить строгие или мягкие зависимости.

Создание поддержки, инициализация первого этапа

Чтобы указать модули ядра, которые нужно скопировать в файл cpio виртуального диска поставщика, перечислите их в BOARD_VENDOR_RAMDISK_KERNEL_MODULES. Сборка выполняетсяdepmod на этих модулях и помещает полученные файлы конфигурации modprobe в cpio ramdisk поставщика.

В процессе сборки также создается файл modules.load, который сохраняется в vendor ramdisk cpio. По умолчанию он содержит все модули, перечисленные в разделе BOARD_VENDOR_RAMDISK_KERNEL_MODULES. Чтобы переопределить содержимое этого файла, используйте BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD, как показано в следующем примере:

BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD := \
    device/vendor/mydevice-kernel/first.ko \
    device/vendor/mydevice-kernel/second.ko \
    device/vendor/mydevice-kernel/third.ko

Поддержка сборки, полная версия Android

Как и в Android 10 и более ранних версиях, модули ядра, перечисленные в файле BOARD_VENDOR_KERNEL_MODULES, копируются платформой Android в раздел поставщика по адресу /vendor/lib/modules. При сборке платформы depmod выполняется для этих модулей, а выходные файлы depmod копируются в раздел поставщика в то же местоположение. Механизм загрузки модулей ядра из /vendor остался таким же, как и в предыдущих версиях Android. Вы сами решаете, как и когда загружать эти модули, но обычно это делается с помощью init.rcскриптов.

Подстановочные знаки и интегрированные сборки ядра

У поставщиков, которые объединяют сборку ядра устройства со сборкой платформы Android, могут возникнуть проблемы при использовании упомянутых выше макросов BOARD для указания модулей ядра, которые нужно скопировать на устройство. Если поставщик не хочет указывать модули ядра в файлах сборки платформы устройства, он может использовать подстановочный знак ($(wildcard device/vendor/mydevice/*.ko). Обратите внимание, что подстановочный знак не работает в случае встроенной сборки ядра, поскольку при вызове make и развертывании макросов в файлах makefile модули ядра ещё не созданы, поэтому макросы будут пустыми.

Чтобы обойти эту проблему, поставщик может создать в ядре ZIP-архив, содержащий модули ядра, которые будут скопированы в каждый раздел. Укажите путь к этому ZIP-архиву в BOARD_*_KERNEL_MODULES_ARCHIVE, где * – название раздела (например, BOARD_VENDOR_KERNEL_MODULES_ARCHIVE). Платформа Android извлекает этот ZIP-архив в нужное место и запускает depmod в модулях.

В ZIP-архиве модуля ядра должно быть правило сборки, которое позволяет платформе создавать архив при необходимости.

Восстановление

В предыдущих версиях Android модули ядра, необходимые для восстановления, указывались в BOARD_RECOVERY_KERNEL_MODULES. В Android 12 модули ядра, необходимые для восстановления, по-прежнему указываются с помощью этого макроса. Однако модули ядра восстановления копируются в cpio-архив ramdisk поставщика, а не в общий cpio-архив ramdisk. По умолчанию все модули ядра, перечисленные в BOARD_RECOVERY_KERNEL_MODULES, загружаются на первом этапе init. Если вы хотите загрузить только некоторые из этих модулей, укажите их в BOARD_RECOVERY_KERNEL_MODULES_LOAD.

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