Роберт Лав - Разработка ядра Linux
- Название:Разработка ядра Linux
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2006
- Город:Москва
- ISBN:5-8459-1085-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Роберт Лав - Разработка ядра Linux краткое содержание
В книге детально рассмотрены основные подсистемы и функции ядер Linux серии 2.6, включая особенности построения, реализации и соответствующие программны интерфейсы. Рассмотренные вопросы включают: планирование выполнения процессов, управление временем и таймеры ядра, интерфейс системных вызовов, особенности адресации и управления памятью, страничный кэш, подсистему VFS, механизмы синхронизации, проблемы переносимости и особенности отладки. Автор книги является разработчиком основных подсистем ядра Linux. Ядро рассматривается как с теоретической, так и с прикладной точек зрения, что может привлечь читателей различными интересами и потребностями.
Книга может быть рекомендована как начинающим, так и опытным разработчикам программного обеспечения, а также в качестве дополнительных учебных материалов.
Разработка ядра Linux - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Объекты kobject
группируются в множества, которые называются kset
. Множества kset
представляются с помощью структур данных struct kset
. Эти множества предназначены для двух целей. Во-первых, они позволяют использовать встроенный в них объект kobject
в качестве базового класса для группы других объектов kobject
. Во-вторых, они позволяют объединять вместе несколько связанных между собой объектов kobject
. На файловой системе sysfs объекты kobject
представляются отдельными каталогами файловой системы. Связанные между собой каталоги, например все подкаталоги одного каталога, могут быть включены в одно множество kset
.
Подсистемы соответствуют большим участкам ядра и являются набором множеств kset. Подсистемы представляются с помощью структур struct subsystem
. Все каталоги, которые находятся в корне файловой системы sysfs, соответствуют подсистемам ядра.
На рис. 17.1 показаны взаимоотношения между этими структурами данных.

Рис. 17.1. Взаимоотношения между объектами kobject
, множествами kset
и подсистемами
Управление и манипуляции с объектами kobject
Теперь, когда у нас уже есть представление о внутреннем устройстве объектов kobject
и связанных с ними структурах данных, самое время рассмотреть экспортируемые интерфейсы, которые дают возможность управлять объектами kobject
и выполнять с ними другие манипуляции. В основном, разработчикам драйверов непосредственно не приходится иметь дело с объектами kobject
. Структуры kobject
встраиваются в некоторые специальные структуры данных (как это было в примере структуры устройства посимвольного ввода-вывода) и управляются "за кадром" с помощью соответствующей подсистемы драйверов. Тем не менее, объекты kobject
не всегда могут оставаться невидимыми, иногда с ними приходится иметь дело, как при разработке кода драйверов, так и при разработке кода управления подсистемами ядра.
Первый шаг при работе с объектами kobject
— это их декларация и инициализация. Инициализируются объекты kobject
с помощью функции kobject_init()
, которая определена в файле следующим образом.
void kobject_init(struct kobject *kobj);
Единственным параметром этой функции является объект kobject
, который необходимо проинициализировать. Перед вызовом этой функции область памяти, в которой хранится объект, должна быть заполнена нулевыми значениями. Обычно это делается при инициализации большой структуры данных, в которую встраивается объект kobject
. В других случаях просто необходимо вызвать функцию memset()
.
memset(kobj, 0, sizeof(*kobj));
После заполнения нулями безопасным будет инициализация полей parent
и kset
, как показано в следующем примере.
kobj = kmalloc(sizeof(*kobj), GFP_KERNEL);
if (!kobj)
return -ENOMEM;
memset(kobj, 0, sizeof(*kobj));
kobj->kset = kset;
kobj->parent = parent_kobj;
kobject_init(kobj);
После инициализации необходимо установить имя объекта с помощью функции kobject_set_name()
, которая имеет следующий прототип.
int kobject_set_name(struct kobject* kobj,
const char* fmt, ...);
Эта функция принимает переменное количество параметров, по аналогии с функциями printf()
и printk()
. Как уже было сказано, на имя объекта указывает поле k_name
структуры kobject
. Если это имя достаточно короткое, то оно хранится в статически выделенном массиве name
, поэтому есть смысл без необходимости не указывать длинные имена.
После того как для объекта выделена память и объекту присвоено имя, нужно установить значение его поля kset
, а также опционально поле ktype
. Последнее необходимо делать только в том случае, если множество kset
не предоставляет типа ktype
для данного объекта, в противном случае значение поля ktype
, которое указано в структуре kset
, имеет преимущество. Если интересно, почему объекты kobject
имеют свое поле ktype
, то добро пожаловать в клуб!
Счетчики ссылок
Одно из главных свойств, которое реализуется с помощью объектов kobject
, — это унифицированная система поддержки счетчиков ссылок. После инициализации количество ссылок на объект устанавливается равным единице. Пока значение счетчика ссылок на объект не равно нулю, объект существует в памяти, и говорят, что он захвачен ( pinned , буквально, пришпилен). Любой код, который работает с объектом, вначале должен увеличить значение счетчика ссылок. После того как код закончил работу с объектом, он должен уменьшить значение счетчика ссылок. Увеличение значения счетчика называют захватом ( getting ), уменьшение — освобождением ( putting ) ссылки на объект. Когда значение счетчика становится равным нулю, объект может быть уничтожен, а занимаемая им память освобождена.
Увеличение значения счетчика ссылок выполняется с помощью функции kobject_get()
.
struct kobject* kobject_get(struct kobject *kobj);
Эта функция возвращает указатель на объект kobject
в случае успеха и значение NULL
в случае ошибки.
Уменьшение значения счетчика ссылок выполняется с помощью функции kobject_put()
.
void kobject put(struct kobject *kobj);
Если значение счетчика ссылок объекта, который передается в качестве параметра, становится равным нулю, то вызывается функция, на которую указывает указатель release
поля ktype
этого объекта.
Структуры kref
Внутреннее представление счетчика ссылок выполнено с помощью структуры kref
, которая определена в файле следующим образом.
struct kref {
atomic_t refcount;
};
Единственное поле этой структуры — атомарная переменная, в которой хранится значение счетчика ссылок. Структура используется просто для того, чтобы выполнять проверку типов. Чтобы воспользоваться структурой kref
, необходимо ее инициализировать с помощью функции kref_init()
.
void kref_init(struct kref *kref) {
atomic_set(&kref->refcount, 1);
}
Как видно из определения, эта функция просто инициализирует атомарную переменную тина atomic_t
в значение, равное единице.
Следовательно, структура kref
является захваченной сразу же после инициализации, так же ведут себя и объекты kobject
.
Для того чтобы захватить ссылку на структуру kref
, необходимо использовать функцию kref_get()
.
void kref_get(struct kref *kref) {
WARN_ON(!atomic_read(&kref->refcount));
atomic_inc(&kref->refcount);
}
Эта функция увеличивает значение счетчика ссылок на единицу. Она не возвращает никаких значений. Чтобы освободить ссылку на структуру kref
, необходимо использовать функцию kref_put()
.
Интервал:
Закладка: