Экспортируемые символы

Экспортируемые символы

При загрузке модули динамически компонуются с ядром. Так же как и в случае динамически загружаемых бинарных файлов пространства пользователя, в коде модулей могут вызываться только те функции ядра (основного образа или других модулей), которые явно экспортируются для использования. В ядре экспортирование осуществляется с помощью специальных директив EXPORT_SYMBOL() и EXPORT_SYMBOL_GPL().

Функции, которые экспортируются, доступны для использования модулями. Функции, которые не экспортируются, не могут быть вызваны из модулей. Правила компоновки и вызова функций для модулей значительно более строгие, чем для основного образа ядра. Код ядра может использовать любые интерфейсы ядра (кроме тех, которые определены с ключевым словом static), потому что код ядра компонуется в один выполняемый образ. Экспортируемые символы, конечно, тоже не должны определяться как static.

Набор символов ядра, которые экспортируются, называется экспортируемым интерфейсом ядра или даже (здесь не нужно удивляться) API ядра.

Экспортировать символы просто. После того как функция определена, необходимо вызвать директиву EXPORT_SYMBOL().

/*

* get_pirate_beard_color — возвратить значение цвета бороды текущего

* пирата pirate — это глобальная переменная, доступная из данной

* функции цвета определены в файле <linux/beard_colors.h>

*/

int get_pirate_beard_color(void) {

 return pirate->beard->color;

}

EXPORT_SYMBOL(get_pirate_beard_color);

Допустим, что функция get_pirate_beard_color() объявлена в заголовочном файле и ее может использовать любой модуль.

Некоторые разработчики хотят, чтобы их интерфейсы были доступны только для модулей с лицензией GPL. Такая возможность обеспечивается компоновщиком ядра с помощью макроса MODULE_LICENSE(). Если есть желание, чтобы рассматриваемая функция была доступна только для модулей, которые помеченные как соответствующие лицензии GPL, то экспортировать функцию можно следующим образом.

EXPORT_SYMBOL_GPL(get_pirate_beard_color);

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