Почему символ модуля ядра Linux не может быть экспортирован должным образом глобально?

Мы написали несколько модулей ядра и многие с экспортированными символами, которые все работают нормально, за исключением 2 символов (что сбивает с толку). Мы экспортировали их, как и все остальные, но два символа не экспортируются глобально после того, как они вставлены в ядро.

В нашем коде C мы имеем (в wdt.ko):

EXPORT_SYMBOL(WDT_Enable);
EXPORT_SYMBOL(WDT_Disable);

Если мы запустим nm на сгенерированном объекте ядра, они появятся правильно:

nm wdt.ko | grep WDT
00000000 T WDT_Enable
00000000 T WDT_Disable

Это должно означать, что эти символы экспортируются глобально. Как только мы изменим объект ядра:

# insmod wdt.ko
# insmod apphandler.ko
apphandler: Unknown symbol WDT_Enable
apphandler: Unknown symbol WDT_Disable

Если мы посмотрим на каллсимсы:

# cat /proc/kallsyms | grep WDT
c12504dc t WDT_Enable  [wdt]
c12502d8 t WDT_Disable [wdt]

Находясь внутри ядра, они не являются глобальными.

Мы подтвердили, что в ядро ​​вставляется правильный файл и что функции видны в одном модуле, но мы не можем объяснить, почему символы внезапно становятся локальными, а не глобальными, как предлагает nm.

Кто-нибудь знает, где может быть наша ошибка?


person user626201    schedule 26.10.2015    source источник
comment
Глобальная видимость, отображаемая nm и /proc/kallsyms, не означает доступность для других модулей, которая контролируется EXPORT_SYMBOL, см., Например, этот ответ. Кроме того, для того, чтобы символы make, определенные одним модулем, были доступны в другом, одного EXPORT_SYMBOL недостаточно. Вам нужно либо собрать оба модуля в одном каталоге, либо использовать переменную KBUILD_EXTRA_SYMBOLS в make-файле для второго модуля: stackoverflow.com/a/32949236 / 3440745.   -  person Tsyvarev    schedule 26.10.2015
comment
Да, согласен с вашими комментариями, и, как уже упоминалось, все наши другие символы работают. Наш единственный файл C, в котором определялся WDT, не включал файл заголовка ниже. Мы собираем все модули в одном месте, и у нас есть общий шаблон make-файла сборки для каждого из них.   -  person user626201    schedule 26.10.2015


Ответы (1)


Хорошо - вскоре после публикации вопроса мы заметили, что в наших путях включения отсутствует модуль include:

#include <linux/module.h>

Код, казалось, компилировал файл без включения #include, и компилятор не генерировал ошибок или жалоб, но в итоге символы были недоступны для последующих модулей.

После включения файла заголовка указанные выше символы доступны модулям, а ядро ​​может разрешить и выполнить код.

person user626201    schedule 26.10.2015
comment
Добавьте эту информацию в свой вопрос (путем редактирования) вместо того, чтобы публиковать ее в качестве ответа (потому что на самом деле это не ответ). - person Tsyvarev; 26.10.2015
comment
К сожалению, это действительно решило нашу проблему. Я не могу объяснить, почему отсутствие заголовка вызвало эффект, но его включение заставило символы работать так, как рекламируется. Других изменений, кроме #include, не было - person user626201; 26.10.2015
comment
Может сработать из-за дополнительного цикла перекомпиляции. Попробуйте удалить и воспроизвести. - person 0andriy; 26.10.2015
comment
Если эта модификация устраняет проблему, что означают слова but had the above effect? - person Tsyvarev; 26.10.2015
comment
До этого вопроса было много-много-много-много-много циклов перекомпиляции, удаления, восстановления, возврата и т. Д. Вышеупомянутый эффект заключался в том, что символы были недоступны (т.е. ошибка insmod). После #include модуль вставлен правильно и функции были правильно вызваны. - person user626201; 27.10.2015