помещается в буферном пуле. С помощью других параметров указывается конфигурация устройств, то есть производятся конкретные указания ядру, какие устройства включаются в данную системную реализацию и их 'адрес'. Например, в конфигурации может быть указано, что терминальная плата вставлена в соответствующий разъем на аппаратной панели.

Существует три стадии, на которых может быть указана конфигурация устройств. Во-первых, администраторы могут кодировать информацию о конфигурации в файлах, которые транслируются и компонуются во время построения ядра. Информация о конфигурации обычно указывается в простом формате, и программа конфигурации преобразует ее в файл, готовый для трансляции. Во-вторых, администраторы могут указывать информацию о конфигурации после того, как система уже запущена; ядро динамически корректирует внутренние таблицы конфигурации. Наконец, самоидентифицирующиеся устройства дают ядру возможность узнать, какие из устройств включены. Ядро считывает аппаратные ключи для самонастройки. Подробности задания системной конфигурации выходят за пределы этой книги, однако во всех случаях результатом процедуры задания конфигурации является генерация или заполнение таблиц, составляющих основу программ ядра.

Интерфейс 'ядро — драйвер' описывается в таблице ключей устройств ввода-вывода блоками и в таблице ключей устройств посимвольного ввода-вывода (Рисунок 10.1). Каждый тип устройства имеет в таблице точки входа, которые при выполнении системных функций адресуют ядро к соответствующему драйверу. Функции open и close, вызываемые файлом устройства, 'пропускаются' через таблицы ключей устройств в соответствии с типом файла. Функции mount и umount так же вызывают выполнение процедур открытия и закрытия устройств, но для устройств ввода-вывода блоками. Функции read и write, вызываемые устройствами ввода-вывода блоками и файлами в смонтированных файловых системах, запускают алгоритмы работы с буферным кешем, инициирующие реализацию стратегической процедуры работы с устройствами. Некоторые из драйверов запускают эту процедуру изнутри из процедур чтения и записи. Более подробно взаимодействие с каждым драйвером рассматривается в следующем разделе.

Интерфейс 'аппаратура — драйвер' состоит из машинно-зависимых управляющих регистров или команд ввода-вывода для управления устройствами и векторами прерываний: когда происходит прерывание от устройства, система идентифицирует устройство, вызвавшее прерывание, и запускает программу обработки соответствующего прерывания. Очевидно, что 'программные устройства', такие как драйвер системы построения профиля ядра (глава 8) не имеют аппаратного интерфейса, однако программы обработки других прерываний могут обращаться к 'обработчику программного прерывания' непосредственно. Например, программа обработки прерывания по таймеру обращается к программе обработки прерывания системы построения профиля ядра.

Администраторы устанавливают специальные файлы устройств командой mknod, в которой указывается тип файла (блочный или символьный), старший и младший номера устройства. Команда mknod запускает выполнение системной функции с тем же именем, создающей файл устройства. Например, в командной строке

mknod /dev/tty13 c 2 13

'/dev/tty13' — имя файла устройства, 'c' указывает, что тип файла — 'символьный специальный' ('b', соответственно, блочный), '2' — старший номер устройства, '13' — младший номер устройства. Старший номер устройства показывает его тип, которому соответствует точка входа в таблице ключей устройств, младший номер устройства — это порядковый номер единицы устройства данного типа. Если процесс открывает специальный блочный файл с именем '/dev/dsk1' и кодом 0, ядро запускает программу gdopen в точке 0 таблицы ключей устройств блочного ввода-вывода (Рисунок 10.2); если процесс читает специальный символьный файл с именем '/dev/mem' и кодом 3, ядро запускает программу mmread в точке 3 таблицы ключей устройств посимвольного ввода-вывода. Программа nulldev — это 'пустая' программа, используемая в тех случаях, когда отсутствует необходимость в конкретной функции драйвера. С одним старшим номером устройства может быть связано множество периферийных устройств; младший номер устройства позволяет отличить их одно от другого. Не нужно создавать специальные файлы устройств при каждой загрузке системы; их только нужно корректировать, если изменилась конфигурация системы, например, если к установленной конфигурации были добавлены устройства.

