Для отправки события в пространство пользователя код ядра должен вызвать функцию kobject_uevent()
.
int kobject_uevent(struct kobject *kobj,
enum kobject_action action, struct attribute *attr);
Первый параметр указывает объект kobject
, который является источником сигнала. Соответствующее событие ядра будет содержать элемент пути на файловой системе sysfs, связанный с объектом, сгенерировавшим сигнал.
Второй параметр позволяет указать команду или событие , которое описывает сигнал. Сгенерированное событие ядра будет содержать строку, которая соответствует номеру, передаваемому в качестве значения параметра enum kobject_action
. Вместо того чтобы непосредственно передать строку, здесь используется ее номер, который имеет тип перечисления ( enum
). Это дает возможность более строго выполнить проверку типов, изменить соответствие между номером строки и самой строкой в будущем, а также уменьшить количество ошибок и опечаток. Перечисления определены в файле и имеют имена в формате KOBJ_foo
. На момент написания книги были определены следующие события: KOBJ_MOUNT
, KOBJ_UNMOUNT
, KOBJ_ADD
, KOBJ_REMOVE
и КОВJ_CHANGE
. Эти значения отображаются на строки "mount" (монтирование), "unmount" (размонтирование), "add" (добавление), "remove" (удаление) и "change" (изменение) соответственно. Допускается добавление новых значений событий, если существующих значений недостаточно.
Последний параметр — опциональный указатель на структуру attribute
. Этот параметр можно трактовать как дополнительную информацию (payload) о событии. Если только одного значения события недостаточно, то событие может предоставить информацию о том, в каком файле файловой системы sysfs содержатся дополнительные данные.
Рассмотренная функция использует динамическое выделение памяти и поэтому может переходить в состояние ожидания. Существует атомарная версия рассмотренной функции, которая идентична ей по всем, кроме того что при выделении использует флаг GFP_ATOMIC
.
int kobject_uevent_atomic(struct kobject *kobj,
enum kobject_action action, struct attribute *attr);
По возможности необходимо использовать стандартный интерфейс без атомарного выделения памяти. Параметры этих функций и их смысл — идентичны.
Использование объектов kobject
и их атрибутов не только дают возможность описать события в терминах файловой системы sysfs, но и стимулируют создание новых объектов и их атрибутов, которые еще не представлены через файловую систему sysfs.
Обе рассмотренные функции определены в файле lib/kobject_uevent.c
и объявлены в файле .
Кратко об объектах kobject
и файловой системе sysfs
В этой главе рассматривается модель представления устройств, файловая система sysfs, объекты kobject
и уровень событий ядра. Описание материала главы было бы невозможно без рассмотрения родственных вещей: были также описаны множества kset
, подсистемы, атрибуты, типы ktype
и счетчики ссылок kref
. Эти структуры предназначены для использования разными людьми в разных местах. Разработчикам драйверов необходимо только ознакомление с внешними интерфейсами. Большинство подсистем драйверов эффективно скрывают внутренние механизмы использования объектов kobject
и других, близких к ним структур. Понимание основных принципов работы и знание основного назначения интерфейсов, таких как sysfs_create_file()
, является достаточным для разработчиков драйверов. Однако для разработчиков, которые занимаются разработкой основного кода ядра, может потребоваться более детальное понимание принципов функционирования объектов kobject
. Объекты kobject
могут оказаться еще более важными, так как их могут использовать и те разработчики, которые вообще не занимаются разработкой подсистем драйверов!!!
Эта глава — последняя из тех, которые посвящены подсистемам ядра. В следующих главах будут рассмотрены некоторые общие вопросы, которые также могут оказаться важными для разработчиков ядра. Например, основные рекомендации по отладке кода!
Один из самых существенных факторов, который отличает разработку ядра от разработки пользовательских приложений, — это сложность отладки. Отлаживать код ядра сложно, но крайней мере по сравнению с кодом пространства пользователя. Еще больше усугубляет ситуацию тот факт, что ошибка в ядре может привести к катастрофическим последствиям для всей системы.
Успех в освоении приемов отладки ядра и, в конце концов, в разработке ядра вообще, в основном, зависит от опыта и понимания принципов работы операционной системы в целом. Понятно также, что, для того чтобы успешно выполнять отладку ядра, необходимо понимать, как ядро работает. Тем не менее когда-то нужно начать, и в этой главе будут рассмотрены подходы к отладке ядра.
Читать дальше