Поддержка операций ввода/вывода - это еще одна функция операционной системы. В многопользовательских ОС, где доступ к ресурсам системы и сервису I/O требуется нескольким клиентам одновременно, эта задача значительно усложняется. Linux имеет свои собственные принципы организации ввода/вывода.
Для пользователя операции ввода/вывода в Linux сходны с файловыми операциями. В ОС Linux понятие файла весьма обширно - устройства ввода/вывода также считаются файлами и доступ к ним аналогичен операции открытия файла. Драйверы устройств представляются как обычные файлы. В файловой системе есть особая категория файлов, создавать которые разрешено лишь администратору системы. Это файлы, содержащие ссылки на драйверы конкретных устройств. На такие файлы распространяются обычные механизмы защиты. В зависимости от имеющихся разрешений доступа к подобным файлам пользователи получают права на чтение/запись на соответствующие устройства. На рис.10 представлена структура драйверов в Linux.
Рис 10. Структура драйверов Linux
Linux различает три класса устройств:
Блочные устройства - устройства с произвольным доступом к независимым блокам данных фиксированного размера. К ним относятся жесткие и гибкие диски, CD-ROM. Блочные устройства обычно используются для хранения файловых систем. Программам разрешен прямой доступ к подобным устройствам для создания и восстановления файловых систем.
Интерфейс блочных устройств является основным интерфейсом дисковых устройств системы, основывающимся на двух основных системных компонентах:
• Блочный кэш буфер (block buffer cache) - буферный пул для текущего ввода/вывода и кэш для завершения операции ввода/вывода. Буферный кэш включает в себя:
• Буферы - набор страниц переменного размера, распределяемых напрямую из пула основной памяти ядра. Каждая из страниц, в свою очередь, делится на несколько буферов одинакового размера.
• Дескрипторы буферов (buffer_heads) - по одному для каждого буфера в кэше.
• Управление буферами на уровне ядра отвечает за запись буферов на диск.
• Менеджер запросов (request manager) - уровень программных средств, управляющий операциями чтения/записи одержимого буферов в драйвер блочного устройства.
Символьные устройства - все остальные устройства, за исключение сетевых, т.е. устройства, обмен с которыми производится посимвольно (например, мышь). Драйвером символьного устройства может быть любой драйвер, не поддерживающий произвольного доступа к блокам данных. При загрузке символьные драйверы регистрируются ядром Linux. Определяется набор описывающих ввод/вывод и поддерживаемых драйвером функций. Поступающий в ядро системы запрос на чтение/запись перенаправляется символьному устройству, которое и осуществляет его обработку.
Обработка символьных драйверов, представляющих терминалы, несколько отличается. Для поддержки стандартного интерфейса с такими драйверами ядро содержит ряд структур "tty-struct", выполняющих двойную функцию.
• буферизацию и контроль потока данных с терминала
• передачу данных алгоритму реализации стратегии канала (line discipline).
Алгоритм реализации стратегии канала - это интерпретатор данных, поступающих с терминала. Наиболее распространенным алгоритмом является tty, позволяющий привести поток данных с терминала к стандартному потоку ввода/вывода пользовательского процесса. Вследствие реализуемых преобразований процессы могут напрямую взаимодействовать с терминалами.
Сетевые устройства - обеспечивают поддержку сетевых функций системы. Пользователи не имеют разрешений на прямую передачу данных в сетевые устройства, доступ к ним осуществляется через подсистему поддержки сети, находящуюся в ядра.