Дополнительные возможности файловых систем. Специальные файлы и аппаратные драйверы.
Понятие «специальный файл» появилось в ОС UNIX. Специальный (виртуальный) файл связан с некоторым устройством ввода-вывода и представляет его для остальной части ОС и прикладных процессов в виде неструктурированного набора байт, то есть в виде обычного файла, но в отличие от обычного файла специальный файл не хранит статичные данные, а является интерфейсом к одному из аппаратных драйверов ОС. Использование специальных файлов упрощает программирование операций с внешними устройствами. Со специальным файлом можно работать так же, как и с обычным, для этого используются привычные системные вызовы для работы с обычными файлами. Кроме того, имеется несколько системных вызовов, используемых только при работе со специальными файлами, например вызов loctl, с помощью которого можно передать команду контроллеру устройства. Для устройств прямого доступа имеет смысл также указатель текущего положения в файле, которым можно управлять с помощью системного вызова lseek.
Представление устройства в виде файла и использование для управления устройством файловых системных вызовов позволяет выполнять только простые операции управления, которые сводятся к передаче в устройство последовательности байт. Для некоторых устройств такие операции вполне адекватны — в основном это устройства, отображающие или принимающие от пользователя строки символов. Форматирование ввода-вывода в устройствах этого класса осуществляется с помощью служебных символов начала кодовой таблицы и их последовательностей, например для перевода строки и возврата каретки принтера или терминала достаточно к последовательности символов текста добавить восьмеричные коды <12> <15>.
Для устройств с более сложной организацией информации (графических дисплеев) от управляющего интерфейса требуется поддержка более сложных операций, таких как заполнение цветом области или вывод на экран основных графических примитивов. Тем не менее файловый интерфейс, оперирующий только с неструктурированным потоком байт, оказывается полезным и для устройств со сложной организацией информации. Такой интерфейс в силу своей простоты и универсальности дает возможность строить над ним другой, более сложный интерфейс с произвольной организацией.
Файловый интерфейс доступен пользователю, поэтому прикладной программист может воспользоваться им для создания собственного интерфейса к какому-либо устройству, обходя лежащие над аппаратным драйвером данного устройства слои высокоуровневых драйверов.
В UNIX специальные файлы традиционно помещаются в каталог /dev, хотя ничто не мешает созданию их в любом каталоге файловой системы. При появлении нового устройства и, соответственно, нового драйвера администратор системы может создать новую запись с помощью команды mknod. Связь специального файла с драйвером устанавливается за счет информации, находящейся в индексном дескрипторе специального файла. Во-первых, в индексном дескрипторе хранится признак того, что файл специальный, причем этот признак позволяет различить класс соответствующего устройству драйвера, то есть он определяет, является ли драйвер байт-ориентированным или блок-ориентированным. Во-вторых, в индексном дескрипторе хранится адресная информация, позволяющая выбрать нужный драйвер и нужное устройство. Эта информация заменяет стандартную адресную информацию обычного файла, состоящую из номеров блоков файла на диске.
Адресная информация специального файла состоит из двух элементов:
- major — номер драйвера;
- minor — номер устройства.
Значение major определяет выбор драйвера, обслуживающего данный специальный файл, а значение minor передается драйверу в качестве параметра вызова и указывает ему на одно из нескольких однотипных устройств, которыми драйвер может управлять. Например, для дисковых драйверов номер устройства задает не только диск, но и раздел на диске. ОС UNIX использует для хранения информации об установленных аппаратных драйверах две системные таблицы:
- bdevsw — таблица блок-ориентированных драйверов;
- cdevsw — таблица байт-ориентированных драйверов.
Номер драйвера – индекс соответствующей таблицы. При открытии специального файла ОС обнаруживает, что она имеет дело со специальным файлом только после того, как прочитает с диска или найдет в системном буфере его индексный дескриптор. При этом она узнает, является ли вызываемый драйвер блок- или байт-ориентированным, после чего использует номер драйвера для обращения к определенной строке одной из двух таблиц: bdevsw или cdevsw. Эти таблицы содержат адреса программных секций драйверов, причем одна строка таблицы описывает один драйвер. Такая организация логической связи между ядром UNIX и драйверами позволяет легко настраивать систему на новую конфигурацию внешних устройств путем модификации таблиц.
Концепция специальных файлов ОС UNIX была реализована во многих ОС, хотя для связи с драйверами в них часто используются другие механизмы.