Экспортировать символы просто. После того как функция определена, необходимо вызвать директиву EXPORT_SYMBOL()
.
/*
* get_pirate_beard_color — возвратить значение цвета бороды текущего
* пирата pirate — это глобальная переменная, доступная из данной
* функции цвета определены в файле
*/
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);
Если код ядра конфигурируется для компиляции в виде модуля, то необходимо гарантировать, что все используемые интерфейсы экспортируются. В противном случае будут возникать ошибки компоновщика и загружаемый модуль не будет работать.
В этой главе были рассмотрены особенности написания, сборки, загрузки и выгрузки модулей ядра. Мы обсудили, что такое модули и каким образом ядро операционной системы Linux, несмотря на то что оно является монолитным, может загружать код динамически. Были также рассмотрены параметры модулей и экспортируемые символы. На примере воображаемого модуля ядра (драйвера устройства) управления удочкой был показан процесс написания модуля и процесс добавления к нему различных возможностей, таких как внешние параметры.
В следующей главе будут рассмотрены объекты kobject
и файловая система sysfs, которые являются основным интерфейсом к драйверам устройств и, следовательно, к модулям ядра.
Глава 17
Объекты kobject и файловая система sysfs
Унифицированная модель представления устройств — это существенно новая особенность, которая появилась в ядрах серии 2.6. Модель устройств — это единый механизм для представления устройств и описания их топологии в системе. Использование единого представления устройств позволяет получить следующие преимущества.
• Уменьшается дублирование кода.
• Используется механизм для выполнения общих, часто встречающихся функций, таких как счетчики использования.
• Появляется возможность систематизации всех устройств в системе, возможность просмотра состояний устройств и определения, к какой шине то или другое устройство подключено.
• Появляется возможность генерации полной и корректной информации о древовидной структуре всех устройств в системе, включая все шины и соединения.
• Обеспечивается возможность связывания устройств с их драйверами и наоборот.
• Появляется возможность разделения устройств на категории в соответствии с различными классификациями, таких как устройства ввода, без знания физической топологии устройств.
• Обеспечивается возможность просмотра иерархии устройств от листьев к корню и выключения питания устройств в правильном порядке.
Последний пункт был самой первой мотивацией необходимости создания общей модели представления устройств. Для того чтобы реализовать интеллектуальное управление электропитанием в ядре, необходимо построить дерево, которое представляет топологию устройств в системе. Для выключения питания устройств, которые организованы в виде древовидной топологии, ориентированной сверху вниз, ядро должно выключить питание нижних узлов (листьев) перед выключением питания верхних узлов. Например, ядро должно выключить питание USB-мыши перед тем, как выключать питание контроллера шины USB, а питание контроллера шины USB должно быть выключено перед выключением питания шины PCI. Чтобы делать это эффективно и правильно для всей системы, ядру необходимо отслеживать топологию дерева всех устройств в системе.
Сердцем модели представления устройств являются объекты kobject , которые представляются с помощью структуры struct kobject
, определенной в файле . Тип kobject
аналогичен классу Object
таких объектно-ориентированных языков программирования, как С# и Java. Этот тип определяет общую функциональность, такую как счетчик ссылок, имя, указатель на родительский объект, что позволяет создавать объектную иерархию.
Читать дальше