Драйвер что это такое какую роль выполняет
Многие считают что самому создать драйвер для Windows это что-то на грани фантастики. Но на самом деле это не так. Конечно, разработка драйвера для какого-то навороченного девайса бывает не простой задачей. Но ведь тоже самое можно сказать про создание сложных программ или игр. В разработке простого драйвера нет ничего сложного и я попытаюсь на примерах это показать.
Сперва нам нужно определится в чем мы же будем создавать наш первый драйвер. Поскольку материал ориентирован на новичков, то язык программирования был выбран один из простых, и это не Си или ассемблер, а бейсик. Будем использовать один из диалектов бейсика — PureBasic. Из коробки он не обучен создавать драйверы, но у него удачный набор файлов, используемых для компиляции и небольшое шаманство позволяет добавить эту возможность. Процесс компиляции состоит из нескольких этапов. Если кратко, то он происходит следующим образом: Сначала транслятор «перегоняет» basic-код в ассемблер, который отдается FASM'у (компилятор ассемблера), который создает объектный файл. Далее в дело вступает линкер polink, создающий исполняемый файл. Как компилятор ассемблера, так и линкер могут создавать драйверы и если немного изменить опции компиляции, то получим не исполняемый файл, типа EXE или DLL, а драйвер режима ядра (SYS).
Окно IDE с загруженным кодом драйвера показано на скрине.
Компиляция драйвера выполняется через меню «Компилятор» (это если кто не понял).
Теперь определимся что будет делать наш первый драйвер. Обычно при изучении программирования начинают с простых вещей, скажем, выполнения математических операций и вывода результата. Вот пусть наш драйвер делает тоже самое, ведь банальная математика производимая в режиме ядра это очень круто!
Может показаться что это куча бессмысленного кода, но это не так.
У каждого драйвера должна быть точка входа, обычно у нее имя DriverEntry() и выполнена она в виде процедуры или функции. Как видите, в этом драйвере есть такая процедура. Если посмотрите на начало кода, то в первых строках увидите как ей передается управление. В этой процедуре происходит инициализация драйвера. Там же назначается процедура завершения работы драйвера, которая в нашем случае имеет имя UnloadDriver(). Процедуры CreateDispatch() и CloseDispatch() назначаются обработчиками соединения и отсоединения проги из юзермода.
Процедура DeviceIoControl() будет обрабатывать запросы WinAPI функции DeviceIoControl(), являющейся в данном драйвере связью с юзермодом. В конце кода расположена так называемая ДатаСекция (DataSection), в которой находятся имена драйвера, сохраненные в формате юникода (для этого использована одна из фишек ассемблера FASM).
Видите сколько понадобилось кода для выполнения простейшей математической операции — сложения двух чисел?
А теперь рассмотрим программу, работающую с этим драйвером. Она написана на том же PureBasic.
Процедура Plus() осуществляет связь с драйвером. Ей передаются хэндл, доступа к драйверу и слагаемые числа, которые помещаются в структуру и указатель на указатель которой, передается драйверу. Результат сложения чисел будет в переменной «Result».
Далее следует код простейшего GUI калькулятора, скопированного из википедии.
Когда закроют окно, то перед завершением работы программы, закрывается связь с драйвером и производится его деинсталляция из системы.
Результат сложения чисел 8 и 2 на скриншоте.
Исходные коды драйвера и программы, можно найти в папке «Examples», PureBasic на файлопомойке, ссылку на который давал в начале статьи. Там так же найдете примеры драйвера прямого доступа к порам компа и пример работы с памятью ядра.
PS.
Помните, работа в ядре чревата мелкими неожиданностями аля, BSOD (синий экран смерти), поэтому экспериментируйте осторожно и обязательно всё сохраняйте перед запуском драйвера.
Как уважаемый хабрапользователь наверняка знает, «драйвер устройства» — это компьютерная программа управляющая строго определенным типом устройства, подключенным к или входящим в состав любого настольного или переносного компьютера.
Основная задача любого драйвера – это предоставление софтового интерфейса для управления устройством, с помощью которого операционная система и другие компьютерные программы получают доступ к функциям данного устройства, «не зная» как конкретно оно используется и работает.
Обычно драйвер общается с устройством через шину или коммуникационную подсистему, к которой подключено непосредственное устройство. Когда программа вызывает процедуру (очередность операций) драйвера – он направляет команды на само устройство. Как только устройство выполнило процедуру («рутину»), данные посылаются обратно в драйвер и уже оттуда в ОС.
Любой драйвер является зависимым от самого устройства и специфичен для каждой операционной системы. Обычно драйверы предоставляют схему прерывания для обработки асинхронных процедур в интерфейсе, зависимом от времени ее исполнения.
Любая операционная система обладает «картой устройств» (которую мы видим в диспетчере устройств), для каждого из которых необходим специфический драйвер. Исключения составляют лишь центральный процессор и оперативная память, которой управляет непосредственно ОС. Для всего остального нужен драйвер, который переводит команды операционной системы в последовательность прерываний – пресловутый «двоичный код».
Как работает драйвер и для чего он нужен?
Основное назначение драйвера – это упрощение процесса программирования работы с устройством.
Он служит «переводчиком» между хардовым (железным) интерфейсом и приложениями или операционными системами, которые их используют. Разработчики могут писать, с помощью драйверов, высокоуровневые приложения и программы не вдаваясь в подробности низкоуровневого функционала каждого из необходимых устройств в отдельности.
Как уже упоминалось, драйвер специфичен для каждого устройства. Он «понимает» все операции, которые устройство может выполнять, а также протокол, с помощью которого происходит взаимодействие между софтовой и железной частью. И, естественно, управляется операционной системой, в которой выполняет конкретной приложение либо отдельная функция самой ОС («печать с помощью принтера»).
Если вы хотите отформатировать жесткий диск, то, упрощенно, этот процесс выглядит следующим образом и имеет определенную последовательность: (1) сначала ОС отправляет команду в драйвер устройства используя команду, которую понимает и драйвер, и операционная система. (2) После этого драйвер конкретного устройства переводит команду в формат, который понимает уже только устройство. (3) Жесткий диск форматирует себя, возвращает результат драйверу, который уже впоследствии переводит эту команду на «язык» операционной системы и выдает результат её пользователю (4).
Как создается драйвер устройства
Для каждого устройства существует свой строгий порядок выполнения команд, называемой «инструкцией». Не зная инструкцию к устройству, невозможно написать для него драйвер, так как низкоуровневые машинные команды являются двоичным кодом (прерываниями) которые на выходе отправляют в драйвер результат, полученный в ходе выполнения этой самой инструкции.
При создании драйвера для Линукса, вам необходимо знать не только тип шины и ее адрес, но и схематику самого устройства, а также весь набор электрических прерываний, в ходе исполнения которых устройство отдает результат драйверу.
Написание любого драйвера начинается с его «скелета» — то есть самых основных команд вроде «включения/выключения» и заканчивая специфическими для данного устройства параметрами.
И чем драйвер не является
Часто драйвер устройства сравнивается с другими программами, выполняющими роль «посредника» между софтом и/или железом. Для того, чтобы расставить точки над «i», уточняем:
- Драйвер не является интерпретатором, так как не исполняется напрямую в софтовом слое приложения или операционной системы.
- Драйвер не является компилятором, так как не переводит команды из одного софтового слоя в другой, такой же.
Ну и на правах рекламы – вы всегда знаете, где скачать новейшие драйвера для любых устройств под ОС Windows.
Опять вернёмся в традиционную область разработки операционных систем (и приложений для микроконтроллеров) — написание драйверов.
Я попробую выделить некоторые общие правила и каноны в этой области. Как всегда — на примере Фантома.
Драйвер — функциональная компонента ОС, ответственная за отношения с определённым подмножеством аппаратуры компьютера.
С лёгкой руки того же Юникса драйвера делятся на блочные и байт-ориентированные. В былые времена классическими примерами были драйвер диска (операции — записать и прочитать сектор диска) и драйвер дисплея (прочитать и записать символ).
В современной реальности, конечно, всё сложнее. Драйвер — типичный инстанс-объект класса, и классов этих до фига и больше. В принципе, интерфейс драйверов пытаются как-то ужать в прокрустово ложе модели read/write, но это самообман. У драйвера сетевой карты есть метод «прочитать MAC-адрес карты» (который, конечно, можно реализовать через properties), а у драйвера USB — целая пачка USB-специфичных операций. Ещё веселее у графических драйверов — какой-нибудь bitblt( startx, starty, destx, desty, xsize, ysize, operation ) — обычное дело.
Цикл жизни драйвера, в целом, может быть описан так:
- Инициализация: драйвер получает ресурсы (но не доступ к своей аппаратуре)
- Поиск аппаратуры: драйвер получает от ядра или находит сам свои аппаратные ресурсы
- Активация — драйвер начинает работу
- Появление/пропадание устройств, если это уместно. См. тот же USB.
- Засыпание/просыпание аппаратуры, если это уместно. В контроллерах часто неиспользуемая аппаратура выключается для экономии.
- Деактивация драйвера — обслуживание запросов прекращается
- Выгрузка драйвера — освобождаются все ресурсы ядра, драйвер не существует.
(Вообще я написал в прошлом году черновик открытой спецификации интерфейса драйвера — см. репозиторий и документ.)
Мне известны три модели построения драйвера:
Драйвер на основе поллинга (циклического опроса) устройства
Такие драйвера применяются только с большого горя или по большой необходимости. Или если это простая встроенная микроконтроллерная система, в которой и есть-то всего два драйвера. Например, конвертор интерфейсов serial port TCP, в котором сеть работает по прерываниям, работу с последовательным портом может, в принципе, выполнять и поллингом. Если не жалко избытка тепла и затрат энергии.
Есть и ещё одна причина: такие драйвера практически неубиваемы. Поэтому, например, в ОС Фантом отладочная выдача ядра в последовательный порт сделана именно так.
В цикле проверяем готовность порта принять байт, передаём байт, закончили упражнение.
Такой драйвер, как нетрудно видеть, пожирает процессор в ожидании готовности устройства. Это можно починить, если скорость работы самого драйвера некритична:
Но, конечно, в целом это никуда не годная (кроме вышеприведённого случая:) модель.
Драйвер на основе прерываний
Общая структура такого драйвера выглядит вот как:
Фактически, такой драйвер порождает для себя псевдо-нить: поток управления, который живёт только на поступлении прерываний от устройства.
Как только драйвер получает очередной запрос на запись, он включает прерывания и «вручную» инициирует отправку в устройство первого байта данных. После чего входящая нить засыпает, ожидая конца передачи. А может и вернуться, если нужна асинхронная работа. Теперь драйвер будет ждать прерывания от устройства. Когда устройство «прожуёт» полученный байт, оно сгенерирует прерывание, при обслуживании которого драйвер или отправит очередной байт (и будет ждать очередного прерывания), или закончит работу, выключит прерывания и «отпустит» ждущую внутри dev_write() нить.
Что забыто
Прежде чем мы перейдём к последней модели драйвера, перечислим вещи, которые я (намеренно) пропустил в предыдущем повествовании.
Обработка ошибок
В нашем псевдокоде никак не проверяется успешность ввода-вывода. Реальное устройство может отказать или сообщить о неисправности носителя. Вынули кабель из порта локалки, на диске случился плохой блок. Драйвер должен обнаружить и обработать.
Таймауты
Устройство может сломаться и просто не ответить на запрос прерыванием, или никогда не выставить бит готовности. Драйвер должен запросить таймерное событие, которое бы вывело его из «ступора» на такой случай.
Смерть запроса
Если окружающая нас ОС это позволяет, то надо быть готовым к тому, что вошедшая в драйвер нить, в рамках которой «пришёл» запрос ввода-вывода, может быть просто убита. Это не должно приводить к фатальным последствиям для драйвера.
Синхронизация
Для простоты я указываю в качестве примитива синхронизации cond. В реальном драйвере это невозможно — cond требует объемлющего mutex в точке синхронизации, а в прерывании какой уж mutex — нельзя! Вот в последней модели, драйвере с собственной нитью, можно применять cond как средство синхронизации нити пользователя и нити драйвера. А вот синхронизация с прерыванием — только spinlock и семафор, причём реализация семафора должна быть готова к возможности активировать (открыть) семафор из прерывания. (В Фантоме это так и есть)
Драйвер на основе нити
От предыдущего он отличается тем, что имеет собственную нить, которая выполняет ввод-вывод.
Преимущество такого драйвера в том, что из нити можно позволить себе куда больше, чем из хендлера прерывания — можно выделять память, управлять таблицами страниц и вообще звать любую функцию ядра. Из прерывания нельзя позволить себе длинные и, тем более, блокирующие операции.
Отметим, что есть третья, промежуточная модель, в которой драйвер не имеет своей нити, а выполняет всё то же самое из нити запроса ввода-вывода. Но, во-первых, см. пункт о том, что её могут убить, во-вторых это жлобство :), а в третьих — не всегда она (нить) такого хочет. Иным бы хотелось асинхронного обслуживания.
Блочный ввод-вывод, сортировка и заборы
Дисковые драйвера обычно имеют на входе очередь запросов — ОС генерирует запросы на ввод-вывод пачками, и все запросы на уровне драйвера асинхронны. При этом хороший драйвер имеет собственную стратегию обслуживания запросов, причём — обслуживания не в порядке поступления.
Действительно, если на обычном дисковом устройстве выполнять запросы в том порядке, в котором они прилетели, головке накопителя придётся совершать хаотичные движения по диску, замедляя ввод-вывод.
Обычно драйвер просто сортирует очередь запросов по номеру блока и обслуживает их так, чтобы головка диска последовательно двигалась от внешней дорожки к внутренней, или наоборот. Это сильно помогает.
Но не всякую пару запросов можно поменять местами. Если файловая система (или её аналог) решила, что ей надо гарантировать целостность данных на диске, она бы очень хотела убедиться в том, что определённая группа запросов завершена. Для этого в очередь запросов вставляется специальный запрос ввода-вывода, который запрещает перемешивать запросы до себя с запросами после себя.
Кроме того, плохая идея переставлять местами запрос на запись блока N и запрос на чтение того же блока. Впрочем, это вопрос договорённостей.
«Слетели драйвера», «У меня нет драйверов на принтер», «Видеокарте нужны драйвера» — если вам непонятно, что это значит и на что влияют драйверы, то эта статья для вас.
Что такое драйвер
Драйвер — это программа, которая работает как инструкция для операционной системы. Драйвер объясняет операционке, как пользоваться каким-то устройством.
Устройство — это то, что физически подключается к компьютеру:
- видеокарта,
- мышь,
- криптотокен,
- монитор,
- сканер,
- джойстик для игр.
Драйвер рассказывает компьютеру, как этим железом пользоваться, что оно умеет, какие команды понимает и как это железо могут использовать другие программы.
👉 Технически драйвер — это программа, которая висит в памяти компьютера всё время, пока компьютеру нужно это устройство.
Известное и неизвестное железо
Операционная система в компьютере знает и умеет многое, в том числе и работать со стандартным оборудованием. Стандартным — это значит тем, которое предоставляет стандартные возможности.
Например, клавиатура, мышь или веб-камера — это стандартное оборудование, потому что независимо от производителя они делают примерно одно и то же.
Разработчики операционной системы знают про такое оборудование, поэтому могут написать стандартные драйверы, которые подойдут к большинству устройств. Именно поэтому мы можем купить в магазине новую мышь и просто подключить её к компьютеру без установки дополнительных программ — операционная система сама разберётся, что делать.
Но бывает так, что разработчики добавили в устройство нестандартные возможности: переназначение сочетаний клавиш, сделали мышь с несколькими колёсиками или встроенный лазерный дальномер в видеокамеру. В этом случае компьютер не разберётся, как этим всем пользоваться, потому что в стандартных драйверах про это ничего нет.
В таких случаях разработчики устройств пишут свой драйвер, который объяснит компьютеру, как пользоваться всеми возможностями устройства. Этот драйвер нужно будет установить.
Сложное оборудование
Ещё бывает так, что оборудование хоть и стандартное, но сложное, например, видеокарта или принтер. Каждый производитель добавляет свои функции и технологии, которые считает нужными, и чаще всего они не совпадают с другими. Если подключить такое устройство к компьютеру, то компьютер, скорее всего, разберётся, что именно в него воткнули, то как с этим работать — неизвестно.
Здесь тоже нужны драйверы — они идут или в комплекте с устройством на компакт-диске или их качают с официального сайта производителя. Чем сложнее устройство, тем больше вероятность, что без установки дополнительных драйверов оно работать не будет.
Например, если у вас навороченная видеокарта, вы вставляете её в компьютер и сначала видите странную огромную картинку с низким разрешением. Это значит, что компьютер пока не нашёл драйверов на эту карточку и запустил её в «режиме совместимости» — то есть в том режиме, в котором он точно сможет ей управлять. Но возможности видеокарты будут сильно порезаны, пока мы не установим нужные нам драйверы.
Что значит «слетели драйвера»?
Это значит, что компьютер не может найти файлы с инструкциями от какого-то устройства. Так бывает при обновлениях системы, заражении вирусом или просто кто-то случайно мог удалить нужные файлы или папку целиком.
Решение простое: берёте заново драйвер с официального сайта или тот, который шёл в комплекте с устройством, и запускаете программу-установщик заново. А она уже сама разберётся, каких файлов не хватает, и настроит всё заново.
Драйверы нужны только на Windows?
Драйверы нужны на всех компьютерах и для всех операционных систем. Но некоторые операционки идут с кучей драйверов в комплекте, а у других этот набор более скромный.
Общее правило для 2021 года такое: большая часть оборудования, которое нужно для обычной офисной работы, подключится к любому компьютеру без необходимости что-то устанавливать. Операционка сама поймёт, что это за устройство, и, скорее всего, у неё уже будут драйверы.
А вот какое-то более сложное оборудование (например, профессиональная аудиокарта или видеокамера) потребуют установки драйверов от производителя.
В чём проблема с драйверами
Проблема в том, что часто производители не делают новые драйверы для старого оборудования. Например:
Есть диджейский контроллер Numark NS7 — это профессиональное оборудование для диджеев и артистов, оно стоит дорого и нужно примерно 100 тысячам человек на всей планете.
Когда контроллер только вышел, компания Numark выпускала драйвера на все свежие операционные системы, проблем с совместимостью не было.
Потом аппарат сняли с производства, поддержку прекратили. Последняя версия драйверов, которую выпустил Numark, — для Windows 10 и MacOS 10.12 (Sierra). С тех пор у Windows вышло большое обновление до 11, а MacOS обновился раз пять. Причём последние две версии сделаны для процессоров Apple, и уже нет надежды, что Numark обновит драйверы для этой архитектуры.
Так что, если вам достался этот редкий профессиональный прибор, вы вынуждены сидеть на древней MacOS Sierra, которая стремительно перестаёт поддерживаться современным софтом.
Практически каждый пользователь компьютера и ноутбука при первой установке/переустановке Windows или подключении к системе нового устройства/железа — сталкивается с термином драйвер.
Прочитав прошлую публикацию, вы могли узнать про дефрагментацию диска, эта же статья будет посвящен определению, что такое драйверы в информатике и какую функцию они выполняют для операционной системы.
Что такое драйвер
Драйвер (driver) — это программное обеспечение для операционной системы, чтобы она могла взаимодействовать с подключенным к компьютеру/ноутбуку аппаратным обеспечением. Это может быть принтер, видеокарта, звуковая карта и т.д. С английского языка переводится, как «проводник».
Другими словами — это проводник, который позволяет общаться между собой устройству и операционной системе.
Также, такое ПО может быть только имитацией подключенного устройства. Например, если вы захотите распечатать какой-либо документ, но самого принтера у вас нет, то его можно будет «распечатать» через имитируемый программой-драйвером принтер в файл pdf.
Для чего нужен драйвер
Драйверы являются неотъемлемой частью операционной системы. Без них она попросту не будет работать, ведь именно они обеспечивают взаимодействие между всем аппаратным обеспечением компьютера и ОС. Но, вы можете этого даже не заметить, т.к. при первом запуске Windows все уже исправно функционирует.
А происходит это, потому что такое программное обеспечение для ключевых компонентов системы — процессор, клавиатура, монитор и т.д. уже по умолчанию есть в самой Windows и автоматически устанавливается вместе с самой ОС. Но, для некоторых устройств (принтер, сканер, видеокарта и других) нужно устанавливать свое ПО, которое обычно выпускает сам производитель.
Простыми словами, без установленной для устройства программы-драйвера, например, для сканера — он попросту не будет работать.
Интересно! При подключении к ПК/ноутбуку какого-либо нового оборудования Windows автоматически начинает поиск подходящего для него ПО.
Как посмотреть установленные драйверы на компьютере с Windows
В ОС Windows 10, 8, 8.1 и 7 их список можно посмотреть в диспетчере устройств. Чтобы открыть его разом нажмите клавиши «WIN + R» на клавиатуре и вбейте команду devmgmt.msc.
Откроется окно со списком аппаратных средств системы, разделенных по категориям. Так раскрыв определенную категорию и открыв какой-либо компонент, можно перейти по вкладке «Драйвер» и посмотреть сведения о нем.
Если вы увидите, устройство с восклицательным знаком — значит программное обеспечение к нему работает неправильно или вообще отсутствует. Его будет необходимо переустановить/установить.
Важно! Подробнее прочитать про установку драйверов можно в соответствующей статье. Там же вы найдете подробную инструкцию по их поиску и автоматической установке с помощью специальных программ.
В заключение
Надеюсь, прочитав данный материал, вы подчерпнули для себя, что-то новое и главное, нужное. Постарался все объяснить, как можно более простыми словами. Заходите почаще, будет еще много полезных и интересных статей.
Читайте также: