Введение
Благодарности
Об авторах
Предисловие
Глава 1. Обзор
1.1 История UNIX
1.2 Стандартные и общие интерфейсы
1.3 Свободное программное обеспечение и открытые исходники
1.4 Краткий обзор дистрибутивов Linux
1.4.1 Debian
1.4.2 Red Hat/Fedora
1.4.3 Mandriva
1.4.4 SUSE
1.4.5 Gentoo
1.4.6 Yellow Dog
1.4.7 Другие дистрибутивы
1.5 Информация о версии ядра
1.6 Linux на PowerPC
1.7 Что такое операционная система
1.8 Организация ядра
1.9 Обзор ядра Linux
1.9.1 Пользовательский интерфейс
1.9.2 Идентификация пользователя
1.9.3 Файлы и файловые системы
1.9.4 Процессы
1.9.5 Системные вызовы
1.9.6 Планировщик Linux
1.9.7 Драйверы устройств Linux
1.10 Переносимость и архитектурные зависимости
Резюме
Упражнения
Глава 2. Исследовательский инструментарий
2.1 Типы данных ядра
2.1.1 Связанные списки
2.1.2 Поиск
2.1.3 Деревья
2.2 Ассемблер
2.2.1 PowerPC
2.2.2 x86
2.3 Пример языка ассемблера
2.3.1 Пример x86,ассемблера
2.3.2 Пример ассемблера PowerPC
2.4 Ассемблерные вставки
2.4.1 Операнды вывода
2.4.2 Операнд ввода
2.4.3 Очищаемые регистры (или список очистки)
2.4.4 Нумерация параметров
2.4.5 Ограничения
2.4.6 asm
2.4.7 __volatile__
2.5 Необычное использование языка C
2.5.1 asmlinkage
2.5.2 UL
2.5.3 inline
2.5.4 const и volatile
2.6 Короткий обзор инструментария для исследования ядра
2.6.1 objdump/readelf
2.6.2 hexdump
2.6.3 nm
2.6.4 objcopy
2.6.5 ar
2.7 Говорит ядро: прослушивание сообщений ядра
2.7.1 printk()
2.7.2 dmesg
2.7.3 /val/log/messages
2.8 Другие особенности
2.8.1 __init
2.8.2 likely() и unlikely()
2.8.3 IS_ERR и PTR_ERR
2.8.4 Последовательности уведомлений
Резюме
Проект Hellomod
Шаг 1: написание каркаса модуля Linux
Шаг 2: компиляция модуля
Шаг 3: запуск кода
Упражнения
Глава 3. Процессы: принципиальная модель выполнения
3.1 Представление нашей программы
3.2 Описатель процесса
3.2.1 Поля, связанные с атрибутами процесса
3.2.2 Поля, связанные с планировщиком
3.2.3 Поля, связанные с отношениями между процессами
3.2.4 Поля, связанные с удостоверением процесса
3.2.5 Поля, связанные с доступными возможностями
3.2.6 Поля, связанные с ограничениями процесса
3.2.7 Поля, связанные с файловой системой и адресным пространством
3.3 Создание процессов: системные вызовы fork(), vfork() и clone()
3.3.1 Функция fork()
3.3.2 Функция vfork()
3.3.3 Функция clone()
3.3.4 Функция do_fork()
3.4 Жизненный цикл процесса
3.4.1 Состояния процесса
3.4.2 Переход между состояниями процесса
3.5 Завершение процесса
3.5.1 Функция sys_exit()
3.5.2 Функция do_exit()
3.5.3 Уведомление родителя и sys_wait4()
3.6 Слежение за процессом: базовые конструкции планировщика
3.6.1 Базовая структура
3.6.2 Пробуждение после ожидания или активация
3.7 Очередь ожидания
3.7.1 Добавление в очередь ожидания
3.7.2 Ожидание события
3.7.3 Пробуждение
3.8 Асинхронный поток выполнения
3.8.1 Исключения
3.8.2 Прерывания
Резюме
Проект: текущая системная переменная
Исходный код процесса
Запуск кода
Упражнения
Глава 4. Управление памятью
4.1 Страницы
4.1.1 flags
4.2 Зоны памяти
4.2.1 Описатель зоны памяти
4.2.2 Вспомогательные функции для работы с зонами памяти
4.3 Фреймы страниц
4.3.1 Функции для затребования страниц фреймов
4.3.2 Функции для освобождения фреймов страниц
4.3.3 Система близнецов (buddy system)
4.4 Выделение секций
4.4.1 Описатель кеша
4.4.2 Описатель кеша общего назначения
4.4.3 Описатель секции
4.5 Жизненный цикл выделителя секции
4.5.1 Глобальные переменные выделителя секции
4.5.2 Создание кеша
4.5.3 Создание секции и cache_grow()
4.5.4 Уничтожение секции: возвращение памяти и kmem_cache_destroy()
4.6 Путь запроса памяти
4.6.1 kmalloc()
4.6.2 kmem_cache_alloc()
4.7 Структуры памяти процесса в Linux
4.7.1 mm_struct
4.7.2 vm_area_struct
4.8 Размещение образа процесса и линейное адресное пространство
4.9 Таблицы страниц
4.10 Ошибка страницы
4.10.1 Исключение ошибки страницы на x86
4.10.2 Обработчик ошибки страницы
4.10.3 Исключение ошибки памяти на PowerPC
Резюме
Проект: отображение памяти процесса
Упражнения
Глава 5. Ввод#Вывод
5.1 Как работает оборудование: шины, мосты, порты и интерфейсы
5.2 Устройства
5.2.1 Обзор блочных устройств
5.2.2 Очереди запросов и планировщик ввода,вывода
5.2.3 Пример: «обобщенное» блочное устройство
5.2.4 Операции с устройством
5.2.5 Обзор символьных устройств
5.2.6 Замечание о сетевых устройствах
5.2.7 Устройства таймера
5.2.8 Терминальные устройства
5.2.9 Прямой доступ к памяти (DMA)
Резюме
Проект: сборка драйвера параллельного порта
Программное обеспечение параллельного порта
Упражнения
Глава 6. Файловые системы
6.1 Общая концепция файловой системы
6.1.1 Файл и имена файлов
6.1.2 Типы файлов
6.1.3 Дополнительные атрибуты файла
6.1.4 Директории и пути к файлам
6.1.5 Файловые операции
6.1.6 Файловые описатели
6.1.7 Блоки диска, разделы и реализация
6.1.8 Производительность
6.2 Виртуальная файловая система Linux
6.2.1 Структуры данных VFS
6.2.2 Глобальные и локальные списки связей
6.3 Структуры, связанные с VFS
6.3.1 Структура fs_struct
6.3.2 Структура files_struct
6.4 Кеш страниц
6.4.1 Структура address_space
6.4.2 Структура buffer_head
6.5 Системные вызовы VFS и слой файловой системы
6.5.1 open()
6.5.2 close()
6.5.3 read()
x Содержание
6.5.4 write()
Резюме
Упражнения
Глава 7. Планировщик и синхронизация ядра
7.1 Планировщик Linux
7.1.1 Выбор следующей задачи
7.1.2 Переключение контекста
7.1.3 Занятие процессора
7.2 Приоритетное прерывание обслуживания
7.2.1 Явное приоритетное прерывание обслуживания в ядре
7.2.2 Неявное пользовательское приоритетное прерывание обслуживания
7.2.2 Неявное приоритетное прерывание обслуживания ядра
7.3 Циклическая блокировка и семафоры
7.4 Системные часы: прошедшее время и таймеры
7.4.1 Часы реального времени: что это такое
7.4.2 Чтение из часов реального времени на PPC
7.4.3 Чтение из часов реального времени на x86
Резюме
Упражнения
Глава 8. Загрузка ядра
8.1 BIOS и Open Firmware
8.2 Загрузчики
8.2.1 GRUB
8.2.2 LILO
8.2.3 PowerPC и Yaboot
8.3 Архитектурно,зависимая инициализация памяти
8.3.1 Аппаратное управление памятью на PowerPC
8.3.2 Управление памятью на x86,аппаратуре
8.3.3 Похожесть кода PowerPC и x86
8.4 Диск начальной загрузки
8.5 Начало: start_kernel()
8.5.1 Вызов lock_kernel()
8.5.2 Вызов page_address_init()
8.5.3 Вызов printk(linux_banner)
8.5.4 Вызов setup_arch
8.5.5 Вызов setup_per_cpu_areas()
8.5.6 Вызов smp_prepare_boot_cpu()
8.5.7 Вызов sched_init()
8.5.8 Вызов build_all_zonelists()
8.5.9 Вызов page_alloc_init
8.5.10 Вызов parse_args()
8.5.11 Вызов trap_init()
8.5.12 Вызов rcu_init()
8.5.13 Вызов init_IRQ()
8.5.14 Вызов softirq_init()
8.5.15 Вызов time_init()
8.5.16 Вызов console_init()
8.5.17 Вызов profile_init()
8.5.18 Вызов local_irq_enable()
8.5.19 Настройка initrd
8.5.20 Вызов mem_init()
8.5.21 Вызов late_time_init()
8.5.22 Вызов calibrate_delay()
8.5.23 Вызов pgtable_cache_init()
8.5.24 Вызов buffer_init()
8.5.25 Вызов security_scafolding_startup()
8.5.26 Вызов vfs_caches_init()
8.5.27 Вызов radix_tree_init()
8.5.28 Вызов signals_init()
8.5.29 Вызов page_writeback_init()
8.5.30 Вызов proc_root_init()
8.5.31 Вызов init_idle()
8.5.32 Вызов rest_init()
8.6 Поток init (или процесс 1)
Резюме
Упражнения
Глава 9. Сборка ядра Linux
9.1 Цепочка инструментов
9.1.1 Компиляторы
9.1.2 Кросскомпиляторы
9.1.3 Компоновщик
9.1.4 Объектные ELF,файлы
9.2 Сборка исходников ядра
9.2.1 Разъяснение исходников
9.2.2 Сборка образа ядра
Резюме
Упражнения
Глава 10. Добавление вашего кода в ядро
10.1 Обход исходников
10.1.1 Познакомимся с файловой системой
10.1.2 Filps и Fops
10.1.3 Пользовательская память и память ядра
10.1.4 Очереди ожидания
10.1.5 Очереди выполнения прерывания
10.1.6 Системные вызовы
10.1.7 Другие типы драйверов
10.1.8 Модель устройства и sysfs
10.2 Написание кода
10.2.1 Основы устройств
10.2.2 Символьное экспортирование
10.2.3 IOCTL
10.2.4 Организация пула и прерывания
10.2.5 Очереди выполнения и тасклеты
10.2.6 Дополнение кода для системного вызова
10.3 Сборка и отладка
10.3.1 Отладка драйвера устройства
Резюме
Упражнения