Как реализовать раздел модуля GKI

GKI и модули GKI можно обновлять независимо от остальной части раздела, поскольку модули GKI находятся в отдельном динамическом разделе супер-образа под названием system_dlkm. Модули GKI подписываются Google с помощью пары ключей, созданной во время сборки ядра, и совместимы только с той версией GKI, для которой они были созданы. Между GKI и модулями GKI нет стабильности ABI. Чтобы модули правильно загружались во время выполнения, GKI и модули GKI должны быть созданы и обновлены вместе.

Как реализовать поддержку раздела system_dklm

Раздел system_dlkm находится в суперразделе как ещё один динамический раздел. Этот раздел может содержать:

  • Модули ядра, подписанные Google во время сборки
  • depmod объекта

Сборка system_dlkm

Создание system_dlkm похоже на создание других динамических разделов. Чтобы добавить system_dlkm в сборку, выполните следующие действия:

  1. В BoardConfig.mk добавьте следующие записи:

    BOARD_USES_SYSTEM_DLKMIMAGE := true
    BOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE := $(TARGET_RO_FILE_SYSTEM_TYPE)
    TARGET_COPY_OUT_SYSTEM_DLKM := system_dlkm
    
  2. В список разделов добавьте system_dlkm: BOARD_GOOGLE_SYSTEM_DYNAMIC_PARTITIONS_PARTITION_LIST := system_dlkm

  3. Если вы используете устройство с разделами A/B или виртуальными разделами A/B, добавьте в файл device.mk следующую строку:

    AB_OTA_PARTITIONS += system_dlkm
    

Определите модули ядра, которые нужно скопировать в system_dlkm

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

Для Android 13

Укажите в BOARD_SYSTEM_DLKM_SRC папку, содержащую файлы объектов ядра необходимых модулей GKI для устройства, в качестве входных данных для системы сборки, чтобы сгенерировать раздел system_dlkm. Пример:

Укажите исходный код модулей GKI в папке и направьте BOARD_SYSTEM_DLKM_SRC на эту папку. Пример:

  BOARD_SYSTEM_DLKM_SRC := kernel/prebuilts/5.10/arm64/system_dlkm_staging

Во время сборки модули, перечисленные в BOARD_SYSTEM_DLKM_SRC, устанавливаются в $ANDROID_PRODUCT_OUT/system_dlkm.

Android 14

Мы упростили реализацию, используя макросы (BOARD_*_KERNEL_MODULES) для других разделов *_dlkm. Список необходимых модулей GKI для устройства должен быть указан в макросе BOARD_SYSTEM_KERNEL_MODULES. Во время сборки эти модули устанавливаются в $ANDROID_PRODUCT_OUT/system_dlkm. Любой модуль в разделе vendor_dlkm, который зависит от модулей в разделе system_dlkm, создает правильные ссылки в файле modules.dep для раздела vendor_dlkm. Из-за межраздельных зависимостей, представленных modules.dep, при загрузке модуля поставщика любой необходимый модуль GKI загружается автоматически.

Например, чтобы установить все модули GKI в раздел system_dlkm для ядра GKI arm64 5.15 из предварительно созданных объектов, выполните следующие действия:

 BOARD_SYSTEM_KERNEL_MODULES := $(wildcard kernel/prebuilts/5.15/arm64/*.ko)

Как подключить system_dlkm во время выполнения

В зависимости от того, какая файловая система используется в качестве файловой системы, доступной только для чтения, добавьте в файл fstab следующее, чтобы смонтировать раздел system_dlkm во время выполнения:

ext4 как файловая система, доступная только для чтения

  system_dlkm /system_dlkm ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect,avb

erofs как файловая система только для чтения

  system_dlkm /system_dlkm erofs ro wait,logical,first_stage_mount,slotselect,avb

Монтирование разделов и загрузка модулей

Во время first_stage_init раздел system_dlkm монтируется в /system_dlkm как файловая система, доступная только для чтения. После успешного монтирования становятся доступны символические ссылки в /system/lib/modules, указывающие на /system_dlkm/lib/modules.

Затем процесс поставщика, например скрипт .rc, может загрузить модули ядра в порядке, указанном в modules.load. В процессе поставщика для загрузки модулей необходимо использовать символическую ссылку /system/lib/modules. При необходимости процесс поставщика также может загрузить модули позже.

SELinux

Каждый файл в разделе system_dlkm помечен контекстом файла system_dlkm_file. Чтобы загрузить файл модулей GKI в раздел system_dlkm, процессу поставщика, отвечающему за загрузку модулей, требуется sepolicy в домене поставщика.

Например, у домена dlkm_loader, который используется Cuttlefish для загрузки модулей GKI, есть следующие разрешения в файле правил shared/sepolicy/vendor/dlkm_loader.te:

allow dlkm_loader self:capability sys_module;
allow dlkm_loader system_dlkm_file:dir r_dir_perms;
allow dlkm_loader system_dlkm_file:file r_file_perms;
allow dlkm_loader system_dlkm_file:system module_load;

Как проверить раздел system-dlkm

Google предоставляет тестовый случай VTS для GKI, чтобы проверить раздел system_dlkm. Чтобы запустить тест вручную, используйте следующую команду atest:

  atest -c vts_dlkm_partition_test