Skip to content

Руководство по разработке модулей ​

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

Модульный механизм KernelSU практически аналогичен механизму Magisk. Если вы знакомы с разработкой модулей Magisk, то разработка модулей KernelSU очень похожа. Представление модулей ниже можно пропустить, достаточно прочитать [различия-с-magisk] (difference-with-magisk.md).

МЕТАМОДУЛЬ ТРЕБУЕТСЯ ТОЛЬКО ДЛЯ МОДИФИКАЦИИ СИСТЕМНЫХ ФАЙЛОВ

KernelSU использует архитектуру метамодулей для монтирования директории system. Только если вашему модулю нужно модифицировать файлы /system (через директорию system), вам необходимо установить метамодуль (например, meta-overlayfs). Другие функции модулей, такие как скрипты, правила sepolicy и system.prop, работают без метамодуля.

WebUI ​

KernelSU modules support displaying interfaces and interacting with users. See the WebUI documentation for additional details.

Конфигурация модулей ​

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

Busybox ​

В комплект поставки KernelSU входит полнофункциональный бинарный файл BusyBox (включая полную поддержку SELinux). Исполняемый файл находится по адресу /data/adb/ksu/bin/busybox. BusyBox от KernelSU поддерживает переключаемый во время работы "ASH Standalone Shell Mode". Этот автономный режим означает, что при запуске в оболочке ash BusyBox каждая команда будет напрямую использовать апплет внутри BusyBox, независимо от того, что задано в качестве PATH. Например, такие команды, как ls, rm, chmod будут НЕ использовать то, что находится в PATH (в случае Android по умолчанию это будут /system/bin/ls, /system/bin/rm и /system/bin/chmod соответственно), а вместо этого будут напрямую вызывать внутренние апплеты BusyBox. Это гарантирует, что скрипты всегда будут выполняться в предсказуемом окружении и всегда будут иметь полный набор команд, независимо от того, на какой версии Android они выполняются. Чтобы заставить команду не использовать BusyBox, необходимо вызвать исполняемый файл с полными путями.

Каждый сценарий оболочки, запущенный в контексте KernelSU, будет выполняться в оболочке BusyBox ash с включенным автономным режимом. Для сторонних разработчиков это касается всех загрузочных скриптов и скриптов установки модулей.

Для тех, кто хочет использовать эту возможность "Автономного режима" вне KernelSU, есть два способа включить ее:

  1. Установите переменной окружения ASH_STANDALONE значение 1
    Пример: ASH_STANDALONE=1 /data/adb/ksu/bin/busybox sh <script>
  2. Переключитесь с помощью параметров командной строки:
    /data/adb/ksu/bin/busybox sh -o standalone <script>

Чтобы убедиться, что все последующие запуски оболочки sh также выполняются в автономном режиме, предпочтительным методом является вариант 1 (и это то, что KernelSU и менеджер KernelSU используют внутри), поскольку переменные окружения наследуются вплоть до дочерних процессов.

отличие от Magisk

BusyBox в KernelSU теперь использует бинарный файл, скомпилированный непосредственно из проекта Magisk. **Поэтому вам не нужно беспокоиться о проблемах совместимости между скриптами BusyBox в Magisk и KernelSU, поскольку они абсолютно одинаковы!

Модули KernelSU ​

Модуль KernelSU - это папка, размещенная в каталоге /data/adb/modules и имеющая следующую структуру:

txt
/data/adb/modules
├── .
├── .
|
├── $MODID                  <--- Папка имеет имя с идентификатором модуля
│   │
│   │      *** Идентификация модуля ***
│   │
│   ├── module.prop         <--- В этом файле хранятся метаданные модуля
│   │
│   │      *** Основное содержимое ***
│   │
│   ├── system              <--- Эта папка будет смонтирована, если skip_mount не существует
│   │   ├── ...
│   │   ├── ...
│   │   └── ...
│   │
│   │      *** Флаги состояния ***
│   │
│   ├── skip_mount          <--- Если он существует, то KernelSU НЕ будет монтировать вашу системную папку
│   ├── disable             <--- Если модуль существует, то он будет отключен
│   ├── remove              <--- Если модуль существует, то при следующей перезагрузке он будет удален
│   │
│   │      *** Необязательные файлы ***
│   │
│   ├── post-fs-data.sh     <--- Этот скрипт будет выполняться в post-fs-data
│   ├── service.sh          <--- Этот скрипт будет выполняться в сервисе late_start
|   ├── uninstall.sh        <--- Этот скрипт будет выполнен, когда KernelSU удалит ваш модуль
│   ├── system.prop         <--- Свойства из этого файла будут загружены в качестве системных свойств программой resetprop
│   ├── sepolicy.rule       <--- Дополнительные пользовательские правила sepolicy
│   │
│   │      *** Автоматически генерируется, НЕЛЬЗЯ создавать или изменять вручную ***
│   │
│   ├── vendor              <--- Символьная ссылка на $MODID/system/vendor
│   ├── product             <--- Символьная ссылка на $MODID/system/product
│   ├── system_ext          <--- Симлинк на $MODID/system/system_ext
│   │
│   │      *** Допускается использование любых дополнительных файлов/папок ***
│   │
│   ├── ...
│   └── ...
|
├── another_module
│   ├── .
│   └── .
├── .
├── .

различия с Magisk

KernelSU не имеет встроенной поддержки Zygisk, поэтому в модуле нет содержимого, связанного с Zygisk. Однако для поддержки модулей Zygisk можно использовать ZygiskNext. В этом случае содержимое модуля Zygisk идентично содержимому, поддерживаемому Magisk.

module.prop ​

module.prop - это конфигурационный файл модуля. В KernelSU, если модуль не содержит этого файла, он не будет распознан как модуль. Формат этого файла следующий:

txt
id=<string>
name=<string>
version=<string>
versionCode=<int>
author=<string>
description=<string>
  • id должно соответствовать данному регулярному выражению: ^[a-zA-Z][a-zA-Z0-9._-]+$
    экс: ✓ a_module, ✓ a.module, ✓ module-101, ✗ a module, ✗ 1_module, ✗ -a-module
    Это уникальный идентификатор вашего модуля. Не следует изменять его после публикации.
  • versionCode должен быть целым. Это используется для сравнения версий
  • Другими, не упомянутыми выше, могут быть любые однострочные строки.
  • Обязательно используйте тип перевода строки UNIX (LF), а не Windows (CR+LF) или Macintosh (CR).

ДИНАМИЧЕСКОЕ ОПИСАНИЕ

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

Сценарии командной оболочки ​

Чтобы понять разницу между post-fs-data.sh и Service.sh, прочитайте раздел Boot Scripts. Для большинства разработчиков модулей service.sh должно быть достаточно, если вам нужно просто запустить загрузочный скрипт.

