567

Драйверы устройств Linux, Третья редакцияdmilvdv.narod.ru/Translate/LDD3/Linux_Device_Drivers_3...Linux, Linux Device Drivers, образы американского

  • Upload
    others

  • View
    86

  • Download
    0

Embed Size (px)

Citation preview

  • Перевод глав

    Драйверы Устройств Linux, 3-я редакция

    V*D*V

  • Оглавление I-1

    Оглавление......................................................................1Драйверы Устройств Linux, Третья Редакция

    ......................................................................2Глава 1, Введение в драйверы устройств

    ................................................................................................................................... 3Роль драйвера устройства

    ................................................................................................................................... 5Строение ядра Linux

    ................................................................................................................................... 7Классы устройств и модулей

    ................................................................................................................................... 9Вопросы безопасности

    ................................................................................................................................... 10Нумерация версий

    ................................................................................................................................... 11Лицензионное соглашение

    ................................................................................................................................... 12Присоединение к сообществу разработчиков ядра Linux

    ................................................................................................................................... 12Обзор книги

    ......................................................................14Глава 2, Сборка и запуск модулей

    ................................................................................................................................... 14Установка вашей тестовой системы

    ................................................................................................................................... 15Модуль Hello World

    ................................................................................................................................... 16Отличия между модулями ядра и приложениями

    ................................................................................................................................... 21Компиляция и загрузка

    ................................................................................................................................... 26Символьная таблица ядра

    ................................................................................................................................... 27Предварительные замечания

    ................................................................................................................................... 28Инициализация и выключение

    ................................................................................................................................... 33Параметры модуля

    ................................................................................................................................... 35Работа в пространстве пользователя

    ................................................................................................................................... 36Краткая справка

    ......................................................................39Глава 3, Символьные драйверы

    ................................................................................................................................... 39Дизайн scull

    ................................................................................................................................... 40Старший и младший номера устройств

    ................................................................................................................................... 46Некоторые важные структуры данных

    ................................................................................................................................... 52Регистрация символьных устройств

    ................................................................................................................................... 54open и release

    ................................................................................................................................... 57Использование памяти в scull

    ................................................................................................................................... 59read и write

    ................................................................................................................................... 66Игра с новым устройством

    ................................................................................................................................... 67Краткая справка

    ......................................................................69Глава 4, Техники отладки

    ................................................................................................................................... 69Поддержка отладки в ядре

    ................................................................................................................................... 71Отладка через печать

  • I-2 Оглавление

    ................................................................................................................................... 78Отладка через запросы

    ................................................................................................................................... 86Отладка наблюдением

    ................................................................................................................................... 88Система отладки неисправностей

    ................................................................................................................................... 94Отладчик и соответствующие инструменты

    ......................................................................101Глава 5, Конкуренция и состояния состязаний

    ................................................................................................................................... 101Ловушки в scull

    ................................................................................................................................... 102Конкуренция и управление ей

    ................................................................................................................................... 104Семафоры и мьютексы

    ................................................................................................................................... 109Завершения

    ................................................................................................................................... 111Спин-блокировки

    ................................................................................................................................... 115Ловушки блокировок

    ................................................................................................................................... 117Альтернативы блокированию

    ................................................................................................................................... 124Краткая справка

    ......................................................................128Глава 6, Расширенные операции символьного драйвера

    ................................................................................................................................... 128ioctl

    ................................................................................................................................... 140Блокирующий Ввод/Вывод

    ................................................................................................................................... 154poll и select

    ................................................................................................................................... 160Асинхронное сообщение

    ................................................................................................................................... 163Произвольный доступ в устройстве

    ................................................................................................................................... 164Контроль доступа к файлу устройства

    ................................................................................................................................... 171Краткая справка

    ......................................................................174Глава 7, Время, задержки и отложенная работа

    ................................................................................................................................... 174Измерение временных промежутков

    ................................................................................................................................... 179Определение текущего времени

    ................................................................................................................................... 181Отложенный запуск

    ................................................................................................................................... 187Таймеры ядра

    ................................................................................................................................... 192Микрозадачи

    ................................................................................................................................... 195Очереди задач

    ................................................................................................................................... 198Краткая справка

    ......................................................................203Глава 8, Выделение памяти

    ................................................................................................................................... 203Как работает kmalloc

    ................................................................................................................................... 207Заготовленные кэши (Lookaside Caches)

    ................................................................................................................................... 211get_free_page и друзья

    ................................................................................................................................... 214vmalloc и друзья

    ................................................................................................................................... 217Копии переменных для каждого процессора

    ................................................................................................................................... 219Получение больших буферов

    ................................................................................................................................... 221Краткая справка

  • Оглавление I-3

    ......................................................................224Глава 9, Взаимодействие с аппаратными средствами

    ................................................................................................................................... 224Порты ввода/вывода и память ввода/вывода

    ................................................................................................................................... 228Использование портов ввода/вывода

    ................................................................................................................................... 233Пример порта ввода/вывода

    ................................................................................................................................... 237Использование памяти ввода/вывода

    ................................................................................................................................... 243Краткая справка

    ......................................................................246Глава 10, Обработка прерываний

    ................................................................................................................................... 247Подготовка параллельного порта

    ................................................................................................................................... 247Установка обработчика прерывания

    ................................................................................................................................... 257Реализация обработчика

    ................................................................................................................................... 262Верхние и нижние половины

    ................................................................................................................................... 266Разделяемые прерывания

    ................................................................................................................................... 269Ввод/вывод, управлемый прерыванием

    ................................................................................................................................... 273Краткая справка

    ......................................................................275Глава 11, Типы данных в ядре

    ................................................................................................................................... 275Использование стандартных типов языка Си

    ................................................................................................................................... 277Определение точного размера элементам данных

    ................................................................................................................................... 277Типы, специфичные для интерфейса

    ................................................................................................................................... 279Другие вопросы переносимости

    ................................................................................................................................... 282Связные списки

    ................................................................................................................................... 286Краткая справка

    ......................................................................288Глава 12, PCI драйверы

    ................................................................................................................................... 288Интерфейс PCI

    ................................................................................................................................... 305Взгляд назад: ISA

    ................................................................................................................................... 307PC/104 и PC/104+

    ................................................................................................................................... 307Другие шины ПК

    ................................................................................................................................... 308SBus

    ................................................................................................................................... 309NuBus

    ................................................................................................................................... 310Внешние шины

    ................................................................................................................................... 310Краткая справка

    ......................................................................312Глава 13, USB драйверы

    ................................................................................................................................... 314Основы USB устройства

    ................................................................................................................................... 318USB и Sysfs

    ................................................................................................................................... 320Блоки запроса USB

    ................................................................................................................................... 331Написание USB драйвера

    ................................................................................................................................... 340USB передачи без Urb-ов

  • I-4 Оглавление

    ................................................................................................................................... 344Краткая справка

    ......................................................................347Глава 14, Модель устройства в Linux

    ................................................................................................................................... 349Kobject-ы, Kset-ы и Subsystem-ы

    ................................................................................................................................... 356Низкоуровневые операции в sysfs

    ................................................................................................................................... 360Генерация события горячего подключения

    ................................................................................................................................... 362Шины, устройства и драйверы

    ................................................................................................................................... 372Классы

    ................................................................................................................................... 376Собираем всё вместе

    ................................................................................................................................... 382Горячее подключение

    ................................................................................................................................... 389Работа со встроенным программным обеспечением

    ................................................................................................................................... 392Краткая справка

    ......................................................................395Глава 15, Отображение памяти и DMA

    ................................................................................................................................... 395Управление памятью в Linux

    ................................................................................................................................... 405Операция устройства mmap

    ................................................................................................................................... 417Выполнение прямого ввода/вывода

    ................................................................................................................................... 423Прямой доступ к памяти

    ................................................................................................................................... 441Краткая справка

    ......................................................................445Глава 16, Блочные драйверы

    ................................................................................................................................... 446Регистрация

    ................................................................................................................................... 452Операции блочного устройства

    ................................................................................................................................... 455Обработка запроса

    ................................................................................................................................... 472Некоторые другие подробности

    ................................................................................................................................... 475Краткая справка

    ......................................................................478Глава 17, Сетевые драйверы

    ................................................................................................................................... 479Каким разработан snull

    ................................................................................................................................... 483Подключение к ядру

    ................................................................................................................................... 486Структура net_device в деталях

    ................................................................................................................................... 495Открытие и закрытие

    ................................................................................................................................... 497Передача пакетов

    ................................................................................................................................... 501Приём пакетов

    ................................................................................................................................... 504Обработчик прерывания

    ................................................................................................................................... 505Уменьшение числа прерываний

    ................................................................................................................................... 508Изменение состояния соединения

    ................................................................................................................................... 509Буферы сокетов

    ................................................................................................................................... 512Разрешение MAC адреса

    ................................................................................................................................... 515Дополнительные команды ioctl

    ................................................................................................................................... 516Статистическая информация

  • Оглавление I-5

    ................................................................................................................................... 517Многоадресность

    ................................................................................................................................... 520Несколько других подробностей

    ................................................................................................................................... 521Краткая справка

    ......................................................................525Глава 18, TTY драйверы

    ................................................................................................................................... 528Небольшой TTY драйвер

    ................................................................................................................................... 532Указатели на функции в tty_driver

    ................................................................................................................................... 538Настройки TTY линии

    ................................................................................................................................... 542ioctl-ы

    ................................................................................................................................... 545Обработка TTY устройствами proc и sysfs

    ................................................................................................................................... 546Структура tty_driver в деталях

    ................................................................................................................................... 547Структура tty_operations в деталях

    ................................................................................................................................... 549Структура tty_struct в деталях

    ................................................................................................................................... 551Краткая справка

    Индекс 553

  • 1 Драйверы устройств Linux, Третья редакция

    Драйверы Устройств Linux, Третья Редакция

    http://lwn.net/Kernel/LDD3/http://oreilly.com/catalog/linuxdrive3/errata/

    ftp://ftp.ora.com/pub/examples/linux/drivers/ftp://ar.linux.it/pub/ldd3/https://github.com/martinezjavier/ldd3/

    Linux Device Drivers, Third Editionby Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman

    Авторское право © 2005, 2001, 1998 O’Reilly Media, Inc. Все права защищены.Напечатано в Соединённых Штатах Америки.

    Опубликовано O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.

    Книги O'Reilly можно приобрести для образования, бизнеса или продажи в рекламных целях.Для большинства книг также доступны Интернет издания (safari.oreilly.com). Для получениядополнительной информации свяжитесь с нашим корпоративным/институциональным отделомпродаж: (800) 998-9938 или [email protected].

    Редактор: Andy OramПроизводственный редактор: Matt HutchinsonУслуги по производству: Octal Publishing, Inc.Разработка обложки: Edie FreedmanРазработка внутреннего оформления: Melanie Wang

    История печати:Февраль 1998: Первая редакция.Июнь 2001: Вторая редакция.Февраль 2005: Третья редакция.

    Nutshell Handbook, логотип Nutshell Handbook и логотип O'Reilly являютсязарегистрированными торговыми марками компании O'Reilly Media, Inc. Обозначения серий оLinux, Linux Device Drivers, образы американского запада и соответствующее оформление книгиявляются товарными знаками компании O'Reilly Media, Inc.

    Многие из обозначений, используемых производителями и продавцами для обозначениясвоих продуктов, заявляются в качестве торговых марок. Если такие обозначения появляютсяв этой книге и O'Reilly Media, Inc. было известно о торговой марке, такие обозначениянапечатаны в верхнем регистре или с заглавной буквы.

    Несмотря на все меры предосторожности, которые были приняты при подготовке этойкниги, издатель и авторы не несут никакой ответственности за ошибки или упущения, или заущерб в результате использования информации, содержащейся в настоящем документе.

    Эта работа лицензируется под лицензией Creative Commons Attribution-NonCommercial-ShareAlike 2.0. Чтобы просмотреть копию данной лицензии, посетите http://creativecommons.org/licenses/by-sa/2.0/ или отправьте письмо по адресу: Creative Commons, 559 Nathan Abbott Way,Stanford, California 94305, USA.

    ISBN: 0-596-00590-3

    http://lwn.net/Kernel/LDD3/http://oreilly.com/catalog/linuxdrive3/errata/https://github.com/martinezjavier/ldd3/mailto:[email protected]://creativecommons.org/licenses/by-sa/2.0/http://creativecommons.org/licenses/by-sa/2.0/

  • 2Глава 1, Введение в драйверы устройств

    Глава 1, Введение в драйверы устройств

    Одно из главных преимуществ свободных операционных систем, таких как Linux, это то, чтоих внутренности открыты для просмотра всем. Эти операционные системы, когда-то тёмная имистическая область, чей код был доступен только небольшому числу программистов, могутбыть теперь легко изучены, поняты и модифицированы кем угодно, если он обладаетнеобходимым уровнем знаний. Linux помог демократизировать операционные системы. ЯдроLinux, тем не менее, представляет собой большой и сложный набор кода, и потенциальныеисследователи ядра нуждаются в точке входа, где они могут обращаться к этому коду небудучи подавленными его сложностью. Часто такую точку входа создают драйверы устройств.

    Драйверам устройств отводится особая роль в ядре Linux. Это прекрасные “чёрные ящики”,которые заставляют специфичную часть оборудования соответствовать строго заданномупрограммному интерфейсу; они полностью скрывают детали того, как работает устройство.Действия пользователя сводятся к выполнению стандартизированных вызовов, которые независят от специфики драйвера; перевод этих вызовов в специфичные для данногоустройства операции, которые исполняются реальным оборудованием, является задачейдрайвера устройства. Этот программный интерфейс таков, что драйверы могут быть собраныотдельно от остальной части ядра и подключены в процессе работы, когда это необходимо.Такая модульность делает драйверы Linux простыми для написания, так что теперь доступнысотни драйверов.

    Есть много причин быть заинтересованным в написании драйверов устройств для Linux.Количество нового оборудования, которое становится доступным (и устаревает!) гарантирует,что создатели драйверов будут заняты в обозримом будущем. Отдельные люди могутнуждаться в знаниях о драйверах, чтобы получить необходимый уровень доступа к устройству,которое представляет для них интерес. Разработчики оборудования, создавая драйвер дляLinux для своей продукции, могут добавить большое и растущее количество пользователейLinux в качестве потенциальных покупателей. А открытая природа системы Linux означает, чтоесли автор драйвера пожелает, исходник драйвера может быть быстро распространён средимиллионов пользователей.

    Эта книга научит вас, как писать ваши собственные драйверы и как исследоватьнеобходимые области ядра. Мы избрали независимый от устройства подход; предлагаемаятехника программирования и интерфейсы представлены, где возможно, без привязки к какому-либо конкретному устройству. Каждый драйвер уникален; как разработчику драйвера, вам

  • 3 Драйверы устройств Linux, Третья редакция

    необходимо хорошо знать работу своего устройства. Но большинство принципов и основныхтехник одинаковы для всех драйверов. Эта книга не может научить вас работать с вашимустройством, но она даст ту необходимую информацию, на основе которой вы сможетесделать ваше устройство рабочим. Поскольку вы учитесь писать драйверы, вы узнаете многовообще о ядре Linux; это может помочь понять вам, как работает ваш компьютер и почему всёпроисходит не так быстро, как вы ожидаете, или выполняется не совсем так, как вы хотите. Мывводим новые идеи постепенно, начиная с очень простых драйверов и основываясь на них;каждое новое понятие сопровождается примером кода, который не нуждается в каком-тоспециальном оборудовании для тестирования.

    В этой главе нет ничего по написанию кода. Тем не менее, мы вводим некоторые основныеконцепции ядра Linux, и позже, когда мы начнём программирование, вы будете рады, чтопознакомились с ними.

    Роль драйвера устройства

    Как программист, вы в состоянии делать свои выборы в своём драйвере и сделатьприемлемый выбор между требуемым временем на программирование и гибкостью результата.Хотя может показаться странным, что мы называем драйвер "гибким", нам нравится это слово,потому что это подчёркивает, что роль драйвера устройства в обеспечении механизма, а неполитики (создании жёстких правил).

    Различие между механизмом и политикой - одна из лучших идей, стоящих за проектом Unix.Большинство проблем программирования в действительности может быть разделено на двечасти: "какие возможности будут обеспечены" (это механизм) и "как эти возможности могутбыть использованы" (это политика, правила). Если две проблемы адресованы разным частямпрограммы, или даже разным программам в целом, программный пакет много легчеразработать и адаптировать к специфическим требованиям.

    Например, управление в Unix графическим дисплеем разделено между X-сервером, которыйзнает оборудование и предлагает унифицированный интерфейс для пользовательскихпрограмм, менеджерами окна и сессий, которые осуществляют индивидуальную политику, незная что-либо об оборудовании. Люди могут использовать тот же оконный менеджер на разномоборудовании и разные пользователи могут запускать разные конфигурации на той же рабочейстанции. Даже полностью различные настольные среды, такие как KDE и GNOME, могутсосуществовать в одной системе. Другим примером является многоуровневая сетеваяструктура TCP/IP: эта операционная система предлагает абстракцию сокета, которая неосуществляет политики в отношении передаваемых данных, в то время как разные серверыуправляют сервисами (и связанными с ними политиками). Более того, сервера, наподобие ftpd,обеспечивают механизм передачи файлов, а пользователи могут использовать любогоклиента, которого пожелают; существуют и клиенты, управляемые через командную строчку ичерез графический интерфейс, и кто угодно может написать новый пользовательскийинтерфейс для передачи файлов.

    Применительно к драйверам используется то же самое разделение механизма и политики.Драйвер дисковода свободен от правил - его задача только показать дискету как непрерывныймассив блоков данных. Более высокие уровни системы обеспечивают правила, такие как, ктоможет иметь доступ к дисководу, можно ли обращаться к нему напрямую или только черезфайловую систему, могут ли пользователи монтировать файловую систему дисковода. Так какразличное окружение обычно нуждается в использовании оборудования разными способами,важно быть по возможности свободными от правил.

  • 4Глава 1, Введение в драйверы устройств

    При написании драйверов программист должен уделить внимание фундаментальнойконцепции: написать код ядра для доступа к оборудованию, но не оказать давление частнымиправилами на пользователя, так как разные пользователи имеют разные потребности. Вашдрайвер должен обеспечивать доступ к оборудованию, оставляя задачи как использоватьоборудование приложениям. Таким образом, драйвер гибок, если обеспечивает доступ коборудованию без ограничений. Иногда, тем не менее, некоторые ограничения должны иметьместо. К примеру, драйвер ввода/вывода может предоставлять только побайтный доступ коборудованию, чтобы избежать написания дополнительного кода, необходимого для передачиотдельных битов.

    Можно также рассматривать драйвер в другой перспективе: это программный слой, которыйнаходится между приложениями и реальным устройством. Эта привилегированная рольдрайвера позволяет программисту драйвера точно выбрать, как устройство должно бытьпредставлено: разные драйверы могут предлагать разные возможности даже для одного и тогоже устройства. Фактически, драйвер должен быть разработан так, чтобы обеспечивать балансмежду разными соображениями. Например, за использование одного устройства могутконкурировать одновременно несколько программ и автор драйвера имеет полную свободурешать, как обслуживать конкурирующие запросы. Вы могли бы сделать распределениепамяти на устройстве независимым от возможностей оборудования или могли бы предложитьпользовательскую библиотеку, чтобы помочь программистам, пишущим приложения, создатьновые правила поверх предложенных простых и так далее. Одно главное соображение -необходимо выбрать между желанием предоставить пользователю максимум возможностей ивременем, которое вы должны затратить на написание драйвера, а также необходимостьюсохранить код максимально простым, чтобы туда на вкрались ошибки.

    "Гибкие" драйверы имеют типичные характеристики. Они включают поддержку синхронных иасинхронных операций, возможность быть открытыми множество раз, возможностьмаксимально полного использования оборудования и отсутствие лишних программных уровней,чтобы оставаться простыми и свободными от ограничивающих операций. Драйверы такогосорта не только работают лучше у конечных пользователей, но также оказываются проще внаписании и сопровождении. Быть свободными от ограничений - общая цель дляразработчиков программного обеспечения.

    Более того, многие драйверы устройств поставляются вместе с пользовательскимипрограммами, чтобы помочь с конфигурированием и доступом к целевому устройству. Такиепрограммы могут быть и простыми утилитами и графическими приложениями. В качествепримера можно привести программу tunelp, которая регулирует работу драйверапараллельного порта, и графическую утилиту cardctl, входящую в состав пакета PCMCIAдрайвера. Часто предоставляются также клиентские библиотеки, которые обеспечиваютвозможности, которые нет необходимости иметь как часть самого драйвера.

    Областью этой книги является ядро, таким образом мы пытаемся не иметь дело спроблемами политик (ограничений) или с пользовательскими программами иливспомогательными библиотеками. Иногда мы говорим о различных ограничениях и какреализовать их поддержку, но мы не будем погружаться в детали о программах, использующихустройство, или ограничений, которые они налагают. Вы должны понимать, однако, чтопользовательские программы являются неотъемлемой частью пакета программногообеспечения и что даже гибкие пакеты распространяются с файлами конфигурации, которыеопределяют поведение по умолчанию для нижележащих механизмов.

  • 5 Драйверы устройств Linux, Третья редакция

    Строение ядра Linux

    В системе Unix несколько параллельных процессов обслуживают разные задачи. Каждыйпроцесс запрашивает системные ресурсы, будь то энергия, память, сетевое подключение, иликакие-то другие ресурсы. Ядро - это большой кусок исполняемого кода, отвечающего заобработку всех таких запросов. Хотя границы между разными задачами ядра не всегда ясноопределены, роль ядра может быть разделена (как показано на Рисунке 1-1) на следующиечасти:

    Рисунок 1-1. Строение ядра Linux

    Управление процессамиЯдро отвечает за создание и уничтожение процессов и обеспечение их взаимодействия свнешним миром (ввод и вывод). Взаимодействие между разными процессами (черезсигналы, каналы или примитивов межпроцессных взаимодействий) является основойобщей функциональности системы и также возложена на ядро. Дополнительно,планировщик, который распределяет время процессора, тоже является частью системыуправления процессами. В общих словах, деятельность процессов управления ядра

  • 6Глава 1, Введение в драйверы устройств

    создаёт абстракцию нескольких процессов поверх одного или нескольких процессоров.

    Управление памятьюПамять компьютера - главный ресурс и способ управления ей особенно важен дляпроизводительности системы. Ядро создаёт виртуальное адресное пространство длякаждого процесса поверх имеющихся ограниченных ресурсов. Разные части ядравзаимодействуют с подсистемой управления памятью через набор функциональныхвызовов, начиная от простой пары malloc/free до много более развитойфункциональности.

    Файловые системыUnix очень сильно связана с концепцией файловой системы; почти всё в Unix может бытьобработано как файл. Ядро строит структурированную файловую систему поверхнеструктурированного оборудования и полученная файловая абстракция интенсивноиспользуется всей системой. В дополнение Linux поддерживает множество типовфайловых систем, то есть различные способы организации данных на физическомносителе. К примеру, диски могут быть отформатированы в стандартной для Linuxфайловой системе ext3, часто используемой файловой системе FAT или некоторыхдругих.

    Управление устройствамиПочти каждая системная операция в конечном счёте связывается с физическимустройством. За исключением процессора, памяти и очень немногих других объектов,каждая операция управления устройством выполняются кодом, специфичным дляданного адресуемого устройства. Этот код называется драйвером устройства. Ядродолжно иметь встроенный драйвер устройства для каждой периферии, существующей всистеме, от жёсткого диска до клавиатуры и ленточного накопителя. Этот аспектфункциональности ядра и является нашим основным интересом в этой книги.

    Сетевое подключениеСетевое подключение должно управляться операционной системой, потому чтобольшинство сетевых операций не зависят от процессов: входящие пакеты - этоасинхронные события. Эти пакеты должны быть собраны, распознаны и распределеныперед тем, как они будут переданы другому процессу для обработки. Система отвечаетза доставку пакетов данных между программой и сетевыми интерфейсами и должнауправлять исполнением программ в зависимости от их сетевой активности.Дополнительно в ядро встроены все задачи маршрутизации и разрешение адресов.

    Загружаемые модули

    Одной из хороших особенностей Linux является способность расширенияфункциональности ядра во время работы. Это означает, что вы можете добавитьфункциональность в ядро (и убрать её), когда система запущена и работает.

    Часть кода, которая может быть добавлена в ядро во время работы, называется модулем.Ядро Linux предлагает поддержку довольно большого числа типов (или классов) модулей,включая, но не ограничиваясь, драйверами устройств. Каждый модуль являетсяподготовленным объектным кодом (не слинкованным для самостоятельной работы), которыйможет быть динамически подключен в работающее ядро программой insmod и отключенпрограммой rmmod.

  • 7 Драйверы устройств Linux, Третья редакция

    Рисунок 1-1 определяет разные классы модулей, отвечающих за специфические задачи -как говорят, модуль принадлежит к определённому классу в зависимости от предлагаемойфункциональности. Картина из модулей, показанная на Рисунке 1-1, охватывает все наиболееважные классы, но далеко не полная, потому что много большая функциональность Linuxмодулизирована.

    Классы устройств и модулей

    Способ видения устройств в Linux разделяется на три фундаментальных типа. Каждыймодуль обычно реализован как один из этих типов и таким образом классифицируется как символьный модуль, блочный модуль, или сетевой модуль. Такое разделение модулейна разные типы или классы не является жёстким; программист может при желании создаватьбольшие модули, содержащие разные драйверы в одном куске кода. Хорошие программисты,тем не менее, обычно создают разные модули для каждой новой функциональности, потомучто декомпозиция является ключом к масштабируемости и расширяемости.

    Этими тремя классами являются:

    Символьные устройстваСимвольное устройство - это такое устройств, к которому можно обращаться как к потокубайтов (так же как к файлу); драйвер символьного устройства отвечает за реализациютакого поведения. Такой драйвер обычно, по крайней мере, поддерживает системныевызовы open, close, read и write. Текстовый экран (/dev/console) и последовательныепорты (/dev/ttyS0 и подобные) являются примерами символьных устройств, так как онихорошо представлены абстракцией потока. Для обращения к символьным устройствамиспользуют узлы (node) файловой системы, такие как /dev/tty1 и /dev/lp0. Единственноеважное отличие между символьными устройствами и обычными файлами - вы всегдаможете двигаться вперед и назад в обычном файле, в то время как большинствосимвольных устройств - это только каналы данных, к которым вы можете обращатьсятолько последовательно. Существуют, однако, символьные устройства, которыевыглядят как области данных, и вы можете двигаться по ним назад и вперёд; к примеру,это обычно используется в грабберах экрана, где приложения могут получать доступ ковсему полученному изображению используя mmap или lseek.

    Блочные устройстваТак же как символьные устройства, блочные устройства доступны через узлы файловойсистемы в директории /dev. Блочное устройство - это устройство (например, диск)который может содержать файловую систему. В большинстве систем Unix блочноеустройство может поддерживать только операции ввода-вывода, которые передают одинили более целых блоков, обычно равных 512 байт (или большей степени числа два).Linux, однако, разрешает приложению читать и писать в блочное устройство, так же как ив символьное устройство - это позволяет передавать любое число байт за раз. Врезультате, блочные и символьные устройства отличаются только способом управленияданными внутри ядра и, соответственно, программным интерфейсом в ядре/драйвере.Как и символьное устройство, каждое блочное устройство доступно через узел файловойсистемы, так что различия между ними не видны пользователю. Блочные драйверыимеют интерфейс для ядра полностью отличный от символьных устройств.

    Сетевые интерфейсыЛюбой сетевой обмен данными делается через интерфейс, то есть устройство, которое в

  • 8Глава 1, Введение в драйверы устройств

    состоянии обменяться данными с другими узлами сети. Обычно, интерфейс - этоаппаратное устройство, но также он может быть чисто программным устройством,наподобие интерфейса loopback (локальное петлевое устройство). Сетевой интерфейсотвечает за отсылку и приём пакетов данных, управляемых подсистемой сети в ядре, беззнания кому предназначены передаваемые пакеты.Многие сетевые соединения (особенно использующие TCP) являются поточно-ориентированными, но сетевые устройства обычно разработаны для передачи и приёмапакетов. Сетевой драйвер ничего не знает об отдельных соединениях; он толькообрабатывает пакеты. Не будучи поточно-ориентированным устройством, сетевойинтерфейс нелегко представить как узел в файловой системе наподобие /dev/tty1. Unixвсё же обеспечивает доступ к интерфейсам через назначение им уникальных имён (такихкак eth0), но это имя не имеет соответствующего элемента в файловой системе. Обменмежду ядром и сетевым устройством сильно отличается от используемого в символьныхи блочных драйверах. Вместо read и write ядро вызывает функции, относящиеся кпередаче пакетов.

    Есть другие пути классификации модулей драйверов, которые по-другому подразделяютустройства. Вообще, некоторые типы драйверов работают с дополнительными наборамифункций ядра для данного типа устройств. К примеру, можно говорить о модуляхуниверсальной последовательной шины (USB), последовательных модулях, модулях SCSI, итак далее. Каждое USB устройство управляется модулем USB, который работает сподсистемой USB, но само устройство представлено в системе или как символьноеустройство (последовательный порт USB, к примеру), или как блочное устройство (USBустройство чтения карт памяти), или как сетевой интерфейс (например, сетевой USBинтерфейс).

    В последнее время в ядро были добавлены другие классы драйверов устройств,включающие драйверы FireWire и I2C. Таким же образом, как они добавили поддержкудрайверов USB и SCSI, разработчики ядра собрали особенности всего класса и передали ихразработчикам драйверов, чтобы избежать двойной работы и ошибок, упростив истабилизировав таким образом процесс написания этих драйверов.

    В дополнение к драйверам устройств в ядре в виде модулей реализованы и другиефункциональные возможности, включающие и аппаратные средства и программноеобеспечение. Общий пример - файловые системы. Тип файловой системы определяет, какорганизована информация на блочном устройстве, чтобы показать дерево файлов идиректорий. Это не драйвер устройства, здесь нет какого-либо устройства, связанного соспособом размещения информации; вместо этого, тип файловой системы - это программныйдрайвер, потому что он отображает структуры данных нижнего уровня на структуры данныхверхнего уровня. Он и является файловой системой, которая определяет, какой длины можетбыть имя файла и какая информация о каждом файле хранится в записи каталога. Модульфайловой системы должен осуществить самый низкий уровень системных вызовов, которыеобращаются к каталогам и файлам, отображая имена файла и пути (так же как другуюинформацию, такую как режимы доступа) к структурам данных, сохранённым в блоках данных.Такой интерфейс полностью независим от фактической передачи данных на и от диска (илидругого носителя), что достигнуто с помощью драйвера блочного устройства.

    Если вы подумаете о том, как сильно система Unix зависит от нижележащей файловойсистемы, то вы поймете, что такое программное понятие жизненно важно дляфункционирования системы. Способность декодировать информацию файловой системыостаётся на самом низком уровне иерархии ядра и имеет предельно важное значение; дажеесли вы напишете блочный драйвер для своего нового CD-ROM, это будет бесполезно, если

  • 9 Драйверы устройств Linux, Третья редакция

    вы не в состоянии выполнить команды ls или cp для данных этого устройства. Linuxподдерживает понятие модуля файловой системы, программный интерфейс которогодекларирует различные операции, которые могут быть выполнены с индексом файловойсистемы (inode), каталогом, файлом и суперблоком. Вряд ли в действительности программиступотребуется написать модуль файловой системы, потому что официальное ядро уже включаеткод для самых важных типов файловых систем.

    Вопросы безопасности

    Безопасность - всё более и более важная проблема в наше время. Мы обсудим связанные сбезопасностью проблемы, поскольку они встречаются в книге повсюду. Однако, естьнесколько общих понятий, которые заслуживают внимания сейчас. Любая проверкабезопасности в системе выполняется кодом ядра. Если у ядра есть бреши в защите, то и усистемы в целом есть бреши. В официально распространяемом ядре только авторизованныйпользователь может загрузить модуль в ядро; системный вызов init_module проверяет,разрешено ли вызывающему процессу загрузить модуль в ядро. Таким образом, когдаработает официальное ядро, только суперпользователь (* Технически, только кто-то сразрешением CAP_SYS_MODULE может выполнить эту операцию. Мы обсуждаем разрешенияв Главе 6 .), или злоумышленник, который смог получить эту привилегию, можетиспользовать мощность привилегированного кода. Когда возможно, авторы драйверов должныизбегать реализации политики безопасности в своем коде. Безопасность - результатограничений, которые часто лучше всего обрабатываются на более высоких уровнях ядра, подуправлением системного администратора. Однако, всегда есть исключения.

    Как автор драйвера устройства, вы должны знать о ситуациях, в которых некоторыеспособы доступа к устройству могли бы неблагоприятно затронуть систему в целом и должныобеспечить адекватный контроль. Например, операции устройства, которые затрагиваютглобальные ресурсы (такие как установка линии прерывания), которые могут повредитьаппаратные средства (загрузку встроенного программного обеспечения, например), или моглибы затронуть других пользователей (таких как установка заданного по умолчанию размераблока на ленточном накопителе), обычно доступны только для достаточно привилегированныхпользователей, и эта проверка должна быть осуществлена в драйвере непосредственно.

    Конечно, авторы драйверов должны также быть внимательными, чтобы избежать внедренияошибок безопасности. Язык программирования Си позволяет легко делать некоторые типыошибок. Много текущих проблем безопасности созданы, например, ошибками переполнениябуфера, когда программист забывает проверять, сколько данных записано в буфер, и данныепродолжают записываться после окончания буфера, поверх совершенно других данных. Такиеошибки могут поставить под угрозу всю систему и их надо избегать. К счастью, обычноотносительно просто избежать этих ошибок в контексте драйвера устройства, в котороминтерфейс для пользователя чётко определен и строго контролируем.

    Стоит иметь в виду и некоторые другие общие идеи безопасности. Любые данные,полученные от пользовательских процессов, должны быть обработаны с большимподозрением; никогда не доверяйте им, пока они не проверены. Будьте внимательны снеинициализированной памятью; любая память, полученная от ядра, должна быть обнуленаили проинициализирована другим способом прежде, чем стать доступной пользовательскомупроцессу или устройству. Иначе, результатом может быть утечка информации (раскрытиеданных, паролей и так далее). Если ваше устройство обрабатывает данные, посланные в него,убедитесь, что пользователь не может послать ничего, что могло бы поставить под угрозусистему. Наконец, думайте о возможном эффекте операций устройства; если естьопределённые операции (например, перезагрузка встроенного программного обеспечения на

    128

  • 10Глава 1, Введение в драйверы устройств

    плате адаптера или форматирование диска), которые могли бы затронуть систему, этиоперации должны почти наверняка быть разрешены только привилегированнымпользователям.

    Будьте внимательны также, получая программное обеспечение от третьих лиц, особеннокогда затрагивается ядро: потому что любой имеет доступ к исходному тексту, любой можетсломать и перекомпилировать части. Хотя вы можете обычно доверять предварительнооткомпилированным ядрам в ваших дистрибутивах, вы должны избегать запуска ядра,откомпилированного незнакомыми людьми - если вы избегаете запуска предварительнооткомпилированного ядра как root, тогда вам лучше не запускать откомпилированное ядро.Например, злонамеренно изменённое ядро могло бы позволить любому загружать модуль,открывая таким образом неожиданную лазейку через init_module. Заметьте, что ядро Linuxможет быть откомпилировано так, чтобы вообще не поддерживать модули, закрывая такимобразом любые связанные с модулем бреши в защите. Конечно, в этом случае всенеобходимые драйверы должны быть встроены непосредственно в само ядро. Отключениезагрузки модулей ядра после начальной загрузки системы через соответствующий механизмстало возможно для версий, начиная с 2.2.

    Нумерация версий

    Прежде, чем углубиться в программирование, мы должны прокомментировать схемунумерации версий, используемую в Linux, и какие версии охвачены этой книгой. Прежде всего,отметьте, что у каждого пакета программ, используемого в системе Linux, есть свойсобственный номер выпуска и часто они взаимозависимы: вы нуждаетесь в определённойверсии одного пакета, чтобы запустить определённую версию другого пакета. Создателидистрибутивов Linux обычно учитывают проблему совместимости пакетов и пользователь,который устанавливает подготовленный дистрибутив, не сталкивается с этой проблемой. Сдругой стороны, те, кто заменяет и модернизирует системное программное обеспечение самирешают эту проблему. К счастью, почти все современные дистрибутивы поддерживаютобновление отдельных пакетов, проверяя межпакетные зависимости; менеджердистрибутивных пакетов вообще не позволит обновиться, пока зависимости неудовлетворены.

    Для запуска примеров, которые мы приводим во время обсуждения, вы не будете нуждатьсяв особых версиях какого-то пакета помимо того, что требуется ядро версии 2.6; для запусканаших примеров может использоваться любой современный дистрибутив Linux. Мы не будемдетализировать определённые требования, потому что файл Documentation/Changes в вашихисходниках ядра - лучший источник такой информации, если вы испытываете какие-топроблемы. Возвращаясь к теме ядра, чётно пронумерованные версии ядра (то есть, 2.6.x)являются устойчивыми, которые предназначены для общего распространения. Нечётныеверсии (такие как 2.7.x), напротив, являются рабочими копиями и весьма неустойчивы;последняя из них представляет текущее состояние разработки, но становится устаревшейчерез несколько дней или около этого.

    Эта книга охватывает версию ядра 2.6. Мы постарались показать все возможности,доступные для авторов драйверов устройств в версии 2.6.10, текущей версии во времянаписания книги. Этот выпуск книги не охватывает предыдущие версии ядра. Для тех, кому этоинтересно, вторая редакция книги подробно охватывала версии от 2.0 до 2.4. Та редакция всёещё доступна на http://lwn.net/Kernel/LDD2/. Программисты ядра должны знать, что процессразработки изменился с версии 2.6. Ядра серии 2.6 теперь принимают изменения, которыеранее считали бы слишком большими для "устойчивого" ядра. Между прочим, это означает, чтовнутренние программные интерфейсы ядра могут измениться, потенциально делая, таким

    http://lwn.net/Kernel/LDD2/

  • 11 Драйверы устройств Linux, Третья редакция

    образом, части этой книги устаревшими; по этой причине код примеров, сопровождающийтекст, как известно, работает на версии 2.6.10, но некоторые модули не компилируют подболее ранними версиями. Программистам, желающим не отставать от изменений впрограммировании ядра, стоит присоединиться к почтовым рассылкам и использовать веб-сайты, перечисленные в библиографии. Есть также интернет-страница, созданная на http://lwn.net/Articles/2.6-kernel-api/, которая содержит информацию об изменениях API, которыепроизошли после публикации этой книги.

    Этот текст особенно не говорит о версиях ядра с нечётным номером. У обычныхпользователей никогда нет причины использовать ядра, находящиеся в разработке. Однако,разработчики, экспериментирующие с новыми возможностями, стремятся запускать последниевыпускаемые релизы. Они обычно обновляются до новой версии, чтобы получитьисправления ошибок и новые реализованные возможности. Отметьте, однако, что нет никакойгарантии на экспериментальных ядрах (* Примечание, нет никакой гарантии также и на чётнопронумерованных ядрах, если вы не полагаетесь на коммерческого провайдера, которыйпредоставляет его собственную гарантию), и никто не поможет вам, если есть проблемы из-заошибки в нетекущем ядре с нечётным номером. Те, кто запускает версии с нечётным номеромядра, обычно достаточно квалифицированы, чтобы углубиться в код без потребности вучебнике, что является другой причиной, почему мы не говорим здесь о разработках ядра.Другая особенность Linux - это то, что это платформо-независимая операционная система,больше не только “клон Unix для клонов PC”: в настоящее время поддерживается примерно 20архитектур. Эта книга платформо-независимая в максимально возможной степени и всепримеры кода были проверены по крайней мере на платформах x86 и x86-64. Поскольку кодбыл проверен и на 32-х разрядных и на 64-х разрядных процессорах, он долженкомпилироваться и работать на всех других платформах. Как вы могли бы ожидать, примерыкода, которые полагаются на специфические аппаратные средства, не работают на всехподдерживаемых платформах, но это всегда заявляется в исходном тексте.

    Лицензионное соглашение

    Linux лицензируется по версии 2 GNU General Public License (GPL), документа,разработанного для проекта GNU Фондом бесплатного программного обеспечения. GPLпозволяет любому распространять и даже продавать продукт, покрытый GPL, пока получательимеет доступ к исходнику и в состоянии реализовать те же самые права. Дополнительно,любой программный продукт, произошедший от продукта, покрытого GPL, если он вообщераспространяется, должен быть выпущен под GPL.

    Основная цель такой лицензии состоит в том, чтобы позволить рост знания, разрешая всемизменять программы по желанию; в то же самое время, люди, продающие программноеобеспечение общественности, могут всё ещё делать свою работу. Несмотря на эту простуюцель, есть бесконечное обсуждение GPL и её использования. Если вы хотите прочитатьлицензию, вы можете найти её в нескольких местах в вашей системе, включая главный каталогдерева исходников ядра в файле COPYING.

    Продавцы часто спрашивают, могут ли они распространить модули ядра только в бинарнойформе. Ответ на этот вопрос преднамеренно оставили неоднозначным. Дистрибьюциябинарных модулей, пока они придер