В операционных системах типа Unix файл устройства , узел устройства или специальный файл — это интерфейс к драйверу устройства , который отображается в файловой системе так, как если бы это был обычный файл . Специальные файлы также есть в DOS , OS/2 и Windows . Эти специальные файлы позволяют прикладной программе взаимодействовать с устройством, используя его драйвер устройства через стандартные системные вызовы ввода-вывода . Использование стандартных системных вызовов упрощает многие задачи программирования и приводит к согласованным механизмам ввода-вывода в пользовательском пространстве независимо от характеристик и функций устройства.
Файлы устройств обычно предоставляют простые интерфейсы для стандартных устройств (таких как принтеры и последовательные порты), но также могут использоваться для доступа к определенным уникальным ресурсам на этих устройствах, таким как разделы диска . Кроме того, файлы устройств полезны для доступа к системным ресурсам , которые не связаны ни с одним реальным устройством, таким как приемники данных и генераторы случайных чисел .
В операционных системах типа Unix есть два основных типа файлов устройств, известные как специальные файлы символов и специальные файлы блоков . Разница между ними заключается в том, сколько данных считывается и записывается операционной системой и оборудованием. Вместе их можно назвать специальными файлами устройств в отличие от именованных каналов , которые не подключены к устройству, но и не являются обычными файлами.
MS-DOS заимствовала концепцию специальных файлов из Unix, но переименовала их в устройства . [1] Поскольку ранние версии MS-DOS не поддерживали иерархию каталогов , устройства отличались от обычных файлов, делая их имена зарезервированными словами , которые не могут использоваться в качестве имен папок или файлов; например: слово CON
является зарезервированным словом. Они были выбраны для определенной степени совместимости с CP/M и все еще присутствуют в современной Windows для обратной совместимости. Имена не чувствительны к регистру, поэтому «con», «Con» и «CON» являются недопустимыми именами.
В Windows XP ввод «Con» в команду «Выполнить» возвращает сообщение об ошибке: «Этот файл не имеет программы, связанной с ним для выполнения этого действия. Создайте связь в панели управления «Параметры папки». Попытка переименовать любой файл или папку с использованием зарезервированного имени автоматически возвращает объект к его предыдущему имени (или «Новая папка», «Новый текстовый документ» и т. д.) без уведомления или сообщения об ошибке. [2] В Windows Vista и более поздних версиях попытка использовать зарезервированное имя для файла или папки приводит к сообщению об ошибке: «Указанное имя устройства недопустимо». [2]
В некоторых Unix-подобных системах большинство файлов устройств управляются как часть виртуальной файловой системы , традиционно монтируемой в /dev
, возможно, связанной с управляющим демоном, который отслеживает добавление и удаление оборудования во время выполнения, внося соответствующие изменения в файловую систему устройства, если это не делается автоматически ядром, и, возможно, вызывая скрипты в системном или пользовательском пространстве для обработки особых потребностей устройства. FreeBSD , DragonFly BSD и Darwin имеют выделенную файловую систему devfs ; узлы устройств автоматически управляются этой файловой системой в пространстве ядра . Linux раньше имел похожую реализацию devfs , но позже от нее отказались, а затем удалили с версии 2.6.17; [3] Linux теперь в основном использует реализацию пользовательского пространства , известную как udev , но существует множество вариантов.
В системах Unix, которые поддерживают изоляцию процесса chroot , таких как Solaris Containers , обычно каждой среде chroot требуется своя собственная /dev
; эти точки монтирования будут видны на хостовой ОС на различных узлах в глобальном дереве файловой системы. Ограничивая узлы устройств, заполняемые в экземплярах chroot /dev
, среда chroot может принудительно обеспечивать изоляцию оборудования (программа не может вмешиваться в оборудование, которое она не может ни видеть, ни называть — еще более сильная форма контроля доступа , чем разрешения файловой системы Unix ).
MS-DOS управляла конфликтом устройств оборудования (см. terminate-and-stay-resident program ), делая каждый файл устройства исключительно открытым. Приложение, пытающееся получить доступ к уже используемому устройству, обнаружило бы, что не может открыть узел файла устройства. Разнообразие семантики драйверов устройств реализовано в Unix и Linux относительно параллельного доступа . [4]
Узлы устройств соответствуют ресурсам, которые ядро операционной системы уже выделило. Unix идентифицирует эти ресурсы по основному номеру и дополнительному номеру , [5] оба хранятся как часть структуры узла . Назначение этих номеров происходит уникально в разных операционных системах и на разных компьютерных платформах . Как правило, основной номер идентифицирует драйвер устройства, а дополнительный номер идентифицирует конкретное устройство (возможно, из многих), которым управляет драйвер: [6] в этом случае система может передать дополнительный номер драйверу. Однако при наличии динамического распределения номеров это может быть не так (например, во FreeBSD 5 и выше).
Как и в случае с другими специальными типами файлов, компьютерная система получает доступ к узлам устройств с помощью стандартных системных вызовов и обрабатывает их как обычные компьютерные файлы. Существуют два стандартных типа файлов устройств; к сожалению, их названия довольно нелогичны по историческим причинам, и объяснения разницы между ними часто неверны.
Специальные файлы символов или символьные устройства обеспечивают небуферизованный прямой доступ к аппаратному устройству. Они не обязательно позволяют программам считывать или записывать отдельные символы за раз; это зависит от рассматриваемого устройства. Символьное устройство для жесткого диска, например, обычно требует, чтобы все операции чтения и записи были выровнены по границам блоков и, скорее всего, не позволит считывать ни одного байта.
Символьные устройства иногда называют « сырыми устройствами», чтобы избежать путаницы, связанной с тем фактом, что символьное устройство для блочного оборудования обычно требует программ для чтения и записи выровненных блоков.
Специальные файлы блоков или блочные устройства предоставляют буферизованный доступ к аппаратным устройствам и предоставляют некоторую абстракцию от их специфики. [7] В отличие от символьных устройств, блочные устройства всегда позволяют программисту читать или записывать блок любого размера (включая отдельные символы/байты) и любого выравнивания. Недостатком является то, что поскольку блочные устройства буферизованы, программист не знает, сколько времени пройдет, прежде чем записанные данные будут переданы из буферов ядра на фактическое устройство, или в каком порядке две отдельные записи поступят на физическое устройство. Кроме того, если одно и то же оборудование предоставляет как символьные, так и блочные устройства, существует риск повреждения данных из-за того, что клиенты, использующие символьное устройство, не знают об изменениях, внесенных в буферы блочного устройства.
Большинство систем создают как блочные, так и символьные устройства для представления оборудования, например, жестких дисков. FreeBSD и Linux, в частности, этого не делают; первая удалила поддержку блочных устройств, [8] тогда как последняя создает только блочные устройства. Чтобы получить эффект символьного устройства из блочного устройства в Linux, нужно открыть устройство с флагом O_DIRECT, специфичным для Linux .
Узлы устройств в Unix-подобных системах не обязательно должны соответствовать физическим устройствам . Узлы, не имеющие такого соответствия, называются псевдоустройствами . Они предоставляют различные функции, обрабатываемые операционной системой. Некоторые из наиболее часто используемых (символьных) псевдоустройств включают:
Кроме того, псевдоустройства BSD с интерфейсом ioctl могут также включать:
Узлы создаются системным вызовом mknod . Программа командной строки для создания узлов также называется mknod . Узлы можно перемещать или удалять обычными системными вызовами файловой системы ( rename , unlink ) и командами ( mv , rm ).
Некоторые версии Unix включают скрипт с именем makedev или MAKEDEV для создания всех необходимых устройств в каталоге /dev . Это имеет смысл только в системах, устройствам которых статически назначены основные номера (например, путем жесткого кодирования в модуле ядра).
Некоторые другие системы Unix, такие как FreeBSD, используют управление узлами устройств на основе ядра только через devfs и не поддерживают ручное создание узлов. Системный вызов mknod(2) и команда mknod(8) существуют для обеспечения совместимости с POSIX, но созданные вручную узлы устройств вне devfs вообще не будут работать. [10]
Для обозначения типа устройства в именах некоторых устройств в иерархии /dev используются следующие префиксы:
В некоторых операционных системах стали широко использоваться некоторые дополнительные префиксы:
Канонический список префиксов, используемых в Linux, можно найти в Linux Device List , официальном реестре выделенных номеров устройств и узлов каталога /dev для операционной системы Linux. [11]
Для большинства устройств за этим префиксом следует номер, однозначно идентифицирующий конкретное устройство. Для жестких дисков буква используется для идентификации устройств, а за ней следует номер для идентификации разделов . Таким образом, файловая система может «знать» область на диске как /dev/sda3 , например, или «видеть» сеанс сетевого терминала как связанный с /dev/pts/14 .
На дисках, использующих типичную главную загрузочную запись ПК , номера устройств основного и дополнительного расширенного раздела нумеруются от 1 до 4, в то время как индексы любых логических разделов — от 5 и далее, независимо от компоновки предыдущих разделов (их родительский расширенный раздел не обязательно должен быть четвертым разделом на диске, и не обязательно должны существовать все четыре основных раздела).
Имена устройств обычно непереносимы между различными вариантами Unix-подобных систем, например, в некоторых системах BSD устройства IDE называются /dev/wd0 , /dev/wd1 и т. д.
devfs — это конкретная реализация файловой системы устройств в операционных системах типа Unix, используемая для представления файлов устройств. Базовый механизм реализации может различаться в зависимости от ОС.
Хранить эти специальные файлы в физически реализованной файловой системе, такой как жесткий диск, неудобно, и поскольку для этого в любом случае требуется помощь ядра, возникла идея создания специальной логической файловой системы, которая не хранится физически.
Определение того, когда устройства готовы к появлению, не является тривиальной задачей. Подход devfs заключается в том, что драйвер устройства запрашивает создание и удаление записей devfs, связанных с устройствами, которые он включает и отключает.
Файл устройства — это зарезервированное ключевое слово, используемое в системах PC DOS , TOS , OS/2 и Windows для разрешения доступа к определенным портам и устройствам.
MS-DOS заимствовала концепцию специальных файлов из Unix, но переименовала их в устройства . [1] Поскольку ранние версии MS-DOS не поддерживали иерархию каталогов , устройства отличались от обычных файлов, делая их имена зарезервированными словами . Это означает, что определенные имена файлов были зарезервированы для устройств и не должны использоваться для именования новых файлов или каталогов. [12]
Сами зарезервированные имена были выбраны для совместимости с обработкой PIP
команд «специальными файлами» в CP/M . В DOS было два вида устройств: блочные устройства (используемые для дисководов) и символьные устройства (обычно все остальные устройства, включая устройства COM и PRN). [13]
DOS использует файлы устройств для доступа к принтерам и портам. Большинство версий Windows также поддерживают эту поддержку, что может вызвать путаницу при попытке создания файлов и папок с определенными именами, поскольку они не могут иметь эти имена. [14] Версии 2.x MS-DOS предоставляют параметр AVAILDEV
CONFIG.SYS , который, если установлен в FALSE
, делает эти специальные имена активными только с префиксом \DEV\
, таким образом позволяя создавать обычные файлы с этими именами. [15]
GEMDOS , DOS-подобная часть Atari TOS , поддерживала похожие имена устройств в DOS, но в отличие от DOS требовала завершающий символ ":" (в DOS это необязательно) для идентификации их как устройств, а не обычных имен файлов (таким образом, "CON:" будет работать как в DOS, так и в TOS, но "CON" будет называть обычный файл в TOS, но консольное устройство в DOS). В MiNT и MagiC , специальное UNIX-подобное унифицированное представление файловой системы, доступ к которому осуществлялся через букву диска "U:", также помещало файлы устройств в "U:\DEV".
Используя перенаправление оболочки и каналы, данные могут быть отправлены на устройство или получены с него. Например, ввод следующего текста отправит файл c:\data.txt
на принтер:
ТИП c:\data.txt > PRN
Другими стандартными устройствами Windows являются PIPE, MAILSLOT и MUP. [21]
8-битная операционная система карманных компьютеров Sharp , таких как PC-E500 , PC-E500S и т. д., состоит из интерпретатора BASIC , системы управления файлами (FCS) типа DOS 2, реализующей элементарную 12-битную файловую систему типа FAT, и системы управления вводом/выводом (IOCS) типа BIOS, реализующей ряд стандартных драйверов символьных и блочных устройств, а также специальных файловых устройств, включая STDO:/SCRN: (дисплей), STDI:/KYBD: (клавиатура), COM: (последовательный ввод/вывод), STDL:/PRN: (принтер), CAS: (кассета), E:/F:/G: (файл памяти), S1:/S2:/S3: (карта памяти), X:/Y: (дискета), SYSTM: (система) и NIL: (функция). [22]
Следующий шаг за пределами устройства с одним открытым устройством — позволить одному пользователю открывать устройство в нескольких процессах, но разрешить только одному пользователю открывать устройство в каждый момент времени.
Devfsd обеспечивает настраиваемое управление узлами устройств с помощью файловой системы устройств Linux.