Чтение онлайн

ЖАНРЫ

Разработка ядра Linux (Второе издание)
Шрифт:

*/

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

Сердцем модели представления устройств являются объекты kobject, которые представляются с помощью структуры

struct kobject
, определенной в файле
<linux/kobject.h>
. Тип
kobject
аналогичен классу
Object
таких объектно-ориентированных языков программирования, как С# и Java. Этот тип определяет общую функциональность, такую как счетчик ссылок, имя, указатель на родительский объект, что позволяет создавать объектную иерархию.

Структура, с помощью которой реализованы объекты

kobject
, имеет следующий вид.

struct kobject {

 char *k_name;

 char name[KOBJ_NAME_LEN];

 struct kref kref;

 struct list_head entry;

 struct kobject *parent;

 struct kset *kset

 struct kobj_type *ktype;

 struct dentry *dentry;

};

Поле

k_name
содержит указатель на имя объекта. Если длина имени меньше
KOBJ_NAME_LEN
, что сейчас составляет 20 байт, то имя хранится в массиве
name
, a поле
kname
указывает на первый элемент этого массива. Если длина имени больше
KOBJ_NAME_LEN
байт, то динамически выделяется буфер, размер которого достаточен для хранения строки символов имени, имя записывается в этот буфер, а поле
k_name
указывает на него.

Указатель

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

Указатель

dentry
содержит адрес структуры
struct dentry
, которая представляет этот объект в файловой системе sysfs.

Поля

kref
,
ktype
и
kset
указывают на экземпляры структур, которые используются для поддержки объектов
kobject
. Поле
entry
используется совместно с полем
kset
. Сами эти структуры и их использование будут обсуждаться ниже.

Обычно структуры

kobject
встраиваются в другие структуры данных и сами по себе не используются. Например, такая важная структура, как
struct cdev
, имеет поле
kobj
.

/* структура cdev - объект для представления символьных устройств */

struct cdev {

 struct kobject kobj;

 struct module *owner;

 struct file_operations *ops;

 struct list_head list;

 dev_t dev;

 unsigned int count;

};

Когда структуры

kobject
встраиваются в другие структуры данных, то последние получают те стандартизированные возможности, которые обеспечиваются структурами
kobject
. Еще более важно, что структуры, которые содержат в себе объекты
kobject
, становятся частью объектной иерархии. Например, структура
cdev
представляется в объектной иерархии с помощью указателя на родительский объект
cdev->kobj->parent
и списка
cdev->kobj->entry
.

Поделиться с друзьями: