Думаю, кто читает эту статью, сталкиваются с проблемой драйверов для
внешних устройств, в частности Wi-Fi адаптеров, таких как ALFA, TP-Link и других на
чипсетах RTL. Здесь я опишу принципы компиляции ядер Samsung с использованием
системы сборки Soong для Android-устройств, а также расскажу, как подготовить среду
для компиляции и сборки ядра. Кроме того, я опишу, как скомпилировать внешние модули
ядра aircrack-ng для мобильных устройств.
Предупреждение.
Не рекомендуется собирать и компилировать ядра и их модули в привилегированной
среде, так как это может повредить операционную систему. Также собранные вами
внешние модули могут повредить ядро и вызвать панику ядра, поэтому не рекомендуется
автоматически загружать модули при старте системы. Не обновляйте Android и ядро
вашего мобильного устройства, так как это может привести к полной несовместимости
ядра с внешним модулем. В данной статье процесс прошивки ядра не описывается,
поскольку устройства различаются, и процесс очень часто отличается!
Существует два метода сборки модулей, которые мне известны:
Первый метод не займёт много времени, но может не сработать на вашем
устройстве.Второй метод займет больше времени, потребует навыков и терпения.
Я объясню, в чём суть каждого метода.
Первый способ:
Сборка модуля ядра Linux без точных заголовочных файлов. Минусы этого метода в
большей степени описаны в статье, но я также хочу добавить от себя: даже если
успешно соберать модуль и попытаемся его загрузить, это может завершиться ошибкой:
insmod: ERROR: could not insert module module.ko: Unknown symbol in
module
Эта ошибка указывает на то, что в модуле обнаружены неизвестные символы ядра. Если
они отсутствуют в самом ядре, внешний модуль не сможет их использовать. Скорее всего,
эти символы устарели и больше не используются в коде и модулях ядра. Однако символы
могут оставаться в коде, просто не экспортироваться в процессе сборки ядра. Это можно
исправить, если они не удалены разработчиком, путём изменения конфигурации или
экспорта переменных в рабочую среду, в зависимости от того, каким способом и с
помощью какого инструмента собирается ядро. Этот метод описан Жуковым Андреем в
статье и в книге «Хакерство. Физические атаки с использованием хакерских устройств».
Вывод из первого метода:
Помимо других проблем, может возникнуть трудность с доступностью символов, которые
не были экспортированы при сборке ядра. К его преимуществам относятся: отсутствие
необходимости в исходных кодах оригинального ядра от вендора, точных заголовочных
файлов, а также отсутствие необходимости в компиляции и прошивке ядра.
Второй метод:
Требует конфигурации и сборки ядра, кросс-компиляции внешнего модуля и прошивки
ядра на мобильное устройство. Этот способ позволяет использовать
не экспортированные символы, если они не удалены разработчиком.
Для примера возьмём ядро №1, которое я буду собирать. Здесь рассматриваются два
ядра, поскольку они различаются в процессе сборки ядра и модулей. Первое ядро новое
и использует систему сборки Soong от Google, а второе — устаревшую систему сборки на
основе Make. Второе я собирать не буду, так как у меня на данный момент нет устройства
для его проверки, а о процессе сборки таких ядер уже написано много статей на 4PDA,
Habr и подобных ресурсах. Однако я собирал ядра устройства M127F и могу сказать, что
для него внешний модуль собрать возможно.
https://opensource.samsung.com/uploadSearch?searchValue=A245FXXU5CXE1
Version:5.10.198 Device:Samsung Galaxy A24 Bootloader version:U5 Android
version: 14https://opensource.samsung.com/uploadSearch?searchValue=M127FXXU3CVL2
Version:4.19.111 Device:Samsung Galaxy M12 Bootloader version:U3 Android
version: 13
Этап №1. Подготовка рабочей среды.
Я использую дистрибутив Kali GNU/Linux 2024.4
. Cоветую вам обновить пакеты. После этого создайте рабочую директорию для
сборки в /usr/src/
или любом другом удобном месте. Также рекомендуется увеличить swap до 30 ГБ, если у вас 16 ГБ ОЗУ.
sudo apt update && sudo apt upgrade
mkdir /usr/src/workdir
# Creating swap fileС
sudo fallocate -l 30G /swapfile && sudo chmod 600 /swapfile
sudo mkswap /swapfile && sudo swapon /swapfile
Этап №2. Скачивание и распаковка.
Скачаем в рабочую директорию исходные коды ядра и Toolchain.
Toolchain для ядер Samsung, использующих систему Soong, можно скачать по ссылке: Samsung Toolchains.
Распаковываем архив, в котором находятся инструкции, архивы с исходными кодами README_Kernel.txt
и Kernel.tar.gz
. Остальные файлы, содержащие в названии platform, не нужны.
README_Kernel.txt — инструкция, в которой описаны все этапы сборки,
информация о том, где взять toolchain, а также куда его распаковать.Kernel.tar.gz содержит исходные коды ядра и скрипт сборки, который использует все команды, описанные в инструкции. Обычно скрипт написан на Bash и
содержит в названии слово build. В моем случае это build_kernel.sh.
Распаковываем toolchain. В моем случае это директория, содержащая build_kernel.sh
.