Рисунок 10.1. Точки входа для драйверов

10.1.2 Системные функции и взаимодействие с драйверами

В этом разделе рассматривается взаимодействие ядра с драйверами устройств. При выполнении тех системных функций, которые используют дескрипторы файлов, ядро, следуя за указателями, хранящимися в пользовательском дескрипторе файла, обращается к таблице файлов ядра и к индексу, где оно проверяет тип файла, и переходит к таблице ключей устройств ввода-вывода блоками или символами. Ядро извлекает из индекса старший и младший номера устройства, использует старший номер в качестве указателя на точку входа в соответствующей таблице и вызывает выполнение функции драйвера в соответствии с выполняемой системной функцией, передавая младший номер в качестве параметра. Важным различием в реализации системных функций для файлов устройств и для файлов обычного типа является то, что индекс специального файла не блокируется в то время, когда ядро выполняет программу драйвера. Драйверы часто приостанавливают свою работу, ожидая связи с аппаратными средствами или поступления данных, поэтому ядро не в состоянии определить, на какое время процесс будет приостановлен. Если индекс заблокирован, другие процессы, обратившиеся к индексу (например, посредством системной функции stat), приостановятся на неопределенное время, поскольку один процесс приостановил драйвер.

Рисунок 10.2. Пример заполнения таблиц ключей устройств ввода-вывода блоками и символами

Драйвер устройства интерпретирует параметры вызова системной функции в отношении устройства. Драйвер поддерживает структуры данных, описывающие состояние каждой контролируемой единицы данного типа устройства; функции драйвера и программы обработки прерываний реализуются в соответствии с состоянием драйвера и с тем, какое действие выполняется в этот момент (например, данные вводятся или выводятся). Теперь рассмотрим каждый интерфейс более подробно.

10.1.2.1 Open

При открытии устройства ядро следует той же процедуре, что и при открытии файлов обычного типа (см. раздел 5.1), выделяя в памяти индексы, увеличивая значение счетчика ссылок и присваивая значение точки входа в таблицу файлов и пользовательского дескриптора файла. Наконец, ядро возвращает значение пользовательского дескриптора файла вызывающему процессу, так что открытие устройства выглядит так же, как и открытие файла обычного типа. Однако, перед тем, как вернуться в режим задачи, ядро запускает зависящую от устройства процедуру open (Рисунок 10.3). Для устройства ввода-вывода блоками запускается процедура open, закодированная в таблице ключей устройств ввода-вывода блоками, для устройств посимвольного ввода-вывода — процедура open, закодированная в соответствующей таблице. Если устройство имеет как блочный, так и символьный тип, ядро запускает процедуру open, соответствующую типу файла устройства, открытого пользователем: обе процедуры могут даже быть идентичны, в зависимости от конкретного драйвера.

алгоритм open /* для драйверов устройств */

входная информация:

 имя пути поиска

 режим открытия

выходная информация:

 дескриптор файла

{

 преобразовать имя пути поиска в индекс, увеличить значение счетчика ссылок в индексе;

 выделить в таблице файлов место для пользовательского дескриптора файла, как при открытии обычного файла;

 выбрать из индекса старший и младший номера устройства;

 сохранить контекст (алгоритм setjmp) в случае передачи управления от драйвера;

 if (устройство блочного типа) {

  использовать старший номер устройства в качестве указателя в таблице ключей устройств ввода-вывода блоками;

  вызвать процедуру открытия драйвера по данному индексу: передать младший номер устройства, режимы открытия;

 }

 else {

  использовать старший номер устройства в качестве указателя в таблице ключей устройств посимвольного ввода-вывода;

  вызвать процедуру открытия драйвера по данному индексу: передать младший номер устройства, режимы открытия;

 }

 if (открытие в драйвере не выполнилось)

  привести таблицу файлов к первоначальному виду, уменьшить значение счетчика в индексе;

}

Рисунок 10.3. Алгоритм открытия устройства

Зависящая от типа устройства процедура open устанавливает связь между вызывающим процессом и открываемым устройством и инициализирует

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату