Второе издание
Скачать 3.09 Mb.
|
Novell Главный инженер по разработке ядра Группа Ximian Desktop, корпорации Novell Роберт Лав Разработка ядра Linux Второе издание www.williamspublishing.com • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • NOVELL PRESS ;-) РАЗРАБОТЧИКУ • • • • Разработка ядра Linux Второе издание Linux Kernel Development Second Edition Robert Love Novell Press, 800 East 96th Street, Indianapolis, Indiana, 46240 USA Novell ® •• Разработка ядра Linux Второе издание Роберт Лав Москва • Санкт-Петербург • Киев 2006 ББК 32.973.26-018.2.75 Л13 УДК 681.3.07 Издательский дом "Вильямc" Зав. редакцией С.Н. Тригуб Перевод с английского АA. Судакава По общим вопросам обращайтесь в Издательский дом "Вильямс" по адресу: info@williamspubiishing.com, http://www.williamspublishing.com 115419, Москва, а/я 783; 03150, Киев, а/я 152 Лав, Роберт. Л13 Разработка ядра Linux, 2-е издание. : Пер. с англ. — М. : ООО "И.Д. Вильяме" 2006. — 448 с. : ил. — Парал. тит. англ. ISBN 5-8459-1085-4 (рус.) В книге детально рассмотрены основные подсистемы и функции ядер Linux серии 2.6, включая особенности построения, реализации и соответствующие программны интерфейсы. Рассмотренные вопросы включают: планирование выполнения процес сов, управление временем и таймеры ядра, интерфейс системных вызовов, особен ности адресации и управления памятью, страничный кэш, подсистему VFS, механиз мы синхронизации, проблемы переносимости и особенности отладки. Автор книги является разработчиком основных подсистем ядра Linux. Ядро рассматривается как с теоретической, так и с прикладной точек зрения, что может привлечь читателей различными интересами и потребностями. Книга может быть рекомендована как начинающим, так и опытным разработчи кам программного обеспечения, а также в качестве дополнительных учебных мате риалов. ББК 32.973.26-018.2.7 Все названия программных продуктов являются зарегистрированными торговыми марками со ответствующих фирм. Никакая часть настоящего издания ни в каких целях не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами, будь то электронные или механические, включая фотокопирование и запись на магнитный носитель, если на это нет письменного разреше ния издательства Novell Press. Aufhorued translation from the English language edition published by Novell Press, Copyright © 200 by Pearson Education, Inc. All rights reserved. No part of this book shall be reproduced, stored in a retrieval system, or transmi ted by any means, electronic, mechanical, photocopying, recording, or otherwise, without written permi sion from the publisher. All terms mentioned in this book that are known to be trademarks or service marks have been appro[ rialely capitalized. Novell Press cannot attest to the accuracy of this information. Use of a term in this boo should not be regarded as affecting the validity of any trademark or service mark. Russian language edition is published by Williams Publishing House according to the Agreement wit R&I Enterprises International, Copyright © 2006 ISBN 5-S459-10854 (рус.) © Издательский дом "Вильяме", 2006 ISBN 0-Й72-Я2720-1 (англ.) © 2005 by Pearson Education, Inc., 200 Оглавление Предисловие 15 Введение 17 Об авторе 21 От издательства 22 Глава 1. Введение в ядро Linux 23 • Глава 2. Начальные сведения о ядре Linux 33 Глава 3. Управление процессами 45 Глава 4. Планирование выполнения процессов 65 Глава 5. Системные вызовы 95 Глава 6. Прерывания и обработка прерываний 109 Глава 7. Обработка нижних половин и отложенные действия 131 Глава 8. Введение в синхронизацию выполнения кода ядра 163 Глава 9. Средства синхронизации в ядре 177 Глава 10. Таймеры и управление временем 207 Глава 11. Управление памятью 233 Глава 12. Виртуальная файловая система 265 Глава 13. Уровень блочного ввода-вывода 293 Глава 14. Адресное пространство процесса 311 Глава 15. Страничный кэш и обратная запись страниц 331 Глава 16. Модули 343 Глава 17. Объекты kobject и файловая система sysfs 355 Глава 18. Отладка 373 Глава 19. Переносимость 389 Глава 20. Заплаты, разработка и сообщество 405 Приложение А. Связанные списки 415 Приложение Б. Генератор случайных чисел ядра 423 Приложение В. Сложность алгоритмов 429 Приложение Г. Библиография и список литературы 433 Предметный указатель 437 Содержание Предисловие 15 Введение 17 Итак... 18 Версия ядра 18 Читательская аудитория 18 Интернет-ресурс 19 Благодарности ко второму изданию 20 Об авторе 21 От издательства 22 Для читателей 22 Глава 1. Введение в ядро Linux 23 Потом пришел Линус: введение в Linux 25 Обзор операционных систем и ядер 26 Ядро Linux в сравнении с классическими ядрами Unix 29 Версии ядра Linux 31 Сообщество разработчиков ядра Linux 32 Перед тем как начать 32 Глава 2. Начальные сведения о ядре Linux 33 Получение исходного кода ядра 33 Инсталляция исходного кода ядра 33 Использование заплат 34 Дерево исходных кодов ядра 34 Сборка ядра 34 Уменьшение количества выводимых сообщений 37 Параллельная сборка 37 Инсталляция ядра 38 "Зверек другого рода" 38 Отсутствие библиотеки l i b c 39 Компилятор GNU С 39 Отсутствие защиты памяти 41 Нельзя просто использовать вычисления с плавающей точкой 42 Маленький стек фиксированного размера 42 Синхронизация и параллелизм 42 Переносимость — это важно 43 Резюме 43 Глава 3. Управление процессами 45 Дескриптор процесса и структура task structure . 46 6 Содержание Выделение дескриптора процесса 47 Хранениедескрипторапроцесса 48 Состояние процесса 50 Манипулирование текущим состоянием процесса 51 Контекст процесса 51 Дерево семейства процессов 52 Создание нового процесса 53 Копирование при записи 54 Реализация потоков в ядре Linux 57 Потоки в пространстве ядра 59 Завершение процесса . 59 Удаление дескриптора процесса 61 Дилемма "беспризорного" процесса 61 Резюме 63 Глава 4. Планирование выполнения процессов 65 Стратегия планирования 67 Процессы, ограниченные скоростью ввода-вывода и скоростью процессора 67 Приоритет процесса 68 Квант времени 69 Вытеснение процесса . 70 Стратегия планирования в действии 70 Алгоритм планирования 71 Очереди выполнения 72 Массивы приоритетов 74 Пересчет квантов времени 75 Вычисление приоритетов и квантов времени 78 Переход в приостановленное состояние и возврат к выполнению 81 Балансировка нагрузки 83 Вытеснение и переключение контекста 87 Вытеснение пространства пользователя 88 Вытеснение пространства ядра 88 Режим реального времени 89 Системные вызовы для управления планировщиком 91 Системные вызовы, связанные с управлением стратегией и приоритетом 91 Системные вызовы управления процессорной привязкой 92 Передача процессорного времени 92 В завершение о планировщике 93 Глава 5. Системные вызовы 95 API, POSIX и библиотека С 96 Вызовы syscall 97 Номера системных вызовов . 98 Производительность системных вызовов 99 Обработка системных вызовов 99 Определение необходимого системного вызова 99 Передача параметров 100 Реализация системных вызовов 101 Проверка параметров 101 Контекст системного вызова 104 Окончательные шаги регистрации системного вызова 104 Доступ к системным вызовам из пространства пользователя 106 Почему не нужно создавать системные вызовы 107 В заключение о системных вызовах 108 Глава 6. Прерывания и обработка прерываний 109 Прерывания 109 Обработчики прерываний 111 Верхняя и нижняя половины 111 Регистрация обработчика прерывания 112 Освобождение обработчика прерывания 114 Написание обработчика прерывания 115 Совместно используемые обработчики 116 Настоящий обработчик прерывания 117 Контекст прерывания 119 Реализация системы обработки прерываний 121 Управление прерываниями 124 Запрещение и разрешение прерываний 125 Запрещение определенной линии прерывания 126 Состояние системы обработки прерываний 127 Не нужно прерывать, мы почти закончили! 128 Глава 7. Обработка нижних половин и отложенные действия 131 Нижние половины 132 Когда нужно использовать нижние половины 133 Многообразие нижних половин 133 Механизм отложенных прерываний (softirq) 136 Реализация отложенных прерываний 136 Использование отложенных прерываний 139 Тасклеты 141 Реализация тасклетов 141 Использование тасклетов 144 Демон ksoftirqd 146 Старый механизм ВН 148 Очереди отложенных действий 149 Реализация очередей отложенных действий 150 Использование очередей отложенных действий 154 Старый механизм очередей заданий 157 Какие обработчики нижних половин необходимо использовать 157 Блокировки между обработчиками нижних половин 159 Запрещение обработки нижних половин 160 Внизу обработки нижних половин 162 8 Содержание Глава 8. Введение в синхронизацию выполнения кода ядра 163 Критические участки и состояние конкуренции за ресурсы 164 Зачем нужна защита 164 Блокировки 167 Откуда берется параллелизм 169 Что требует защиты 170 Взаимоблокировки 172 Конфликт при захвате блокировки и масштабируемость 174 Блокировки в вашем коде 176 Глава 9. Средства синхронизации в ядре 177 Атомарные операции 177 Целочисленные атомарные операции 178 Битовые атомарные операции 181 Спин-бдокировки 183 Другие средства работы со спин-блокировками 186 Спин-блокировки и обработчики нижних половин 187 Спин-блокировки чтения-записи 188 Семафоры 190 Создание и инициализация семафоров 193 Использование семафоров 193 Семафоры чтения-записи . 195 Сравнение спин-блокировок и семафоров 196 Условные переменные 196 BLK: Большая блокировка ядра 197 Секвентные блокировки 199 Средства запрещения преемптивности 200 Барьеры и порядок выполнения 201 Резюмирование по синхронизации 205 Глава 10. Таймеры и управление временем 207 Информация о времени в ядре 208 Частота импульсов таймера: HZ 209 Идеальное значение параметра HZ 210 Переменная jiffies 213 Внутреннее представление переменной j iffies 214 Переполнение переменной jiffies 215 Пространство пользователя и параметр HZ 217 Аппаратные часы и таймеры 218 Часы реального времени . 218 Системный таймер 218 Обработчик прерываний таймера 219 Абсолютное время 221 Таймеры 223 Использование таймеров 224 Состояния конкуренции, связанные с таймерами 226 Содержание 9 Реализациятаймеров 226 Задержка выполнения 227 Задержка с помощью цикла 227 Короткие задержки 229 Функция schedule_timeout () 230 Время вышло 232 Глава 11. Управление памятью 233 Страницы памяти 233 Зоны 235 Получение страниц памяти 238 Получение страниц заполненных нулями 238 Освобождение страниц 239 Функция kmalloc () 240 Флаги gfp_mask 241 Функция kfгее () 245 Функция vmalloc () 246 Уровень слябового распределителя памяти 248 Устройство слябового распределителя памяти 249 Интерфейс слябового распределителя памяти 252 Пример использования слябового распределителя памяти 254 Статическое выделение памяти в стеке 256 Честная игра со стеком 257 Отображение верхней памяти 257 Постоянное отображение 257 Временное отображение 258 Выделение памяти, связанной с определенным процессором 259 Новый интерфейс percpu 260 Работа с данными, связанными с процессорами, на этапе компиляции 260 Работа с данными, связанными с процессорами, на этапе выполнения 261 Когда лучше использовать данные, связанные с процессорами 263 Какой способ выделения памяти необходимо использовать 264 Глава 12. Виртуальная файловая система 265 Общий интерфейс к файловым системам 266 Уровень обобщенной файловой системы 266 Файловые системы Unix 267 Объекты VFS и их структуры данных 269 Другие объекты подсистемы VFS 270 Объект superblock 270 Операции суперблока 272 Объект inode 274 Операции с файловыми индексами 276 Объект dentry 278 Состояние элементов каталога 280 Кэш объектов dentry 280 Операции с элементами каталогов 281 10 Содержание Объект file 283 Файловые операции 284 Структуры данных, связанные с файловыми системами 288 Структуры данных, связанные с процессом 289 Файловые системы в операционной системе Linux 291 Глава 13. Уровень блочного ввода-вывода 293 Анатомия блочного устройства 294 Буферы и заголовки буферов 295 Структура b i o 298 Сравнение старой и новой реализаций 300 Очереди запросов . 301 Запросы 301 Планировщики ввода-вывода 302 Задачи планировщика ввода-вывода 302 Лифтовой алгоритм Линуса 503 Планировщик ввода-вывода с лимитом по времени 304 Прогнозирующий планировщик ввода-вывода 307 Планировщик ввода-вывода с полностью равноправными очередями 308 Планировщик ввода-вывода noop 309 Выбор планировщика ввода-вывода 309 Резюме 310 Глава 14. Адресное пространство процесса 311 Дескриптор памяти 313 Выделение дескриптора памяти 315 Удаление дескриптора памяти 315 Структура mm_struct и потоки пространства ядра 316 Области памяти 316 Флаги областей VMA 317 Операции с областями VMA 319 Списки и деревья областей памяти 320 Области памяти в реальной жизни 321 Работа с областями памяти 322 Функция find_vma () 323 Функция find_vma_prev () 324 Функция find_VMA_intersection () 324 Функции mmap () и do_mmap (): создание интервала адресов 325 Системный вызов mmap () 326 Функции munmap () и do_munmap (): удаление интервала адресов 327 Системный вызов munmap () 327 Таблицы страниц 327 Заключение 329 Глава 15. Страничный кэш и обратная запись страниц 331 Страничный кэш 332 Объект address_space 332 Содержание 11 Базисное дерево 335 Старая хеш-таблица страниц 336 Буферный кэш 336 Демон pdflush 337 Демоны bdflush и kupdated 339 Предотвращение перегруженности: для чего нужны несколько потоков 339 Коротко о главном 341 Глава 16. Модули 343 Модуль "Hello,Worldl" 343 Сборка модулей 345 Использование дерева каталогов исходных кодов ядра 345 Компиляция вне дерева исходных кодов ядра 347 Инсталляция модулей 347 Генерация зависимостей между модулями 347 Загрузка модулей 348 Управление конфигурационными параметрами 349 Параметры модулей 351 Экспортируемые символы 353 Вокруг модулей 354 Глава 17. Объекты kobject и файловая система sysfs 355 Объекты k o b j e c t 356 Типы ktype 357 Множества объектов k s e t 358 Подсистемы 358 Путаница со структурами 359 Управление и манипуляции с объектами k o b j e c t 360 Счетчики ссылок 361 Структуры kref 362 Файловая система sysfs 363 Добавление и удаление объектов на файловой системе sysfs 365 Добавление файлов на файловой системе sysfs 366 Уровень событий ядра 369 Кратко об объектах kobj e c t и файловой системе sysfs 371 Глава 18. Отладка 373 С чего необходимо начать 373 Дефекты ядра 374 Функция p r i n t k () 375 Устойчивость функции p r i n t k () 375 Уровни вывода сообщений ядра 376 Буфер сообщений ядра 377 Демоны syslogd и klogd 377 Замечание относительно функции p r i n t k () и разработки ядра 378 Сообщения Oops 378 Утилита ksymoops 380 12 Содержание Функция kallsyms 380 Конфигурационные параметры отладки ядра 381 Отладка атомарных операций 38] Генерация ошибок и выдача информации 382 Магическая клавиша SysRq 382 Сага об отладчике ядра 384 Использование отладчика gdb 384 Отладчик kgdb 385 Отладчик kdb 385 Исследование и тестирование системы 385 Использование идентификатора UID в качестве условия 385 Использование условных переменных 386 Использование статистики 386 Ограничение частоты следования событий при отладке 387 Нахождение исполняемых образов с изменениями приводящими к ошибкам 388 Если ничто не помогает — обратитесь к сообществу 388 Глава 19. Переносимость 389 История переносимости Linux 390 Размер машинного слова и типы данных 391 Скрытые типы данных ' 394 Специальные типы данных 394 Типы с явным указанием размера 395 Знак типа данных char 396 Выравнивание данных 396 Как избежать проблем с выравниванием 397 Выравнивание нестандартных типов данных 397 Заполнение структур 398 Порядок следования байтов 399 История терминов big-endian и little-endian 401 Порядок байтов в ядре 401 Таймер 401 Размер страницы памяти 402 Порядок выполнения операций процессором 403 Многопроцессорность, преемптивность и верхняя память 403 Пару слов о переносимости 404 Глава 20. Заплаты, разработка и сообщество 405 Сообщество 405 Стиль написания исходного кода 406 Отступы 406 Фигурные скобки 406 Длинные строки 407 Имена 408 Функции 408 Комментарии 408 Использование директивы typedef 410 Содержание 13 Использование того, что уже есть 410 Никаких директив i f d e f в исходном коде - 410 Инициализация структур 411 Исправление ранее написанного кода 411 Организация команды разработчиков 411 Отправка сообщений об ошибках ' 412 Генерация заплат 412 Представление заплат 413 Заключение 414 Приложение А. Связанные списки 415 Кольцевые связанные списки 416 Перемещение по связанному списку 416 Реализация связанных списков в ядре Linux 417 Структура элемента списка 417 Работа со связанными списками 419 Перемещение по связанным спискам 421 |