Этап №3. Редактирование скрипта и экспорт переменных среды.
В скрипте build_kernel.sh
встречается строка:
python scripts/gen_build_config.py ...
Это Python-скрипт, который генерирует конфигурацию сборки из входных данных. Иногда
требуется заменить python
на python2
или более новую версию, так как несовместимость может привести к ошибке. В моем случае я заменил на python2.
После вызова Python-скрипта в этом же скрипте можно увидеть строки export...
, задающие переменные среды для Bash-скрипта ./build/build.sh
, который запускается в конце.
Скрипт build.sh
отвечает за сборку ядра и модулей. Если его просмотреть, можно увидеть все возможные переменные среды в виде комментариев с их описанием (см.ScreenShot-№2).
Если собрать ядро без определенных экспортированных переменных, получится
стандартное ядро без неиспользуемых символов.

В build_kernel.sh
добавляем строки (см. ScreenShot-№3):
TRIM_NONLISTED_KMI=0
# Позволяет экспортировать все неиспользуемые
символы.KMI_SYMBOL_LIST_STRICT_MODE=0
# Если установлено в 1, выполняет
строгую проверку символов.DO_NOT_STRIP_MODULES=0
# Если установлено в 1, сохраняет информацию
для отладки в собранных модулях.

Этап №4. Сборка ядра и отслеживание ошибок.
Предоставим файлу скрипта права на исполнение:
sudo chmod +x ./build_kernel.sh
./build_kernel.sh # Start
Запускаем его и внимательно смотрим вывод. Ошибки не всегда выделяются красным
цветом, а многопоточная сборка может привести к тому, что ошибки будут выводится в
потоке, они могут затеряться в выводе.
В выводе могут появляться Warning
— предупреждения, которые обычно некритичны.
Частые ошибки:
Error 137 — Процесс был принудительно остановлен (SIGKILL).
Error 2 — Файл или каталог не найден. Чаще всего возникает из-за отсутствия следующих компонентов: bc, flex, bison.
Ядра Linux чувствительны к условиям и конфигурациям. Любые изменения могут
привести к множеству ошибок. Если столкнулись с проблемой, не стоит менять
конфигурацию ядра, а лучше предоставить ему всё необходимое: toolchain, системные
требования, пакеты.
Также в процессе сборки стоит найти переменные среды (см. ScreenShot-№4). Обычно
они выводятся в начале вывода и выглядят так:
PATH=<Value> LLVM=1 LLVM_IAS=1
Эти переменные понадобятся при сборке внешних модулей.

Этап №5. Сборка внешних модулей ядра.
OUT_DIR/
— каталог с собранным ядром.OUT_DIR/staging/lib/modules/
— промежуточные файлы.OUT_DIR/arch/arm64/boot/Image
— скомпилированное ядро, которое нужно прошить.
Подготовка к сборке внешних модулей.
Для сборки внешнего модуля понадобится:
Директория
OUT_DIR/staging/lib/module/
Копируем её в
основную ОС в/lib/modules/
.Создаём директорию
ExternalModules
(например, в/usr/src/
).
Скачиваем исходные коды внешних модулей в ExternalModules.
Настройка Makefile.
Перейдите в директорию модуля rtl8188eus/.
В Makefile присутствует комментарий: # Platform Related, под ним располагаются переменные (см. ScreenShot №5), эти переменные нужны для того, чтобы выбрать, под какую платформу собрать модуль, чаще это CONFIG_PLATFORM_I386_PC = y, то есть Intel 80386 (также известный как i386 или просто 386), значение этой или похожей переменной нужно изменить на n, то есть если это значение будет n, то ifeq пропустит эту платформу, как раз это и нужно сделать. Здесь мы пропускаем ifeq для того, чтобы экспортировать свои переменные среды, а не те, которые экспортируются в ifeq.

