Содержание


Разработка модулей ядра Linux

Часть 28. Система /sys. Обзор

Comments

Серия контента:

Этот контент является частью # из серии # статей: Разработка модулей ядра Linux

Следите за выходом новых статей этой серии.

Этот контент является частью серии:Разработка модулей ядра Linux

Следите за выходом новых статей этой серии.

В предыдущей статье разбиралось, как из кода модуля ядра создать именованные файлы в каталоге /proc, чтобы обеспечить пользователю возможность взаимодействия с модулем. В данной статье мы продолжим изучение того, как для этой же цели использовать каталог /sys. Хотя назначение файловой системы sysfs (иерархия имён в /sys) намного обширнее, но применительно к модулям-драйверам нас интересует только данный аспект использования системы sysfs.

О системе /sys

Одно из главных «нововведений» в ядре, начиная с версии 2.6, — это появление единой унифицированной модели представления устройств в Linux. Основные составляющие данной модели - это файловая система sysfs и дуальный к ней (поддерживаемый ею) пакет пользовательского пространства udev. Модель устройств— это единый механизм для представления устройств и описания их топологии в системе. Декларируется множество преимуществ, которые обусловлены созданием единого представления устройств:

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

Файловая система sysfs возникла первоначально из-за необходимости обеспечивать последовательность действий при динамическом управлении электропитанием (иерархия устройств при включении-выключении) и для поддержки горячего подключения устройств. Но получившаяся в результате модель оказалась более функциональной, чем ожидалось изначально. Сама по себе эта система является весьма сложной и объёмной, и о ней следовало бы написать отдельную книгу. Но в контексте создания модулей ядра нас интересует, в первую очередь, возможность создания интерфейса из модуля к файловым именам в файловой системе /sys. Эта функциональность очень похожа на ту, которая используется модулем для создания файловых имен в подсистеме /proc.

Структура /sys

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

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

   struct cdev { 
      struct kobject           kobj; 
      struct module           *owner; 
      struct file_operations  *ops; 
      ...
   };

Во внешнем представлении в каталоге /sys каждому объекту struct kobject соответствует каталог, что видно и из самого определения структуры:

   struct kobject { 
   ...
      struct kobj_type *ktype;
      struct dentry    *dentry; 
   };

Но это вовсе не означает, что каждый инициализированный объект struct kobject автоматически экспортируется в файловую систему /sys. Для того, чтобы сделать объект видимым в /sys, необходимо вызвать:

int kobject_add( struct kobject *kobj );

Хотя это и не делается в примерах, представленных ниже, так как используемые для регистрации имён в /sys вызовы API (class_create()) высокого уровня берут эту задачу на себя.

Таким образом, объекты struct kobject естественным образом отображаются в каталоги пространства имён /sys, которые увязываются в иерархии. Файловая система sysfs - это дерево каталогов без файлов. А как создать файлы в этих каталогах, в содержимом которых отображаются данные ядра? Каждый объект struct kobject (каталог) содержит (через свой компонент struct kobj_type) массив структур struct attribute.

   struct kobj_type {
   ...
      struct sysfs_ops  *sysfs_ops;
      struct attribute **default_attrs;
   }

Каждая такая структура struct attribute (определенная в <linux/sysfs.h>) и является определением одного файлового имени, содержащегося в рассматриваемом каталоге:

   struct attribute {
   ...
      char   *name        /* имя атрибута-файла */;
      mode_t  mode struct /* права доступа к файлу */;
   }

Показанная там же структура таблицы операций (struct sysfs_ops) содержит два поля — определения функций show() и store(), соответственно, чтения и записи символьного поля данных ядра, отображаемых этим файлом (сами функции и их прототипы показаны в примере ниже).

Этих сведений о sysfs должно быть вполне достаточно для создания интерфейса модуля в пространство имён /sys, но перед тем, как переходить к примеру, остановимся на сходстве и различиях между /proc и /sys в качестве интерфейса для отображения модулем подконтрольных ему данных ядра. Различия систем /proc и /sys складываются, главным образом, на основе негласных соглашений и устоявшихся традиций:

  • информация терминальных имён /proc — комплексная, обычно содержит большие объёмы текстовой информации, иногда это таблицы, и даже с заголовками, проясняющими смысл столбцов таблицы;
  • информацию терминальных имён /sys (атрибутов) рекомендуется оформлять в виде:
    1. простых;
    2. символьных изображений;
    3. представляющих значения, соответствующие скалярным типам данных языка C (int, long, char[]);

Сравним информацию, полученную из систем /proc и /sys:

$ cat /proc/partitions  | head -n5
major minor  #blocks  name
  33     0   10022040 hde
  33     1    3783276 hde1
  33     2          1 hde2
$ cat /sys/devices/audio/dev
14:4
$ cat /sys/bus/serio/devices/serio0/set
2

Как видно, в первом случае - это (потенциально) обширная таблица, с сформированным заголовком, разъясняющим смысл колонок, а во втором — представление целочисленных значений.

Заключение

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


Ресурсы для скачивания


Похожие темы


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux, Open source
ArticleID=840700
ArticleTitle=Разработка модулей ядра Linux: Часть 28. Система /sys. Обзор
publish-date=10162012