Символ ядра, помеченный буквой "T" в /proc/kallsyms, не экспортируется
Условное обозначение machine_power_off
помечен буквой "Т" в /proc/kallsyms
:
$ grep -w machine_power_off /proc/kallsyms
ffffffff8102391b T machine_power_off
Но это не экспортируется. Является ли буква "Т" в каллсимах необходимой и достаточной для экспорта символа? Является ли экспорт необходимым и достаточным для использования в других модулях?
Мой модуль, использующий его, скомпилирован с предупреждением:
WARNING: "machine_power_off" [/path/to/module.ko] undefined!
На хост-машине (3.2.0-4-amd64) я могу загрузить этот модуль, но на VirtualBox (3.16.0-4-amd64) он выдает следующее сообщение:
insmod: ERROR: could not insert module module.ko: Unknown symbol in module
Почему этот модуль загружается в мою хост-систему, а не в VirtualBox?
2 ответа
Марка "Т" в /proc/kallsyms
означает, что символ является глобально видимым и может использоваться в коде другого ядра (например, драйверами, скомпилированными встроенными).
Но для того, чтобы его можно было использовать в коде модуля ядра, необходимо экспортировать символ, используя EXPORT_SYMBOL
или похожие. Список экспортируемых символов ведется отдельно от списка всех символов в ядре.
Экспортированные символы можно найти в файле /lib/modules/<kernel-version>/build/Module.symvers
,
(этот файл должен существовать для возможности сборки модулей ядра против данного ядра).
Чтобы использовать символы ядра, которые являются глобальными, но не экспортируются (например, machine_power_off
символ, который вы упоминаете), вы можете использовать kallsyms_lookup
в коде вашего модуля:
#include <linux/kallsyms.h>
static void (*machine_power_off_p)(void);
machine_power_off_p = (void*) kallsyms_lookup_name("machine_power_off");
Теперь вы можете позвонить machine_power_off
функция через machine_power_off_p
указатель:
(*machine_power_off_p)();