Во всех скриптах вашего модуля используйте MODDIR=${0%/*} для получения пути к базовому каталогу вашего модуля; НЕ кодируйте жестко путь к вашему модулю в скриптах.

различия с Magisk

С помощью переменной окружения KSU можно определить, выполняется ли сценарий в KernelSU или в Magisk. Если скрипт выполняется в KernelSU, то это значение будет равно true.

каталог system ​

После загрузки системы содержимое этого каталога будет наложено поверх раздела /system. Это означает, что:

ТРЕБОВАНИЕ МЕТАМОДУЛЯ

Директория system монтируется только если у вас установлен метамодуль, предоставляющий функциональность монтирования (например, meta-overlayfs). Метамодуль обрабатывает способ монтирования модулей. См. Руководство по метамодулям для получения дополнительной информации.

  1. Файлы с теми же именами, что и в соответствующем каталоге в системе, будут перезаписаны файлами в этом каталоге.
  2. Папки с теми же именами, что и в соответствующем каталоге в системе, будут объединены с папками в этом каталоге.

Если вы хотите удалить файл или папку в исходном каталоге системы, необходимо создать файл с тем же именем, что и файл/папка, в каталоге модуля с помощью команды mknod filename c 0 0. Таким образом, система overlayfs автоматически "забелит" этот файл, как если бы он был удален (раздел /system при этом фактически не изменится).

Вы также можете объявить в customize.sh переменную с именем REMOVE, содержащую список каталогов для выполнения операций удаления, и KernelSU автоматически выполнит команду mknod <TARGET> c 0 0 в соответствующих каталогах модуля. Например:

sh
REMOVE="
/system/app/YouTube
/system/app/Bloatware
"

В приведенном выше списке будут выполнены команды mknod $MODPATH/system/app/YouTuBe c 0 0 и mknod $MODPATH/system/app/Bloatware c 0 0; при этом /system/app/YouTube и /system/app/Bloatware будут удалены после вступления модуля в силу.

Если вы хотите заменить каталог в системе, то необходимо создать каталог с тем же путем в каталоге модуля, а затем установить для этого каталога атрибут setfattr -n trusted.overlay.opaque -v y <TARGET>. Таким образом, система overlayfs автоматически заменит соответствующий каталог в системе (без изменения раздела /system).

Вы можете объявить в файле customize.sh переменную с именем REPLACE, содержащую список заменяемых каталогов, и KernelSU автоматически выполнит соответствующие операции в каталоге вашего модуля. Например:

REPLACE=" /system/app/YouTube /system/app/Bloatware "

В этом списке будут автоматически созданы каталоги $MODPATH/system/app/YouTube и $MODPATH/system/app/Bloatware, а затем выполнены команды setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/YouTube и setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/Bloatware. После вступления модуля в силу каталоги /system/app/YouTube и /system/app/Bloatware будут заменены на пустые.

различия с Magisk

KernelSU использует архитектуру метамодулей, где монтирование делегируется подключаемым метамодулям. Официальный метамодуль meta-overlayfs использует OverlayFS ядра для бессистемных модификаций, в то время как Magisk использует magic mount (bind mount), встроенный непосредственно в его ядро. Оба достигают одной цели: модификация файлов /system без физического изменения раздела /system. Подход KernelSU обеспечивает большую гибкость и уменьшает поверхность обнаружения.

Если вы заинтересованы в использовании overlayfs, рекомендуется прочитать документацию по overlayfs ядра Linux.

system.prop ​

Этот файл имеет тот же формат, что и build.prop. Каждая строка состоит из [key]=[value].

sepolicy.rule ​

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

Установщик модулей ​

Инсталлятор модуля KernelSU - это модуль KernelSU, упакованный в zip-файл, который может быть прошит в APP-менеджере KernelSU. Простейший установщик модуля KernelSU - это просто модуль KernelSU, упакованный в zip-файл.

txt
module.zip
│
├── customize.sh                       <--- (Необязательно, более подробно позже)
│                                           Этот скрипт будет использоваться в update-binary
├── ...
├── ...  /* Остальные файлы модуля */
│

WARNING

Модуль KernelSU НЕ поддерживается для установки в пользовательское Recovery!!!

Персонализация ​

Если вам необходимо настроить процесс установки модуля, то в качестве опции вы можете создать в программе установки скрипт с именем customize.sh. Этот скрипт будет источником (не исполняться!) сценария установщика модуля после извлечения всех файлов и применения стандартных разрешений и secontext. Это очень удобно, если ваш модуль требует дополнительной настройки в зависимости от ABI устройства, или вам необходимо установить специальные разрешения/секонтекст для некоторых файлов модуля.

Если вы хотите полностью контролировать и настраивать процесс установки, объявите SKIPUNZIP=1 в файле customize.sh, чтобы пропустить все шаги установки по умолчанию. При этом ваш customize.sh будет сам отвечать за установку.

Сценарий customize.sh запускается в оболочке BusyBox ash KernelSU с включенным "Автономным режимом". Доступны следующие переменные и функции:

Переменные ​

  • KSU (bool): переменная, отмечающая, что скрипт выполняется в окружении KernelSU, причем значение этой переменной всегда будет true. Ее можно использовать для различения KernelSU и Magisk.
  • KSU_VER (string): строка версии текущего установленного KernelSU (например, v0.4.0)
  • KSU_VER_CODE (int): код версии текущего установленного KernelSU в пользовательском пространстве (например, 10672)
  • KSU_KERNEL_VER_CODE (int): код версии текущей установленной KernelSU в пространстве ядра (например, 10672)
  • BOOTMODE (bool): в KernelSU всегда должно быть true.
  • MODPATH (path): путь, по которому должны быть установлены файлы ваших модулей
  • TMPDIR (path): место, где вы можете временно хранить файлы
  • ZIPFILE (path): установочный zip-архив вашего модуля
  • ARCH (string): архитектура процессора устройства. Значение: arm, arm64, x86 или x64.
  • IS64BIT (bool): true, если $ARCH имеет значение arm64 или x64.
  • API (int): уровень API (версия Android) устройства (например, 23 для Android 6.0)

WARNING

В KernelSU MAGISK_VER_CODE всегда равен 25200, а MAGISK_VER всегда равен v25.2. Пожалуйста, не используйте эти две переменные для определения того, запущен ли он на KernelSU или нет.

Функции ​

txt
ui_print <msg>
    вывести <msg> на консоль
    Избегайте использования 'echo', так как он не будет отображаться в консоли пользовательского recovery

abort <msg>
    вывести сообщение об ошибке <msg> на консоль и завершить установку
    Избегайте использования команды 'exit', так как в этом случае будут пропущены шаги очистки завершения установки

set_perm <target> <owner> <group> <permission> [context]
    если [context] не задан, то по умолчанию используется "u:object_r:system_file:s0".
    Эта функция является сокращением для следующих команд:
       chown owner.group target
       chmod permission target
       chcon context target

set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission> [context]
    если [context] не задан, то по умолчанию используется "u:object_r:system_file:s0".
    для всех файлов в <directory> будет вызвана команда:
       set_perm file owner group filepermission context
    для всех каталогов в <directory> (включая себя самого), он вызовет:
       set_perm dir owner group dirpermission context

Загрузочные сценарии ​

В KernelSU скрипты делятся на два типа в зависимости от режима их работы: режим post-fs-data и режим late_start service:

  • режим post-fs-data
    • Эта стадия является БЛОКИРУЮЩЕЙ. Процесс загрузки приостанавливается до завершения выполнения или по истечении 10 секунд.
    • Сценарии запускаются до того, как будут смонтированы какие-либо модули. Это позволяет разработчику модулей динамически настраивать свои модули до того, как они будут смонтированы.
    • Этот этап происходит до запуска Zygote, что практически означает, что все в Android
    • ПРЕДУПРЕЖДЕНИЕ: использование setprop приведет к блокировке процесса загрузки! Вместо этого используйте resetprop -n <prop_name> <prop_value>.
    • Запускайте скрипты в этом режиме только в случае необходимости.
  • режим обслуживания late_start
    • Эта стадия является НЕБЛОКИРУЮЩЕЙ. Ваш скрипт выполняется параллельно с остальным процессом загрузки.
    • Это рекомендуемый этап для запуска большинства скриптов.

В KernelSU скрипты запуска делятся на два типа по месту их хранения: общие скрипты и скрипты модулей:

  • Общие скрипты
    • Размещаются в файлах /data/adb/post-fs-data.d или /data/adb/service.d.
    • Выполняется только в том случае, если скрипт установлен как исполняемый (chmod +x script.sh)
    • Скрипты в post-fs-data.d выполняются в режиме post-fs-data, а скрипты в service.d - в режиме late_start service.
    • Модули не должны НЕ добавлять общие скрипты при установке
  • Скрипты модуля
    • Размещаются в отдельной папке модуля
    • Выполняются только в том случае, если модуль включен
    • post-fs-data.sh запускается в режиме post-fs-data, а service.sh - в режиме late_start service.

Все загрузочные скрипты будут выполняться в оболочке BusyBox ash от KernelSU с включенным "Автономным режимом".

Выпускается под лицензией GPL3.