Найти в Дзене
IT. Как это работает?

От транзистора до фреймворка. Часть 21. Драйвер устройства

Оглавление

Видео: YouTube

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

Прерывания

Как мы ранее выяснили, прерывания делятся на аппаратные, поступающие с устройств и программные, вызываемые приложением пользователя.

Виды прерываний
Виды прерываний

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

Линии прерываний
Линии прерываний

По номеру прерывания из таблицы векторов прерываний изымается адрес обработчика и помещается в регистр счетчика инструкций.

Вызов обработчика прерывания
Вызов обработчика прерывания

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

Цепочка вызовов перед программным прерыванием
Цепочка вызовов перед программным прерыванием

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

Общая схема функционирования драйвера устройства
Общая схема функционирования драйвера устройства

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

Место драйвера в программном обеспечении

На данном рисунке изображены рассмотренные ранее слои программного обеспечения.

Слои программного обеспечения
Слои программного обеспечения

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

Унифицированный интерфейс драйвера устройства
Унифицированный интерфейс драйвера устройства

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

Слой аппаратных абстракций

Теперь рассмотрим таинственный слой функций аппаратных абстракций. Зачем же он нужен? Как мы рассмотрели ранее, никакой исполняемый код не обращается к устройству напрямую. Все устройства подключены к некоторой системной шине. У функций ядра есть возможность работы с регистрами контроллера системной шины, как с областью памяти, расположенной за пределами 56 килобайт адресного пространства.

Проекция контроллера шины на адресное пространство операционной системы
Проекция контроллера шины на адресное пространство операционной системы

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

Использование функции аппаратной абстракции
Использование функции аппаратной абстракции

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

Цепочка вызовов функций

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

Цепочка вызовов функций
Цепочка вызовов функций

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

Еще параметрами API функции являются указатель на буфер buf, куда полученные с устройства данные будут направлены и количество байт count, которые необходимо считать. Именно по этому указателю будут перемещены считанные данные из адресного пространства ядра в адресное пространство пользовательского процесса. До этого момента программный код выполнялся в контексте пользовательского приложения. Но с вызовом программного прерывания контекст пользовательского процесса меняется на контекст ядра операционной системы. Функция ядра, получив дескриптор файла, находит в таблице дескрипторов адреса функций обработчиков прерываний. Выбранный конкретный обработчик прерывания обращается к контроллеру шины через предоставляемую слоем аппаратных абстракций функцию. Как только самая последняя функция добралась до данных на устройстве, начинается выходы из всей цепочки функций. Таким образом, на подобном простом примере мы рассмотрели вопрос работы драйвера устройства и его место в архитектуре слоев программного кода.

Сравнительная оценка производительности  ввода/вывода данных

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

Сравнительное время доступа к памяти и твердотельному накопителю
Сравнительное время доступа к памяти и твердотельному накопителю

По строкам в ней описаны некоторые операции, производимые компьютером. В среднем столбце реальное примерное время выполнение операции. Так, доступ к кэш памяти первого уровня, на сколько мы помним из статьи про память, происходит на максимально возможной частоте работы процессора. Доступ к этой памяти может быть осуществлен за половину наносекунды. Для человеческого восприятия это очень малая величина. Доступ к оперативной памяти происходит за величину примерно в сто наносекунд. Это тоже очень быстро чтоб осознать человеку. Пропорционально увеличим все время во столько раз, чтобы длительность обращения к кэш памяти составило 1 секунду. Такой короткий временной промежуток человек вполне способен осознать.
С учетом пропорционального увеличения времени,  обращение к оперативной памяти теперь происходит за почти что три с половиной минуты. Это длительность музыкального трека.
Дальше больше. Рассматриваем операцию доступа к данным на устройстве твердотельного накопителя SSD. Такой накопитель на основе флэш памяти без вращающихся и двигающихся механических частей по идее должен быть быстр. И мы так все считаем, это же SSD, это скорость. Необходимо отметить, что доступ к такому устройству осуществляется при помощи драйвера или даже цепочки драйверов. В принятой системе измерения времени —  три дня на операцию чтения одной страницы памяти размером 4 килобайта.  А давайте считаем 1 мегабайт данных. И это в нашем замедленном мире будет длиться 23 дня. Откуда такие задержки? При отсутствии явных признаков движущихся механических частей в носителе информации, можно обвинять только таинственную жизнь электронов на пути от устройства до процессора. А ведь без обмена данными с внешним миром вычислительная система просто бесполезна. Мы плавно подходим к таким вопросам как многозадачность и многопоточность. Только эти понятия способны объяснить почему наши компьютеры все еще справляются со своими задачами. Кроме того, рассмотренные основы этих вопросов откроют путь к синхронной и асинхронной обработке, очередям и
callback функциям. А это уже совсем современность и последний писк моды.

Продолжение следует...