Символ ядра, помеченный буквой "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)();
Другие вопросы по тегам