Автор работы: Пользователь скрыл имя, 04 Января 2011 в 19:53, курсовая работа
Разработкой драйверов обычно занимаются профессионалы, каждая крупная компания, выпускающая технику имеет целый штат сотрудников, занимающихся разработкой драйверов. Прежде всего, разработчик драйвера должен владеть программированием на языке С (без расширений С++), поскольку описание синтаксиса и применения конструкций этого языка не рассматриваются в данной книге вовсе. Во-вторых, разработчик драйверов, пусть начинающий, должен иметь твердо сформировавшееся представление о программировании в многозадачной среде при интенсивном использовании многопоточности.
Введение.
Драйверная концепция – неотъемлемая часть современных операционных систем. Эта концепция – основа взаимодействия системы (пользователя) с какими бы то ни было устройствами (системными/периферийными, реальными/виртуальными и т.д.). Даже системные программисты далеко не всегда имеют представление об этой концепции, о принципах ее работы, о программировании с использованием этой концепции. А ведь системное программирование – ключ к пониманию основ IT.
Написание драйверов – достаточно сложная, но, тем не менее, очень интересная и актуальная отрасль программирования. Знание особенностей технологии написания драйверов открывает огромное количество возможностей – написание драйверов для устройств, уже не поддерживаемых производителем, для устройств, драйвера к которым еще не написаны, исправление ошибок в драйверах, написание драйверов к различным промышленным устройствам и т.д.
У каждой операционной системы есть свои особенности, отсюда вытекает своя специфика написания драйверов под них. То же самое можно сказать и о разных типах оборудования.
Разработкой
драйверов обычно занимаются профессионалы,
каждая крупная компания, выпускающая
технику имеет целый штат сотрудников,
занимающихся разработкой драйверов.
Прежде всего, разработчик драйвера должен
владеть программированием на языке С
(без расширений С++), поскольку описание
синтаксиса и применения конструкций
этого языка не рассматриваются в данной
книге вовсе. Во-вторых, разработчик драйверов,
пусть начинающий, должен иметь твердо
сформировавшееся представление о программировании
в многозадачной среде при интенсивном
использовании многопоточности.
Часть 1. Драйвера.
1.1 Основные понятия.
Драйвер
– это часть кода операционной
системы (небольшая программка не для
пользователя, а для ОС), отвечающая
за взаимодействие с аппаратурой. Под
словом «аппаратура» можно подразумевать
как реальные физические устройства,
так и виртуальные и
С момента своего появления и до сегодняшнего дня драйвер непрерывно эволюционировал, и процесс этот продолжается до сих пор. Один из моментов эволюции драйвера – это эволюция концепции драйвера, как легко заменяемой части операционной системы. Как отдельный и довольно независимый модуль драйвер сформировался не сразу, да и сейчас многие драйверы практически неотделимы от операционной системы. Во многих случаях это приводит к необходимости переустановки системы (ОС Windows) или переборки ее ядра (в UNIX-системах).
Список основных общих концепций драйверов в Windows и UNIX-системах выглядит так:
Классификация типов драйверов для ОС Windows:
- Драйверы виртуальных устройств (Virtual Device Drivers, VDD) – используются для поддержки программ MS-DOS;
- Драйверы принтеров (Printer Drivers);
2. Драйверы режима ядра (Kernel-Mode Drivers):
- Драйверы файловой системы (File System Drivers) – осуществляют ввод/вывод на локальные и сетевые диски
- Унаследованные драйверы (Legacy Drivers) – написаны для предыдущих версий Windows
- Драйверы видеоадаптеров (Video Drivers) – реализуют графические операции
- Драйверы потоков устройств (Streaming Drivers) – осуществляют ввод/вывод потоков видео и звука
- WDM-драйверы (Windows Driver Model) – поддерживают технологию Plug and Play и управления электропитанием.
Драйверы бывают одно- и многоуровневыми. Если драйвер является многоуровневым, то обработка запросов ввода/вывода распределяется между несколькими драйверами, каждый из которых выполняет свою часть работы. Между этими драйверами можно поставить любое количество фильтр-драйверов (filter-drivers). При обработке запроса данные идут от вышестоящих драйверов к нижестоящим, а при возврате – наоборот. Одноуровневый драйвер (monolithic) драйвер является противоположностью многоуровневому.
Для технологии Plug and Play существуют три уровня-типа драйверов:
- шинные драйверы
- фильтр-драйверы
- функциональные драйверы
Системное ПО, поддерживающее Plug and Play предоставляет следующие возможности:
- автоматическое распознавание подключенных к системе устройств
- распределение и перераспределение ресурсов (таких, как порты ввода/вывода и участки памяти) между запросившими их устройствами
- загрузка необходимых драйверов
- предоставление драйверам необходимого интерфейса для взаимодействия с технологией Plug and Play
- реализация механизма, позволяющего драйверам и приложениям получать информацию касаемо изменений в наборе устройств, подключенных к системе устройств, и совершить необходимые действия
- предоставление драйверам необходимого интерфейса для взаимодействия с технологией Plug and Play
- реализация механизма, позволяющего драйверам и приложениям получать информацию касаемо изменений в наборе устройств, подключенных к системе устройств, и совершать необходимые действия.
1.2. Инструментарий.
Существует
много утилит, которые могут понадобиться
при разработке драйверов. Основным
средством разработки является Microsoft
Windows DDK, Device Driver Kit, — пакет разработки
драйверов, включающий компилятор, редактор
связей (линкер), заголовочные файлы, библиотеки,
большой набор примеров (часть
из которых является драйверами, реально
работающими в операционной системе)
и, разумеется, документацию. В состав
пакета входит также отладчик WinDbg, позволяющий
проводить интерактивную
Языком программирования, который используется в DDK является язык С, допускающий вставки на языке ассемблер, который в былые времена был основным и единственным языком программирования драйверов.
В бесплатно распространяемом пакете DDK всегда отсутствовала интегрированная среда разработки. Поэтому есть необходимость использовать Visual Studio в качестве средства редактирования исходного кода. При должной настройке этой среды процесс выявлений синтаксических ошибок существенно облегчается — неотъемлемое преимущество интегрированных сред программирования. Компилятор и редактор связей Visual Studio C++ создают нормальный бинарный код, вполне работоспособный при указании соответствующих опций (настроек) компиляции, однако эталоном следует считать бинарный код, получающийся при компиляции кода драйвера с использованием утилиты Build из состава пакета DDK. Разумеется, встроенный интерактивный отладчик Visual Studio и прилагаемая документация становятся для разработки драйвера совершенно бесполезными, поскольку не предназначены для работы с программным обеспечением для режима ядра.
Есть пакеты разработки драйверов и от других фирм: WinDriver или NuMega Driver Studio, но у них есть отличия базиса функций Microsoft (порой довольно большие) и масса других мелких неудобств.
Так же необходимо использовать некоторые сторонние утилиты, такие как: редактор реестра, мониторы обращений к реестру и файлам, средство просмотра каталогов имен объектов, программы просмотра, сохранения и т.д. отладочных сообщений.
Что же касается написания драйверов под 64х битные системы, то очень полезными являются такие инструменты, как:
- анализатор PREfast, от Microsoft. Это статический анализатор кода, который обнаруживает некоторые классы ошибок, которые часто встречаются как в драйверах, так и в обычных C и C++ программах.
- статический анализатор кода общего назначения Gimpel Software PC-lint, который обнаруживает помимо некоторых из перечисленных ошибок, еще и огромное количество ошибок, встречающихся в обычных программах.
-
статический анализатор кода Viva64 предназначен
для поиска ошибок в C++ программах, проявляющихся
при переносе кода с 32-битных на 64-битные
системы.
Часть 2. Архитектура Windows.
Цели разработки.
Пять фундаментальных задач Windows последнего поколения:
- Совместимость. Операционная система должна поддерживать максимально возможное множество программного и аппаратного обеспечения.
- Переносимость. Операционная система должна функционировать на максимально возможном количестве имеющихся сейчас и ожидаемых в перспективе аппаратных платформ.
- Расширяемость. Поскольку требования рынков постоянно растут, операционная система должна уметь с легкостью расширять набор своих возможностей и перечень поддерживаемой аппаратуры при минимальном вмешательстве в свой внутренний код.
- Надежность и устойчивость. Операционная система должна быть стойкой к неумышленному или преднамеренному неправильному использованию компонентов. Пользовательские приложения не должны иметь возможности приведения системы к фатальным сбоям.
- Производительность. Операционная система должна обеспечивать хорошую производительность на всех поддерживаемых аппаратных платформах.
Разумеется, провозглашение и достижение цели не всегда есть одно и то же, и серьезные компромиссы общих и текущих задач оказываются неизбежными. Windows столь же подвержена компромиссам, как и все остальные операционные системы.
Уровни аппаратных привилегий в Windows.
Для достижения устойчивости в работе системы, разработчики Windows выбрали для построения ядра так называемую 'архитектуру клиент-сервер'. В данном случае, пользовательское приложение и является клиентом служб операционной системы.
Пользовательское приложение функционирует в специальном режиме (относительно аппаратного обеспечения), называемом 'user mode' — пользовательский режим. В пределах этого режима, код приложения ограничен выполнением "безвредных" инструкций. Например, через реализацию "таинственного" маппинга (mapping, отображение) виртуальной памяти (страничное представление виртуальной памяти) пользовательский код лишается возможности доступа к виртуальной памяти, предоставленной другим приложениям (за исключением случаев обоюдного согласия, что реализуется специально предназначенными на тот случай методами). Инструкции аппаратного ввода/вывода также не могут быть выполнены кодом пользовательского режима. Целый класс инструкций центрального процессора (называемых привилегированными) запрещен в Windows для выполнения кодом пользовательского режима, как, например, команды процессора IN, OUT. Если вдруг приложению потребуется выполнить что-нибудь из числа таких запрещенных для нее действий, оно должно запросить соответствующую службу операционной системы.
Код самой операционной системы выполняется в так называемом 'kernel mode' — режиме ядра (режиме уровня ядра). Код режима ядра вправе выполнить любую процессорную инструкцию, не исключая инструкций ввода/вывода. Память, принадлежащая любому приложению, может быть доступна коду режима ядра, конечно, если страничная память приложения в данный момент не сброшена на жесткий диск.
Современные
процессоры реализуют несколько
форм привилегированного режима в отличие
от непривилегированного. Код режима
ядра выполняется в