could not insert module: Unknown symbol — Исправление ошибок modprobe
Архитектура ошибки и симптомы сбоя
Ошибка «Modules: could not insert module: Unknown symbol in module» (сопровождающаяся кодом возврата ENOEXEC / Exec format error в терминале) возникает при попытке загрузить модуль ядра (insmod или modprobe). Она означает, что модуль ссылается на функции или экспортированные переменные ядра (EXPORT_SYMBOL / EXPORT_SYMBOL_GPL), адреса которых отсутствуют в текущей таблице символов /proc/kallsyms запущенного ядра из-за несовпадения версий ядра, отсутствия зависимых модулей или расхождения CRC-хешей символов (Module Versioning / Modversions).
Диагностическая таблица параметров сбоя
| Параметр | Значение | Инженерный смысл сбоя |
|---|---|---|
| Unknown symbol | Unresolved Relocation | Функция или символ ядра не найдены при динамической компоновке в памяти. |
| vermagic | Kernel ABI Signature | Строка сигнатуры версии ядра, компилятора и флагов сборки (SMP, PREEMPT). |
| Module.symvers | Symbol CRC Checksums | База контрольных сумм интерфейсов ядра для валидации совместимости ABI. |
Пошаговое дерево решений и сценарии траблшутинга
Сценарий 1: Проверка точных имен недостающих символов в dmesg
# Просмотр точных имен незарегистрированных символов:
dmesg -T | grep -A 5 -B 2 "Unknown symbol"
# Пример вывода: 'my_driver: Unknown symbol devm_ioremap_resource (err -2)'Сценарий 2: Обновление карты зависимостей модулей (depmod)
Если модуль был скопирован вручную, ядро не знает о его зависимостях:
# Принудительная регенерация карты зависимостей modules.dep:
sudo depmod -a
# Проверка зависимостей конкретного модуля перед загрузкой:
modinfo -F depends module_nameСценарий 3: Сверка vermagic и пересборка модуля через DKMS
Если модуль скомпилирован под другую подверсию ядра или с другими опциями CONFIG:
# Сравнение текущего ядра и vermagic модуля:
uname -r
modinfo module_name.ko | grep vermagic
# Пересборка модуля под текущее работающее ядро через DKMS:
sudo dkms remove module_name/1.0.0 --all
sudo dkms add module_name/1.0.0
sudo dkms build module_name/1.0.0
sudo dkms install module_name/1.0.0ITSTM настроит автоматическую пересборку DKMS-модулей, исправит несовместимости ABI ядра и восстановит работу специфического серверного оборудования.
Частые вопросы (FAQ)
Чем insmod отличается от modprobe при ошибках unknown symbol?
Утилита insmod пытается загрузить бинарный файл .ko напрямую, игнорируя дерево зависимостей. Утилита modprobe считывает файл modules.dep и автоматически загружает все предварительно необходимые родительские модули.
Почему ошибка возникает после частичного обновления системы (apt upgrade)?
Если пакет ядра linux-image обновился, но сервер еще не перезагружен, запущенное ядро ищет символы старой версии, а модули в /lib/modules/ уже заменены файлами от нового ядра.
Что означает флаг CONFIG_MODVERSIONS в ядре?
Флаг MODVERSIONS вычисляет 32-битный CRC-хеш для каждого экспортируемого символа ядра. Если сигнатура функции в ядре изменилась хотя бы на один аргумент, модуль скомпилированный под старый прототип загружен не будет.
Как принудительно найти, какой модуль экспортирует нужный символ?
Используйте файл Module.symvers: grep "имя_символа" /usr/src/linux-headers-$(uname -r)/Module.symvers или проверьте текущие символы ядра: grep "имя_символа" /proc/kallsyms.