Категории
Самые читаемые
Лучшие книги » Компьютеры и Интернет » Интернет » Операционная система UNIX - Робачевский Андрей Михайлович

Операционная система UNIX - Робачевский Андрей Михайлович

Читать онлайн Операционная система UNIX - Робачевский Андрей Михайлович

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 101 102 103 104 105 106 107 108 109 ... 156
Перейти на страницу:

Ядро вызывает те или иные функции драйвера в зависимости от запроса. Например, если процесс выполняет системный вызов read(2) для специального файла символьного устройства, ядро вызовет функцию <i>xx</i>read() для соответствующего символьного драйвера. Если же процесс запрашивает ту же операцию для обычного дискового файла, ядро вызовет процедуру <i>xx</i>strategy() для блочного драйвера, обслуживающего данную файловую систему.

Вообще говоря, можно выделить пять основных случаев, в которых ядро обращается к функциям драйвера:

□ Автоконфигурация. Обычно происходит в процессе инициализации UNIX, когда ядро определяет, какие устройства доступны в системе.

□ Ввод/вывод. Запрос на операцию ввода/вывода может быть инициирован как прикладным процессом, так и некоторыми подсистемами ядра, например, подсистемой управления памятью.

□ Обработка прерываний. Ядро вызывает соответствующую функцию драйвера для обработки прерывания, поступившего от устройства (если устройство способно генерировать прерывания).

□ Специальные запросы. Ядро вызывает соответствующую функцию драйвера для обработки специальных команд, полученных с помощью системного вызова ioctl(2).

□ Реинициализация/Останов. Некоторые типы аппаратных архитектур могут требовать сброса и реинициализации устройства. Определенные функции драйвера также вызываются при останове операционной системы.

На рис. 5.2 и 5.3 приведены схемы доступа к драйверам символьного и блочного устройств.

Рис. 5.2. Доступ к драйверу символьного устройства

Рис. 5.3. Доступ к драйверу блочного устройства

Как видно из рисунков, схема обработки запроса ядром UNIX различна для символьных и блочных устройств.

При обсуждении точек входа драйверов устройств следует иметь в виду, что большинство функций драйвера, отвечающих за передачу данных, осуществляют копирование информации из адресного пространства ядра, в котором находится сам драйвер, в адресное пространство задачи. Когда ядро вызывает функцию драйвера, все действия выполняются в системном контексте процесса. Однако схема вызова функций может быть различной:

□ Функция может быть вызвана по запросу процесса. Например, если процесс выполняет системный вызов read(2), ядро вызывает соответствующую точку входа драйвера <i>xx</i>read(), обеспечивающего работу с файлом. В этом случае говорят, что функция имеет контекст задачи.

□ Функция может быть вызвана другой подсистемой ядра операционной системы. Например, для блочного драйвера функция <i>xx</i>strategy() может быть вызвана страничным демоном, для сохранения страниц во вторичной памяти (как правило, на жестком диске). Поскольку страничный демон представляет собой системный процесс, выполняющийся только в контексте ядра, функция <i>xx</i>strategy() в этом случае имеет системный контекст.

□ Если функция вызывается в процессе обработки прерывания, то она имеет контекст прерывания — специальный вид системного контекста. Функции драйвера, отвечающие за обработку прерывания, например <i>xx</i>intr() имеют этот тип контекста.

Различия в контексте и причинах вызова тех или иных функций драйвера позволяют представить драйвер устройства состоящим из двух частей: верхней части (top half) и нижней части (bottom half). Функции верхней части драйвера имеют синхронный характер, т.е. вызываются по определенным запросам прикладного процесса и выполняются в его контексте. Таким образом, для этих функций доступно адресное пространство и u-area процесса, и при необходимости эти функции могут перевести процесс в состояние сна (вызовом функции sleep() ядра). Функции ввода/вывода и управления принадлежат верхней части драйвера.

Вызов функций нижней части носит асинхронный характер. Например, момент вызова функции обработки прерываний нельзя предугадать, и ядро не может контролировать, когда эта функция будет вызвана. Выполнение таких функций происходит в контексте ядра и обычно не имеет никакого отношения к контексту текущего процесса. Таким образом, функции системного контекста не имеют права адресовать структуры данных текущего процесса, например его u-area, а также не могут перевести процесс в состояние сна, поскольку это заблокирует процесс, не имеющий непосредственного отношения к работе драйвера.

Две части драйвера требуют синхронизации. Например, в случае, когда функции обеих частей используют одну и ту же структуру данных, функция верхней части при выполнении должна заблокировать прерывания на период работы с "разделяемой" областью памяти. В противном случае, прерывание может поступить в тот момент, когда целостность структуры данных нарушена, что приведет к непредсказуемым результатам.

Все представленные выше функции, за исключением <i>xx</i>halt(), <i>xx</i>poll() и <i>xx</i>intr(), принадлежат верхней части драйвера. Функция <i>xx</i>halt() вызывается ядром при останове системы и, таким образом, имеет системный контекст, не связанный с контекстом прикладного процесса.

Функция <i>xx</i>poll() обычно вызывается при обработке ядром прерывания таймера для всех устройств, указанных как опрашиваемые. Это необходимо, в частности, для устройств, которые не могут или "не хотят" использовать аппаратные прерывания. Вместо этого <i>xx</i>poll() может использоваться для эмуляции прерываний, например вызывая функцию <i>xx</i>intr() на каждый n-ный тик системного таймера. Поэтому и функция <i>xx</i>poll() и функция обработки прерывания <i>xx</i>intr() не могут рассчитывать на контекст прикладного процесса. В большинстве версий UNIX функции опроса и обработки прерываний вызываются не через коммутатор устройств, а через специальные таблицы ядра.

В UNIX SVR4 определены две дополнительные точки входа — init() и start(). Драйвер регистрирует эти функции в таблицах ядра io_init[] и io_start[]. Код начальной загрузки системы запускает функции <i>xx</i>init() перед инициализацией ядра, а функции <i>xx</i>start() сразу же после инициализации.

Файловый интерфейс

В главе 4 мы рассмотрели интерфейс т.н. независимой или виртуальной файловой системы, обеспечивающей унифицированный интерфейс работы с различными типами физических файловых систем (например, ufs или s5fs), имеющих разные внутренние структуры и возможности. При этом подходе используется унифицированный формат метаданных активных файлов, которые хранятся в памяти (в in-core — таблице индексных дескрипторов) и не зависят от конкретной реализации файловой системы. Эти объекты получили название виртуальных индексных дескрипторов или vnode. Для каждого vnode определен набор абстрактных операций, которые реализованы функциями реальных файловых систем. Например, vnode файла, расположенного в файловой системе s5fs, адресует вектор операций (или коммутатор файловых систем, FSS) s5fsops, содержащий конкретные функции этой файловой системы — s5fs_close(), s5fs_open() или s5fs_ulink().

1 ... 101 102 103 104 105 106 107 108 109 ... 156
Перейти на страницу:
На этой странице вы можете бесплатно скачать Операционная система UNIX - Робачевский Андрей Михайлович торрент бесплатно.
Комментарии