Создание скрипта для сборки и компиляции драйвера.
Для сборки и компиляции создаётся bash скрипт: build_module.sh, в нём прописываются все необходимые переменные среды и утилиты. В Makefile а точнее в ifeq платформы экспортировались такие переменные как: CROSS_COMPILE, KSRC, KVER, MODDESTDIR, STAGINGMODDIR, ARCH, SUBARCH, все они отвечают за то что, будет использоватся в сборке и кросс компиляции драйвера. Также мы добавим свои переменные среды, ибо без них ничего не получится, PATH, LLVM и LLVM_IAS.
Переменные среды использующиеся в сборке и компиляции драйвера.
CROSS_COMPILE - Кросс компилятор.
KSRC (Kernel Source Code) - Путь к исходному коду ядра.
KVER (Kernel Version) - Версия ядра.
MODDESTDIR (пред.Module Distribution Directory) - Каталог в который будут установлены собранные модули.
STAGINGMODDIR (Staging Module Directory) - Директория в которой будут перемещены модули которые находятся в стадии разработки или тестирования.
ARCH (Architecture) - Архитектура устройства под которое будет собран и скомпилирован драйвер.
SUBARCH (Sub Architecture) - Под архитектура под которую будет собран драйвер.
Кастомные перемнные среды использующие в сборке и компиляции ядра.
PATH - это список каталогов, в которых система ищет исполняемые файлы при выполнении команд.
LLVM - Если значение 1 то использует LLVM инструменты вместо gnu.
LLVM_IAS - Если установлено в 1 то использует ассемблер clang вместо GNU as.
touch build_module.sh
chmod +x build_module.sh
nano build_module.sh
Все значения переменных, точнее большая часть берется из вывода процесса сборки и компиляции ядра, также значения могут хранится в скриптах сборки ядра. Параметр -j 2 у make указывает колличество потоков.
#!/bin/bash
make clean
echo ""
export PATH=\
/home/motherfucker/Desktop/MyKernel/kernel/build/build-tools/path/linux-x86:\
/home/motherfucker/Desktop/MyKernel/kernel/prebuilts-master/clang/host/linux-x86/clang-r416183b/bin:\
/home/motherfucker/Desktop/MyKernel/out/target/product/a24/obj/KERNEL_OBJ/kernel-5.10/host_tools
export CROSS_COMPILE="aarch64-linux-gnu-"
export KSRC=/lib/modules/5.10.198-android12-9/build
export KVER=5.10.198-android12-9
export MODDESTDIR=/lib/modules/5.10.198-android12-9/kernel/drivers/net/wireless/
export STAGINGMODDIR=/lib/modules/5.10.198-android12-9/kernel/drivers/staging
export SUBARCH=arm64
export ARCH=arm64
export LLVM=1
export LLVM_IAS=1
make -j 2
Частые ошибки при сборке и компиляции.
Универсального решения проблем здесь нету, ядра и модули ядра очень капризны к сборке, ошибки и проблемы решаются самостоятельно. Обратитесь к ChatGPT или DeepSeek если вы не хотите тратить время на изучение.
Ошибка: cc: not found.
/bin/sh: 1: cc: not found - Некритичная ошибка, говорит о том что cc не найден, скорее всего, его просто нету по путям, указанным в переменных окружения.
Ошибки: Unknown warning option: см. ScreenShotError-№1.
Эти ошибки возникают когда компилятор не знает данных ему флагов, эти модули должны собираться gcc но собираются с помощью clang и он не понимает что это за флаги, просто комментируем их в Makefile.

Ошибка: scripts/mod/modpost: not found см. ScreenShotError-№2.
Может возникать когда вы пересобрали ядро и в процессе оно до конца не собралось или полностью не скомпилировалось.

Ошибки GCC: Error unrecognized argument и Unrecognized command-line option: см. ScreenShotError-№3.
Скорее всего ошибки возникли из-за того, что не экспортировали нужные переменные среды в рабочую среду, или некорректно их экспортировали.

Ошибки: ERROR: modpost: module 8188eu uses symbol kernel_read from namespaceVFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver, but does not import it см. ScreenShotError-№4.
Чтобы исправить ошибку нужно найти используемые символы в исходном коде. Используйте
команду grep для этого, но сначала выполните make clean
,
sudo grep -ir "" ./
Поле того как выполнился grep, откроем найденный файл исходного кода .c
и добавим в него строку кодаMODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
, и так со всеми файлами и символами.

Этап №6. Загружаем внешний модуль .ko aircrack-ng.
Копируем ранее собраный внешний модуль на мобильное устройство, и загружаем в ядро с помошью insmod или modprobe.
Сразу после загрузки модуля в ядро нужно убедится в его работоспособности, выполним
dmesg | tail -50
и внимательно осмотрим вывод на ошибки. Если ошибок нету подключим устройство использующие чипсет aka wifi адаптер для которого мы собирали модуль и попробуем найти новый интерфейс который поддерживает режим монитора с помощью ip a, ifconfig, iwconfig
.
Если все работает и новый интерфейс присутствует то попробуем протестировать его используя wifite
, airodump-ng
. Попробуем поменять режим managment на monitor.
sudo wifite --no-pmkid -i <New-interface>
# start airodump-ng
sudo ifconfig wlan1 up
sudo iwconfig wlan1 mode Monitor
sudo airodump-ng <New-interface>

⚠️ Примечание:
Индикация led может не работать на подключенном устройстве потому что эта функция может быть отключена в собранном модуле. wifite может не работать если вы принудительно не укажете интерфейс с помощью флага -i
.