We detected you are likely not from a Russian-speaking region. Would you like to switch to the international version of the site?

  Назад к списку статей

Разработка и отладка пользовательских ядровых модулей Linux прямо в Termux с использованием clang/llvm

Termux — удобная среда для разработки на Android, но при попытке «собрать модуль ядра прямо в телефоне» важно сразу правильно расставить ожидания. В строгом смысле пользовательские ядровые модули — это объекты, которые должен загружать Linux-кernel. Termux не является полноценной заменой kernel-окружению, однако разработку (и часто — сборку) можно организовать прямо в Termux: подготовить toolchain на базе clang/llvm, получить корректные исходники kernel (или нужные заголовки), собрать модуль и затем отладить его в целевой среде, где действительно выполняется Linux с соответствующим kernel.

В этой статье рассмотрим безопасный, легальный и практичный подход: сборка модуля в Termux с использованием clang/llvm и последующая отладка в целевом Linux (например, в виртуальной машине или на отдельной dev-платформе), при этом вы минимизируете «магические» действия и повышаете воспроизводимость.

Ключевая идея: чем Termux полезен

Termux позволяет:

  • подготовить toolchain clang/llvm;
  • собрать модуль с использованием Makefile ядра;
  • упаковать артефакты и перенести их на target;
  • использовать средства диагностики сборки и логов;
  • организовать обмен файлами и логами (локальная сеть через VPN на случай изолированных сетей — только для создания локальной сети).

Ограничения:

  • Termux работает поверх Android/Linux-ABI, но не заменяет ваш целевой kernel;
  • загрузка .ko требует поддержки и прав в целевой системе;
  • в большинстве случаев необходимы заголовки и конфигурация ядра той системы, где модуль будет загружен.

Требования

  • Android-устройство с установленным Termux.
  • Доступ к исходникам ядра Linux нужной версии (или хотя бы корректные kernel headers и .config/эквивалент для сборки).
  • Целевая Linux-среда (VM/плата/десктоп), совпадающая по kernel ABI/настройкам с тем, под что вы собираете.
  • Доступ к модулю: загрузка через insmod / modprobe и просмотр dmesg.
  • Для отладки: gdb/прочие инструменты на стороне target, а также подготовка symbolов (включение CONFIG_DEBUG_INFO в ядре/модуле при необходимости).

Подготовка окружения Termux: clang/llvm и базовые утилиты

Начнем с установки зависимостей в Termux. Уточнение: состав пакетов может отличаться в зависимости от версии репозиториев Termux.

pkg update
pkg install clang lld llvm make git cmake ninja build-essential rsync

Если ваша сборка потребует дополнительных инструментов (например, flex/bison для генерации, bc, perl и т.п.), добавляйте их по факту ошибки сборки.

Далее проверьте доступность toolchain:

clang --version
ld.lld --version
llvm-ar --version

Получение исходников ядра и важность «правильного» kernel

Сборка модуля выполняется не «в вакууме». Важно, чтобы версия и конфигурация ядра на target совпадали (или были совместимы) с тем, что вы используете для сборки. Самые распространенные причины проблем:

  • другая версия kernel;
  • несовместимые опции конфигурации;
  • отсутствие корректных headers;
  • несовпадение архитектуры или ABI.

Рекомендуется брать исходники (или, как минимум, tree для сборки модулей) той же версии, которую вы будете загружать на target.

Пример: клонирование дерева ядра:

git clone https://github.com/torvalds/linux.git linux
cd linux

Далее переключитесь на точный тег/коммит нужной версии:

# пример, уточните под ваш kernel
git checkout v6.6.30

Пример структуры модульного проекта

Предположим, у вас есть небольшой модуль «hello world», который компилируется как .ko. Типовая структура:

my_mod/
  my_mod.c
  Makefile

Исходник: минимальный Linux kernel module

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

static int init my_mod_init(void)
{
    pr_info("my_mod: loaded
");
    return 0;
}

static void exit my_mod_exit(void)
{
    pr_info("my_mod: unloaded
");
}

module_init(my_mod_init);
module_exit(my_mod_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("RybinskLAB");
MODULE_DESCRIPTION("Example module built with clang/llvm");

Makefile для сборки модуля

Для корректной сборки лучше использовать стандартный подход через Makefile ядра:

obj-m += my_mod.o

И запуск сборки будет выглядеть так (см. следующий раздел).

Сборка модуля в Termux через Makefile ядра и clang/llvm

Наиболее надежный путь: использовать target tree ядра как основу для сборки модулей. В Termux вы вызываете make из каталога ядра, а исходник модуля лежит в отдельной директории.

Скопируйте модуль в tree ядра (или используйте out-of-tree сборку с M=). Для наглядности рассмотрим out-of-tree:

mkdir -p ~/build/my_mod
cp -r my_mod ~/build/my_mod/

Теперь из каталога ядра:

cd ~/linux

export ARCH=arm64
export CROSS_COMPILE=
export CC=clang
export LD=ld.lld

make -C . M=$HOME/build/my_mod modules

Важно:

  • Если вы собираете под ту же архитектуру, что и target, ARCH и окружение могут быть иными.
  • Если архитектура отличается, потребуется кросс-компилятор/настройка, и тогда устанавливается соответствующее CROSS_COMPILE (или вы настраиваете clang target appropriately).
  • В реальных проектах часто используют make oldconfig/make defconfig и точную .config, но для модуля ключевое — корректная конфигурация/согласованность символов и ABI.

Проверьте артефакт:

ls -l $HOME/build/my_mod/.ko

Типовые проблемы сборки и как их диагностировать

  • Несовпадение версий kernel: сигнатуры структур/символов отличаются → получите ошибки линковки или несовместимость на загрузке.
  • Нет нужных заголовков/конфигурации: сборка может завершиться ошибками про отсутствующие include или опции.
  • Не тот компилятор/флаги: некоторые опции ядра требуют согласованности clang/LLD и версий toolchain.
  • Неправильный ARCH: модуль соберется, но не загрузится.

Подсказка для диагностики: включайте подробный вывод Make и сохраняйте лог на диск:

make -C . M=$HOME/build/my_mod modules V=1 2>&1 | tee build.log

Перенос модуля на target

После сборки вам нужно загрузить .ko на систему с тем же kernel. Самый практичный вариант — rsync по локальной сети.

Пример: (на стороне target должен быть доступен ssh). Сначала определите IP target:

# на target: ip a
# затем на Termux:
rsync -avz $HOME/build/my_mod/my_mod.ko user@TARGET_IP:/home/user/

Если сеть сложная и вам требуется изолированная локальная инфраструктура, допустимо использовать VPN исключительно для создания локальной сети между устройствами (не как обход блокировок).

Загрузка модуля и просмотр логов

На target выполните:

sudo insmod my_mod.ko
dmesg | tail -n 50

Если модуль уже существует или были предыдущие попытки:

sudo rmmod my_mod
dmesg | tail -n 50

Отладка: от симптома к источнику

Отладка kernel modules обычно строится на комбинации:

  • корректных логов из pr_info/pr_err и dmesg;
  • символов и трассировки ошибок;
  • минимизации модификаций при каждой попытке загрузки;
  • проверки версий и конфигурации kernel.

Отладочные сообщения и быстрые «контрольные точки»

Старайтесь делать отладку воспроизводимой: добавляйте сообщения в ключевые места и проверяйте их на этапе init и перед потенциально опасными участками.

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

static int init my_mod_init(void)
{
    pr_info("my_mod: init enter
");

    / TODO: test logic here */

    pr_info("my_mod: init exit
");
    return 0;
}

static void exit my_mod_exit(void)
{
    pr_info("my_mod: exit
");
}

module_init(my_mod_init);
module_exit(my_mod_exit);

MODULE_LICENSE("GPL");

Если загрузка падает: что проверить в первую очередь

  • Логи: dmesg -T сразу после insmod.
  • Состояние зависимостей: если модуль зависит от других модулей — убедитесь, что они загружены.
  • Совместимость по ABI: типичная причина падений после сборки «на другой машине».
  • Параметры модуля: если используете module_param, проверяйте значения.

Пример сбора более полного контекста:

sudo insmod my_mod.ko 2>/tmp/insmod.err || true
dmesg -T | tail -n 200
cat /tmp/insmod.err

Символы и подготовка к более глубокой отладке

Для продвинутой отладки вам обычно нужен gdb и symbol-пакеты на стороне target. Практически полезно убедиться, что сборка kernel и модуля содержит отладочные символы (обычно это достигается настройками конфигурации ядра).

На стороне target проверьте, что доступны символы:

# зависит от дистрибутива; один из вариантов
uname -r
# и далее — наличие -dbg пакетов или vmlinux с символами

Если ваш проект требует точного соответствия, согласуйте сборку kernel с теми же параметрами, под которые вы тестируете.

Организация процесса разработки в Termux: workflow

  1. Клонируете нужное дерево ядра/подготовленную сборочную директорию.
  2. Поднимаете toolchain clang/llvm в Termux.
  3. Пишете модуль и Makefile out-of-tree.
  4. Собираете модуль через make -C ... M=... modules.
  5. Переносите .ko на target.
  6. Загружаете и проверяете dmesg.
  7. Инкрементально улучшаете код, сохраняя логи сборки и загрузки.

Почему именно clang/llvm: плюсы и нюансы

Использование clang/llvm в ядре может дать:

  • удобство интеграции современных предупреждений;
  • согласованность со многими toolchain-платформами;
  • быстрее цикл разработки за счет предсказуемой среды сборки.

Нюанс: kernel tree может требовать определенной версии clang/LLD. Если на target вы видите несовместимость, попробуйте подобрать версию toolchain ближе к рекомендованной в документации ядра для вашей версии.

Заключение

Разработка и отладка пользовательских ядровых модулей Linux «в Termux» реальна в формате управляемой инженерной цепочки: вы собираете модуль через clang/llvm в Termux, переносите артефакт на целевую Linux-систему и выполняете загрузку/диагностику по логам и параметрам ядра. Ключ к успеху — строгая согласованность версий kernel и понимание того, что загрузка модулей происходит только в среде, где работает соответствующий kernel.

Если вы хотите ускорить цикл разработки, подобрать правильные версии toolchain под ваш kernel и выстроить reproducible workflow под команду — обратитесь в РыбинскЛАБ. Мы поможем с настройкой окружения, сборкой модулей и организацией процесса отладки.

* Текст статьи подготовлен и структурирован с использованием технологий искусственного интеллекта. Проверен и доработан перед публикацией.

Нужна помощь с настройкой Termux, Linux и серверов?

Я оказываю ИТ-услуги: настройка серверов, автоматизация, безопасность, помощь с Linux и инфраструктурой. Материалы сайта — только в ознакомительных и образовательных целях.

Связаться со мной
Поддержать проект