Система ввода/вывода в LINUX.
В системе ввода/вывода все внешние устройства рассматриваются как файлы, над которыми допускается производить обычные файловые операции. Конечно, существуют и драйверы устройств, но интерфейс с ними оформлен для пользователя как обращение к специальному файлу. Специальные файлы являются средством унификации системы ввода/вывода.
Каждому подключенному устройству (терминалу, дискам, принтеру и т. д.), соответствует, как минимум, один специальный файл. Большая часть этих специальных файлов хранится в каталоге /dev:
$ cd /dev
$ ls -l
onsole пульт управления системы
dsk порции на диске
fd0 флоппи-диск 1
mem память
lр принтер
lр0 параллельный порт 0
. . .
root порция на диске для корневой файловой системы
swap своп-порция
syscon альтернативное имя пульта
systty еще одно имя для системной консоли
term директория для терминалов
ttyS0 серийный порт 0 (COM1)
. . .
Когда программа выполняет запись в такой специальный файл, то ОС система перехватывает их и направляет на устройство, например принтер). При чтении данных из такого типа файла в действительности они принимаются с устройства, например, с диска. Программа не должна учитывать особенности работы устройства ввода/вывода. Для этой цели и служат специальные файлы (драйверы), которые выполняют функции интерфейса между компонентами ядра ОС и прикладными программами общего назначения.
Система обнаруживает отличие обычного файла от специального только после того, как будет проанализирован соответствующий индексный дескриптор, на который ссылается запись в каталоге.
Индексный дескриптор специального файла содержит информацию о классе устройства, его типе и номере. Класс устройства определяет устройства с посимвольным обменом и с поблочным обменом. Примером устройства с посимвольным обменом может служить клавиатура. Специальные файлы, обеспечивающие связь с устройствами такого типа, называют байт-ориентированными. Для блочных устройств характерен обмен большими блоками информации, это ускоряет обмен и делает его более эффективным. Все дисковые устройства поддерживают блочный обмен, а специальные файлы, обслуживающие их, называют блок-ориентированными. Специальные файлы не содержат какой-либо символьной информации, поэтому в листинге каталога их длина не указывается.
Тип и номер устройства, также являются основными характеристиками специальных файлов (в поле длины помещаются главный и дополнительный номера соответствующего устройства). Первый из них определяет тип устройства, второй — идентифицирует его среди однотипных устройств. ОС может одновременно обслуживать несколько десятков, и даже сотни терминалов. Каждый из них должен иметь свой собственный специальный файл, поэтому наличие главного и дополнительного номеров позволяет установить требуемое соответствие между устройством и таким файлом.
На одном диске можно создать несколько файловых систем. Некоторые системы используют по одной файловой системе на диске, а другие — по несколько. Новую файловую систему можно создать с помощью команды mkfs (make file system). Например, выражение # /sbin/mkfs /dev/dsk/fl1 512 означает: создать на флоппи-диске b: размером в 512 блоков.
По желанию можно задать размер файловой системы в блоках и количество i-узлов (т. е. максимальное число файлов, которые могут быть сохранены в файловой системе). По умолчанию число i-узлов равно числу блоков, деленному на четыре. Максимальное число i-узлов в одной файловой системе 65 000. Если по некоторым причинам вам необходимо более 65000 i-узлов на диске, необходимо создать две или более файловые системы на этом диске.
Всякая файловая система может быть прикреплена (монтирована) к общему дереву каталогов, в любой его точке. Например, каталог / — это корневой (root) каталог системы, кроме этого, он является основанием файловой системы, которая всегда монтирована. Каталог /usr1 находится в каталоге /, но в данном случае является отдельной файловой системой от корневой файловой системы, так как все файлы в нем находятся на отдельной части диска или вообще на отдельном диске. Файловая система /usr1 — монтируемая файловая система — корень в точке, где каталог /usr1 существует в общей иерархии (рис. 1 и 2).
Рис. 1. Файловая система перед
монтированием /dev/dsk/os1
Рис. 2. Файловая система после
монтирования /dev/dsk/os1 как /usr/
Для монтирования файловой системы используется команда /sbin/mount. Эта команда разрешает расположить данную файловую систему везде в существующей структуре каталогов:
#/sbin/mount/dev/dsk/osl/usr1 монтирует /dev/dsk/osl на /usr1
#/sbin/mount/dev/dsk/flt/а монтирует /dev/dsk/flt на /а
Если нужно монтировать файловую систему на диски, которые должны быть защищены от записи, чтобы система была доступна только для чтения, необходимо добавить опцию — r к команде /sbin/mount.
Каталог, к которому прикрепляется монтируемая файловая система, должен быть в данный момент пустой, так как содержимое его будет недоступно, пока файловая система монтируется.
Чтобы получить информацию о файловых системах, которые смонтированы, например, на системе LINUX, можно использовать команду /sbin/mount без аргументов (рис. 3).
Рис. 3.
Эта команда выводит каталог, на который была смонтирована файловая система (например, usrl), устройство /dev, на котором она находится, час и дата, когда она была смонтирована. Для демонтирования файловой системы используется команда /sbin/umount, которая имеет обратное действие по отношению к команде mount. Она освобождает файловую систему и как бы вынимает ее целиком из структуры каталогов, так что все ее собственные файлы и каталоги становятся недоступны:
# /sbin/umount /b
# /sbin/umount /dev/dsk/0s2
Корневая файловая система не может быть демонтирована. Кроме того, команда umount не будет выполнена, если кто-нибудь использует файл из той файловой системы, которую пытаются демонтировать (это может быть даже простое пребывание пользователя в одном из каталогов демонтируемой файловой системы).
В командах mount и umount пользователь использует аббревиатуру физических дисковых устройств.
В LINUX дисковые устройства имеют своеобразные обозначения. В LINUX пользователь никогда не сталкивается с проблемой точного указания физического устройства, на котором располагается информация. В LINUX произвольное число внешних устройств может быть очень большим, поэтому, пользователь имеет дело только с именем каталога, в котором находятся нужные ему файлы. Все файловые системы монтируются один раз, как правило, при загрузке системы. На некоторые каталоги могут быть смонтированы файловые системы и с удаленных компьютеров.
Для физических устройств в LINUX существуют директории dsk и rdsk, которые содержат файлы, соответствующие дисковым устройствам. Обыкновенно имена файлов в этих директориях одинаковы и единственная разница между ними, что директория rdsk содержит дисковые устройства со специальным доступом (raw), который используют некоторые устройства системы для более быстрого доступа к диску. Одна типичная директория dsk содержит следующие устройства:
$ 1s /dev/dsk
0s0 1s0 c0t0d0s0 c0tld0s0 f0 f05q f13dt fld8d
0sl 1sl c0t0d0sl c0tld0sl f03d f05qt f13h fld8dt
0s2 1s2 c0t0d0s2 c0tld0s2 f03dt f0d8d f13ht fld8t
. . .
$
B системе LINUX дисковые устройства логически разделены на секции, подобно разделам определяемым в Partition Table MasterBoot MS DOS. Файлы 0s1, 0s2, 0s3 и т. д, соответствуют секциям первой, второй, третьей и т. д. диска с номером 0. Файлы 1s0, 1sl, 1s2 и т. д. соответствуют секциям первой, второй, третьей и т. д. диска с номером 1. Если система имеет больше дисков, секции будут пронумерованы ns0, nsl и т. д. для каждого диска с номером n.
Системы с большим количеством дисковых устройств используют следующую систему нумерации:
с controller d disk s section
где controller — номер контроллера диска; disk — номер диска; section -номер секции диска.
Так, 0s0 обычно эквивалентно c0t0d0s0, а 0sl — c0t0d0sl, и трехсимвольные имена секций — это просто сокращение для дискового контроллера с номером 0.
Файлы, имена которых начинаются с f, определяют различные виды гибких дисков. Каталог rmt содержит файлы на устройствах типа магнитная лента:
$ 1s /dev/rmt
c0s0 cls0 c3s0 ntape ntapel tape tapel
Файлы c0s0, cls0, c2s0 и c3s0 определяют четыре кассетных ленточных запоминающих устройства. Файлы tape и tapel определяют магнитные запоминающие устройства с двумя бобинами. Файлы, чьи имена начинаются с n, относятся к тем же устройствам, только лента не перематывается после использования, в то время как использование других файлов заставляет ленту перематываться, когда использующая ее программа заканчивает работу.
В некоторых системах эти файлы имеют другие названия, однако все они всегда находятся в /dev и словарь, который обычно приходит с системой, содержит подробное описание устройств и связанных с ними файлов.
Файловая система extX при операциях ввода/вывода использует буферизацию данных. При считывании блока информации ядро выдает запрос операции ввода/вывода на несколько расположенных рядом блоков. Такие операции сильно ускоряют извлечение данных при последовательном считывании файлов. При занесении данных в файл файловая система extX, записывая новый блок, заранее размещает рядом до 8 смежных блоков. Такой метод позволяет размещать файлы в смежных блоках, что ускоряет их чтение и дает возможность достичь высокой производительности системы.
Ввод и вывод в Linux
Система файлов Linux, ориентированная на устройства, осуществляет доступ к дисковой памяти с помошью двух кэшей:
- Данные хранятся в кэше страниц, который объединен с системой виртуальной памяти;
- Метаданные хранятся в буферном кэше, причем каждый кэш индексируется блоком диска.
Linux разбивает устройства на три класса: Блочные устройства допускают произвольный доступ к полностью независимым блокам данных фиксированного размера. Символьные устройства включают большую часть всех других устройств; они не нуждаются в поддержке функциональности обычных файлов. Сетевые устройства взаимодействуют с сетевой системой ядра. Модульная структура драйверов устройств в Linux изображена на рис. 1.5. Рис. 1.5. Модульная структура драйверов устройств. Блочные устройства обеспечивают основной интерфейс ко всем дисковым устройствам в системе. Блочный буферный кэш служит для двух основных целей:
- Как буферный пул для активного ввода-вывода
- Как кэш для завершенного ввода-вывода.
Менеджер запросов управляет чтением и записью содержимого буферов с помощью драйвера блочного устройства. Символьные устройства. Драйвер символьного устройства не поддерживает произвольный доступ к фиксированным блокам данных. Драйвер символьного устройства регистрирует набор функций, реализующих разнообразные требуемые операции ввода-вывода. Ядро не выполняет почти никакой предварительной обработки запроса на чтение или запись в файл символьного устройства, но просто передает данный запрос драйверу устройства. Основное исключение из этого правила – это особый набор драйверов символьных устройств, которые реализуют доступ к терминальным устройствам (TTY); для них ядро поддерживает стандартный интерфейс.
Взаимодействие процессов в Linux
Как и UNIX, Linux информирует процессы о наступлении событий с помощью сигналов. Существует ограниченный набор сигналов, и они не могут нести какую-либо информацию: только факт, что сигнал имеет место, доступен процессу. Ядро Linux не использует сигналы для коммуникации процессов, исполняемых в режиме ядра. Коммуникация внутри ядра осуществляется с помощью структур планировщика – states (состояния) и wait.queue (очередь ожидания). Механизм конвейера (pipe) позволяет дочернему процессу наследовать коммуникационный канал от процесса-родителя. Данные, записываемые с одного конца конвейера, могут быть прочитаны на другом конце. Общая память обеспечивает очень быстрый способ коммуникации; любые данные, записанные одним процессом в регион общей памяти, могут быть немедленно прочитаны любым другим процессом, который отобразил этот регион в свое адресное пространство. Однако с целью синхронизации общая память должна использоваться в сочетании с каким-либо другим комуникационным механизмом. Объект в общей памяти используется как файл откачки для регионов общей памяти, так же как файл может быть использован для откачки информации из региона, отображаемого в память. Отображения в общую память перенаправляют отказы страниц в регион памяти, занятый разделяемым объектом. Разделяемые объекты помнят свое содержимое, даже если в данный момент никакие процессы не отображают их в свои виртуальные пространства памяти.