Linux Device Drivers 3 / Драйверы устройств Линукс (третье издание): Глава 1. Драйвера устройств - введение
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Драйверы устройств - вводная глава allez 20.10.10 в 11:08 |
|
|
Одно из многих преимуществ свободных операционных систем, типичный представитель которых является Линукс, то что внутреннее устройство доступно для любого человека. Операционная система, темное и мистическое пространство, код которого был доступен для небольшого количества программистов, может теперь без труда быть рассмотрен, понят и модифицирован каждым обладающим необходимыми знаниями. Линукс помог демократизации операционных систем. Код ядра Линукс остается большим и сложным, даже исследователям необходима вводная часть, как к нему подступиться не нарушая его многогранности. Часто, драйвера устройств являются этой вводной частью. ximen 18.10.10 в 11:52 Одно из преимуществ свободных операционных систем, типичным представителем которых является Linux, - это доступность их внутреннего устройства для любого человека. Код операционной системы, который был доступен для ограниченного круга программистов, теперь может быть без труда рассмотрен, понят и модифицирован каждым, кто обладает необходимыми знаниями. Linux помог демократизации операционных систем. Однако, код ядра Linux остается большим и сложным, и даже будущим специалистам необходима вводная часть, чтобы они могли подступиться к нему, не нарушая его многогранности. Часто драйвера устройств являются этой вводной частью. JoUki 05.07.11 в 10:12 |
||
|
Драйвера устройств играют особую роль в ядре Линукс. Это особого вида «черные ящики» которые делают ответы особой части аппаратного обеспечения четко определённым внутренним программным интерфейсом, полностью скрывают как работает устройство. Действия пользователя представляют собой ряд стандартных вызовов, в сущности эти вызовы устройство зависимые операции которые работают с реальным аппаратным обеспечением и играют роль драйвера устройства. Этот программируемый интерфейс как этот драйвер может быть построен отдельно от остального ядра и быть подключенным во время работы когда это необходимо. Эта модульность делает написание драйверов достаточно простым, кстати поэтому сотни из них сегодня доступны. ximen 18.10.10 в 11:52 |
||
|
Вот почему есть смысл интересоваться написанием драйверов для Линукс. Скорость с которой приходит новое доступное аппаратное обеспечение (и устаревшего!) постоянно растет, вот почему писатели драйверов будут заняты в обозримом будущем. Особенно может понадобиться знания о драйверах для достижения доступа к возможностям устройств которые интересуют заказчика. Продавцам аппаратного обеспечения, создание драйверов именующийся у них продуктов, могут добавить большое и растущее количество пользователей Линукс на их потенциальных рынках. Сущность открытого кода операционной системы Линукс подразумевает что автор драйвера может если захочет распространить его исходный код для миллионов пользователей. ximen 18.10.10 в 11:52 |
||
|
Эта книга научит написать собственные драйвера и как использовать связанные части ядра. Мы даем аппаратно-независимое направление, предоставленные методы и интерфейсы, где это возможно, не привязаны ни к одному особенному устройству. Каждый драйвер различен, как писатель драйверов вам также необходимо понимать особенности устройства. Правда большинство принципов и методологических подходов одинаковы для всех устройств. Эта книга не может рассказать о вашем устройстве, но дает вам направление на подоплеку, которую вам необходимо знать при работе с вашим устройством. ximen 18.10.10 в 11:52 |
||
|
Если вы научитесь писать драйвера, вы само собой узнаете много о ядре Линукс; это может помочь вам понять как работает ваша машина и почему дело движется не всегда так быстро как вы надеялись или делают не то что нужно. Мы вводим новые понятия постепенно, начиная с очень простых примеров кода для тестирования которых не нужно специальное аппаратное обеспечение. ximen 18.10.10 в 11:52 |
||
|
Эта глава на самом деле не вводит в написание кода. Тем не менее, мы вводим несколько базовых понятий о ядре Линукс что вас порадует позже, когда мы начнем программировать. ximen 18.10.10 в 11:53 |
||
|
Роль драйверов устройств ximen 18.10.10 в 11:53 |
||
|
Как программист, вы постоянно должны делать собственный выбор драйвера, и выбрать приемлемый вариант между временем отведенного на программирование и гибкостью результата. Хотя это может показаться странным говорить что драйвер «гибкий», мы выбрали это слово потому что придаем ему особое значение так как драйвер устройства представляет собой механизм, а не политику. ximen 18.10.10 в 11:53 |
||
|
Различие между механизмом и политикой одна из лучших идей после проекта Unix. Большинство проблем программирования на самом деле идут на компромисс между двумя частями: «какие представлены возможности» (механизм) и «как могут быть использованы возможности пользователем» (политика). Если есть два подхода обращенные к разным частям программы или даже различным программам взятым вместе, тогда программный пакет намного проще совершенствовать и применять в практических целях. ximen 18.10.10 в 11:53 |
||
|
На пример, управление Unix графическим дисплеем разделяются между Х-сервером, который знаком с аппаратным обеспечением и поддерживает единый интерфейс пользователя программ, а также окна и менеджеры сессий, которые осуществляют особенную политику не зная ничего о аппаратном обеспечении. Люди могут использовать один и тот же оконный менеджер на разном аппаратном обеспечении, и различные пользователи могут запускать различные конфигурации на одной и той же рабочей станции. Даже совершенно разное рабочее окружение, такие как KDE и GNOME, могут сосуществовать в одной и той же системе. Другой пример — структурная расслоение сетевого протокола TCP/IP: операционная система предлагает сокетную абстракцию, которая выполняет без установки рассмотрение переданных данных, в то время как различные серверы управляют сервисами (и их ассоциированными политиками). Более того, сервер такой как ftpd обеспечивает механизм перемещения файлов, тогда когда пользователь может использовать все что предпочтут его клиенты, и командная строка и графический клиенты сосуществуют и любой может написать новый интерфейс для перемещения файлов. ximen 18.10.10 в 11:54 |
||
|
Драйверы связанны между собой, одинаково разделенные механизмы и применяемой политике. Пассивный драйвер это свободная политика его роль только показать дискету как продолжающейся массив блока данных. Более высокий уровень системы обеспечивают политики, такие как кто может иметь доступ к флоппи диску, либо диск доступен напрямую через файловую систему, а также либо пользователь может монтировать файловую систему на диске. С тех пор как различные окружения обычно требуются для использования аппаратного обеспечения различными путями, важно чтобы политика была свободной на столько насколько это возможно. ximen 18.10.10 в 11:54 |
||
|
Когда пишутся драйвера, программист с особенным вниманием должен относиться к этим фундаментальным основам: писать код ядра для доступа к аппаратному обеспечению, но не должен навязывать какую-нибудь особенную политику для пользователя, так как у разных пользователей разные потребности. При создании драйвера необходимо иметь дело с имеющимся аппаратным обеспечением, используя все подходы использования аппаратного обеспечения в приложениях. Драйвер, тогда, гибкий когда предоставляет доступ к возможностям аппаратного обеспечения без особых проблем. Иногда, тем не менее, некоторые политики должна быть реализованы. На пример, цифровой драйвер ввода\вывода может только предложить битово-широкий доступ к аппаратному обеспечению в порядке избегая дополнительного кода необходимого для управления единичными битами. ximen 18.10.10 в 11:54 |
||
|
На драйвер можно смотреть с разных точек зрения: это слой программного обеспечения который лежит между приложениями и подлинным устройством. Эта преимущественная роль драйверов позволяет программистам выбирать как устройство будет представлено: различные драйвера могут предложить различные возможности, даже для одного и того же устройства. Целью современного драйвера должен быть баланс между многими различными точками зрения. Для примера, отдельное устройство может быть использовано совместно различными программами и программисты драйверов имеют полную свободу определяя как поддерживать эти соглашения. Вы можете осуществлять отображение памяти на устройстве независимо от возможностей аппаратного обеспечения или можете обеспечивать пользовательскую библиотеку для помощи программистам приложений осуществляя новые политики на вершине доступных примитивов и так далее и тому подобное. Одно из главных соображений при продаже драйвера: приходится выбирать между сильным желанием представить пользователю как можно больше возможностей, и временем отведенным на его написание, также требуется сохранить простоту чтобы не запутать пользователя. ximen 18.10.10 в 11:54 |
||
|
Свободная политика драйверов имеют несколько типов характеристик. Они включают в себя поддержку и синхронных, и асинхронных операций, способность открывать множественные времена, способность использовать все возможности аппаратного обеспечения, и недостаток слоя программного обеспечения «упрощенные случаи» или предоставлять политически связанные операции. Драйверы этого типа не только работают лучше для конечных пользователей, но также оказывается проще для написания а также поддержки (сопровождения). Существование свободной политики фактически общая цель для проектировщиков программного обеспечения. ximen 18.10.10 в 11:54 |
||
|
Многие драйвера устройств, на самом деле, выпущенные вместе с пользовательскими программами позволяют задать конфигурацию устройства и обеспечивают доступ к нему. Эти программы могут выстраивать как ряд из простых утилит образуя целое графическое приложение. Примеры включающие программу tunelp, которые регулируют как работает драйвер параллельного порта принтера и графическая утилита cardctl, которая является частью пакета драйверов PCMCIA. Часто и клиентские библиотеки обеспечивают это, которые обеспечивают такие возможности что нет необходимости осуществлять их как часть драйвера. ximen 18.10.10 в 11:54 |
||
|
В рамках этой книги ядро, так мы попытались не вести дело с политикой результатов или с программными приложениями или поддерживать библиотеки. Иногда мы говорим о различных политиках и как поддерживать их, но мы не хотели вдаваться в подробности о программах использующих устройства или навязывать их политики. Вы должны понять, тем не менее, что пользовательские программы существенная часть программных пакетов и что свободная политика пакетов поставляемых с конфигурационными файлами допускает недосмотр режима лежащего в основе механизма. ximen 18.10.10 в 11:54 |
||
|
Внутреннее устройство ядра ximen 18.10.10 в 11:55 |
||
|
В Unix системе, несколько действующих одновременно процессов обслуживающих различные задачи. Каждый процесс запрашивает ресурсы системы, будь то управление компьютером, памяти, сетевых соединений или некоторые другие ресурсы. Ядро это большой кусок выполняемого кода обеспечивающих все эти запросы. Хотя различие между различными задачами ядра не всегда ясно выражены, роль ядра, тем не менее, их можно разделить на следующие части: (смотрите на рисунок 1-1) ximen 18.10.10 в 11:55 |
||
|
Управление процессами. ximen 18.10.10 в 11:55 |
||
|
Управление памятью. ximen 18.10.10 в 11:55 |
||
|
Файловые системы. ximen 18.10.10 в 11:55 |
||
|
Контроль устройств. ximen 18.10.10 в 11:55 |
||
|
Сетевая работа. ximen 18.10.10 в 11:56 |
||
|
Загружаемые модули. ximen 18.10.10 в 11:56 |
||
|
Одна из хороших особенностей Линукс это способность во время работы ядра устанавливать его параметры. Это значит что вы можете добавить функциональность ядра (а также убирать какую-то функциональность) в то время когда система запускается и во время её работы. ximen 18.10.10 в 11:56 |
||
|
Каждый кусок кода, который добавляется во время работы ядра, называется модулем. Ядро Линукс предлагает поддержку для достаточно немногих различных типов (или классов) модулей, включая, но не ограничивая, драйверы устройств. Каждый модуль переделывает объект кода (не связанные в полностью исполняемый комплекс ) это может быть динамичное связывание во время работы ядра «внутреннего модуля (insmod)» программы и могут быть не связанные «удаленного модуля (rmmod)???» программы. ximen 18.10.10 в 11:56 |
||
|
Рисунок 1-1 отображает различные классы модулей, которые заведуют специфическими задачами так модуль принадлежит какому-то особому классу в соответствии со своей функциональностью. Место модулей на рисунке 1-1 покрывает большинство важных классов, но далеко не все, потому что все больше и больше функциональностей добавляются в Линукс. ximen 18.10.10 в 11:56 |
||
|
Классы устройств и модулей. ximen 18.10.10 в 11:56 |
||
|
Линукс смотрит на устройства различая три основные типа устройств. Каждый модуль обычно принадлежит одному из этих типов, а они классифицируются на символьные модули, блочные модули или сетевые модули. Это разделение модулей на различные типы или классы, не является жестким правилом, программист может выбирать строить огромные модули различных типов осуществляя различные драйвера в одном куске кода. Хороший программист, вне всякого сомнения, обычно создает различные модули для каждой новой функциональности которую они осуществляют, потому что разложение уравновешенный и распространенный ключевой элемент. ximen 18.10.10 в 11:57 |
||
|
Символьные устройства. ximen 18.10.10 в 11:57 |
||
|
Блочные устройства. ximen 18.10.10 в 11:57 |
||
|
Сетевые интерфейсы. ximen 18.10.10 в 11:57 |
||
|
Не будучи потоково ориентированным устройством, сетевой интерфейс не проще(?) отображен как узле в файловой системе, как /dev/tty1. Unix обеспечивает доступ к интерфейсу назначая постоянное и уникальное имя для него (на пример eth0), но это имя не соответствует узлу в файловой системе (/dev/tty02). Связь между ядром и драйвером сетевого устройства полностью отличается от того как это осуществляется в символьных и блочных драйверах. Вместо чтения и записи, ядро вызывает функционально связанную передачу пакета. ximen 18.10.10 в 11:57 |
||
|
С другой стороны классификация модулей драйверов противоположность в основном типам устройств. Обычно, несколько типов драйверов работают с добавлением слоев функций поддержки ядра, которые дают типы устройств. На пример, один может переговариваться с универсальной последовательной шиной (USB), модули последовательного порта, SCSI модули и так далее. Каждое USB устройство управляется модулем который работает с подсистемой USB, но устройство представлено в системе как символьное устройство (последовательный порт USB микрофон), блочное устройство (USB картридер), или сетевое устройство (USB сетевой интерфейс). ximen 18.10.10 в 11:58 |
||
|
Другие классы драйверов устройств добавляются в ядро в последний момент, включая FireWire и I2O драйвера. В тоже время они управляют USB и SCSI драйверами, разработчики ядра собрали широкий класс особенностей и экспортировали их в инструментарий драйверов во избежание двойной работы и ошибок, эта упрощает и делает более строгим процесс написания таких драйверов. ximen 18.10.10 в 11:58 |
||
|
В дополнение у драйверов устройств, есть другая функциональность, и аппаратное и программное обеспечение, представлено в системе модулем ядра. Простой пример файловая система. Тип файловой системы определяет как организована информация на блочном устройстве, представляя дерево каталогов и файлов. Так внутри это не драйвера устройств, вот почему не ясно устройство объединено с тем где лежит информация, тип файловой системы вместо программного драйвера, потому что это отображение структуры низкого уровня на более высокий. Файловая система определяет возможную длину названия файла и какая информация храниться в файле внутри директории. Модуль файловой системы должен выполнять вызовы низкого уровня которые открывают доступ к файлам и директориям, отображая названия файлов и директорий (также как и другая информация, такая как режимы доступа) структуры хранимых данных в блоках данных. Так интерфейс фактически полностью зависит от перемещения данных с диска (или с других носителей информации), которые заканчивают на драйвере блочного устройства. ximen 18.10.10 в 11:58 |
||
|
Если вы поймете как строго Unix система зависит от основной файловой системой, вы поймете какая программная концепция жизненно важна для этой операционной системы. Способность декодировать информации в файловой системе на самом низком уровне ядра иерархически и предельно важно, даже если вы пишите блочный драйвер для вашего нового CD-ROMa это бесполезно если вы не сможете запустить ls и cp для данных этих хостов. Линукс поддерживает концепцию модулей файловой системы, этот программный интерфейс объявляет различные операции которые могут быть сделаны узды, директории, файлы и суперблоки файловой системы. Это достаточно необычно для программиста фактически необходимо писать модули файловой системы, потому что официальное ядро уже включает код для большинства типов файловых систем. ximen 18.10.10 в 11:58 |
||
|
Подходы безопасности ximen 18.10.10 в 11:59 Вопросы безопасности ximen 18.10.10 в 11:59 |
||
|
В современном мире, безопасность вызывает все большее беспокойство. Мы будем обсуждать реализации подходов безопасности по мере того как они появятся в книге. Тем не менее несколько основных понятий, стоит упомянуть прямо сейчас. hardorsoft 19.10.10 в 22:45 |
||
|
Любая проверка безопасности в системе вынуждается кодом ядра. Если в ядре есть «уязвимость» в безопасности, тогда и система в целом «уязвимая». В официальном дистрибутиве ядра, только авторизированный пользователь может загрузить модуль, системный вызов init_module проверяется если вызываемый процесс идентифицирован в системе тогда модуль загружается в ядро. Так когда запускается служебное ядро, только суперпользователь или человек который сменил при входе свои права, может взяться за управление привилегированного кода. hardorsoft 19.10.10 в 22:45 |
||
|
Тогда когда это возможно, авторы драйверов должны избегать шифрование политики безопасности в своем коде. Управлять политикой безопасности лучше всего на более высоких уровнях ядра, под контролем системного администратора. Тем не менее всегда бывают исключения. hardorsoft 19.10.10 в 22:46 |
||
|
[1] Технически, только кто-то с правами доступа CAP_SYS_MODULE может выполнять эту операцию. Права доступа мы рассмотрим в шестой главе. hardorsoft 19.10.10 в 22:46 |
||
|
Как автор драйвера, вы должны осознавать ситуацию в которой некоторые типы устройств имеют возможность враждебно действовать на систему и в целом должны обеспечиваться соответствующий контроль. На пример, операции устройства которые действует на глобальные ресурсы (такие как установки внутренней линии), которые могут причинить вред аппаратному обеспечению (на пример при загрузке фирменного программного обеспечения) или когда могут действовать другие пользователи (такие как установки по умолчанию размера блока на ленточном диске), обычно только доступный достаточно привилегированным пользователям, и их проверка должна быть сделана внутри драйвера. hardorsoft 19.10.10 в 22:46 |
||
|
Авторы драйверов, должны также быть внимательными, конечно же, не допуская так называемых баггов в безопасности. Язык программирования С способствует этому делая несколько типов характерных ошибок. Много текущих проблем безопасности производятся, на пример, из-за переполнения буфера ошибок, который программист часто забывает проверить как много данных записано в буфер и переполняют его несвязанными данными. Такие ошибки могут подвергать опасности внутренности системы поэтому необходимо избегать их. Успешно, избегать таких ошибок довольно просто в драйверах у которых интерфейс пользователя точно определен и легко контролируем. hardorsoft 19.10.10 в 22:47 |
||
|
Есть несколько других подходов, которых стоит придерживаться. Любой полученный ввод информации от процесса пользователя должен быть обработан с огромным подозрением, ни когда не надейтесь на него пока не проверите все. Будьте внимательны с не инициированной памятью, любая память достигает ядра должна быть обнулена или другим образом про инициирована до того как будет доступна для пользовательского процесса или устройства. Иначе, результатом может быть оказаться утечка информации (обнаружение информации, паролей и т.д.). Если ваше устройство интерпретирует отправку данных к ядру, вы должны быть уверены что пользователь не может послать ничего что может причинить вред системе. Наконец, подумайте о возможных результатах от операций устройства; если есть какие-то особенные операции (на пример, перезагрузка фирменного программного обеспечения на соединительном устройстве или форматирование диска) которые могут воздействовать на систему, то они должны непременно ограничиваться правами пользователя. hardorsoft 19.10.10 в 22:47 |
||
|
Также, будьте внимательны, когда получаете программное обеспечение от третей стороны, особенно когда они обращаются к ядру: потому что любой кто имеет доступ и исходному коду, может сломать и пере компилировать. Хотя вы можете обычно довериться на заранее откомпилированные ядра в вашем дистрибутиве, вы должны избегать запуск ядра откомпилированного не надёжными друзьями, если вы не можете запустить заранее откомпилированное бинарный файл от имени суперпользователя, тогда вы лучше не запускайте заранее откомпилированное ядро. На пример, злонамеренно модифицированное ядро может разрешить любому загрузить модуль, так открыть неожиданную заднюю дверь через init_module. hardorsoft 19.10.10 в 22:48 |
||
|
Помните что ядро Линукс может быть откомпилированы без поддержки модуля, так закрытие любого связанного модуля может оказаться «уязвимостью» в безопасности. В этом дело, конечно, все необходимые драйвера должны бить построены прямо в ядре. Это тоже возможно, с ядром 2.2 и более поздних издательствах ядра, запрещая загрузку модулей ядра, после того как система загрузится через возможный механизм. hardorsoft 19.10.10 в 22:48 |
||
|
Нумерация версий hardorsoft 19.10.10 в 22:48 |
||
|
Прежде чем копаться в программировании, мы должны сделать замечания о схеме нумерации версий используемые в Линукс и которые версии описывает эта книга. hardorsoft 19.10.10 в 22:50 |
