Внешний и внутренний интерфейсы устройств
Независимо от типа файла (обычный файл, каталог, связь или специальный файл) пользовательский процесс может работать с файлом через стандартный интерфейс, включающий системные вызовы open, close, read и write. Ядро само распознает, нужно ли обратиться к его стандартным функциям или вызвать подпрограмму драйвера устройства. Другими словами, если процесс пользователя открывает для чтения обычный файл, то системные вызовы open и read обрабатываются встроенными в ядро подпрограммами open и read соответственно. Однако, если файл является специальным, то будут вызваны подпрограммы open и read, определенные в соответствующем драйвере устройства (рисунок 2.3).
Кратко поясним этот рисунок. С каждым специальным файлом в системе связаны старший (major) и младший (minor) номера. После того, как (по содержанию i-узла) файловая система распознает, что данный файл является специальным, ядро ОС UNIX использует старший номер специального файла как индекс в конфигурационной таблице драйверов устройств. Поддерживаются две раздельные таблицы для символьных и блочных специальных файлов (или соответствующих драйверов). Для блочных драйверов используется системная таблица bdevsw, а для символьных - cdevsw. В обоих случаях элементом таблицы является структура (в терминах языка программирования Си), элементы которой содержат указатели на подпрограммы соответствующего драйвера. Допускается (и на самом деле используется) реализация драйверов, которые одновременно могут обрабатывать и блочный, и символьный ввод/вывод. В этом случае для драйвера будут существовать и элемент таблицы bdevsw, и таблицы cdevsw.
Рис. 2.3. Логическое представление открытия специального символьного файла
Старшему номеру специального файла блочного или специального файла, вообще говоря, соответствуют разные драйверы. Например, символьному специальному файлу /dev/tty и блочному специальному файлу /dev/swap в UNIX System V соответствует старший номер 6. Но поскольку первый специальный файл - символьный, а второй - блочный, они могут использовать один и тот же старший номер, хотя им соответствуют разные драйверы. В любом случае, младший номер специального файла передается в качестве параметра соответствующей функции драйвера, который волен использовать его любым образом, хотя обычно младший номер используется в качестве номера устройства, обслуживаемого аппаратным контроллером, которым на самом деле управляет данный драйвер. Другими словами, один драйвер как программная единица может управлять несколькими физическими устройствами.