Роберт Лав - Разработка ядра 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().
Интервал:
Закладка: