
- •Раздел 1 Основы теории операционных систем
- •Раздел 2 Машинно-зависимые свойства операционный систем
- •Раздел 3 Машинно-независимые свойства операционных систем
- •Раздел 1 основы теории ос
- •Общие сведения об операционных системах
- •Архитектура ос
- •Распределенная обработка в сетевых ос
- •Сетевые службы.
- •Раздел 2 машинно – зависимые компоненты ос
- •Архитектурные особенности модели микропроцессорной системы
- •Обработка прерываний
- •Планирование процессов
- •Обслуживание ввода-вывода
- •Управление реальной памятью
- •Управление виртуальной памятью
- •Раздел 3 машинно-независимые свойства операционных систем
- •Работа с файлами
- •Планирование заданий
- •Синхронизация процессов и потоков
- •Защищённость и отказоустойчивость ос
Обслуживание ввода-вывода
Режимы управления ввода-вывода
Операция ввода-вывода может выполняться по отношению к программному модулю в двух режимах:
синхронном – программный модуль приостанавливает свою работу до тех пор, пока операция ввода-вывода не будет завершена, что показано на рисунке 2.9, а. Так выполняются системные вызовы;
асинхронном – программный модуль продолжает выполняться в мультипрограммном режиме одновременно с операцией ввода-вывода, что показано на рисунке 2.9,б. Это приводит к более гибким решениям, так как на основе асинхронного вызова всегда можно построить синхронный, создав дополнительную промежуточную процедуру, блокирующую выполнение вызвавшей процедуры до момента завершения ввода-вывода. В виде таких процедур выполняются внутренние вызовы операций ввода-вывода из модулей ядра.
При этом операция ввода-вывода может быть инициирована не только пользовательским процессом, но и кодом ядра, например кодом подсистемы виртуальной памяти для считывания отсутствующей в памяти страницы.
Рисунок 2.9, а – Синхронное выполнение операции ввода-вывода.
Рисунок 2.9, б – Асинхронное выполнение операции ввода-вывода.
Рисунок 2.10 – Обозначения процедур на рисунках 2.9, а и б.
Виртуальные устройства
Специальные файлы, называемые иногда виртуальными, являются удобным унифицированным представлением устройств ввода-вывода.
Понятие специального файла появилось в операционной системе UNIX. Специальный файл всегда связан с некоторым устройством ввода-вывода и представляет его для остальной части операционной системы и прикладных процессов в виде неструктурированного набора байт. Со специальным файлом можно работать так же, как и с обычным. Для этого используются те же системные вызовы: open, create, read, write и close.
Для устройств прямого доступа имеет смысл указатель текущего положения в файле, которым можно управлять с помощью системного вызова I seek.
Традиционно специальные файлы помещаются в каталог /dev. При появлении нового устройства и соответственно нового драйвера администратор системы может создать новую запись с помощью команды mknod. Например, следующая команда создает блок-ориентированный специальный файл:
mk nod /dev/dsk/sc4d2s3 b 32 33
Адресная информация специального файла состоит из двух элементов:
major — номер драйвера и определяет выбор драйвера, обслуживающее данный специальный файл;
minor – номер устройства и передается драйверу в качестве параметра вызова и указывает ему на одно из нескольких однотипных устройств, которыми драйвер может управлять.
ОС UNIX использует для хранения информации об установленных аппаратных драйверах две системные таблицы:
bdevsw — таблица блок-ориентированных драйверов;
cdevsw — таблица байт-ориентированных драйверов.
Номер драйвера (major) является индексом соответствующей таблицы. При открытии специального файла операционная система обнаруживает, что она имеет дело со специальным файлом только после того, как прочитает с диска или найдет в системном буфере его индексный дескриптор. При этом она узнает, является ли вызываемый драйвер блок- или байт-ориентированным, после чего использует номер драйвера для обращения к определенной строке одной из двух таблиц: bdevsw или cdevsw, что показано на рисунке 2.11.
Рисунок 2.11 – Организация связи ядра
UNIX с драйверами.
Драйверы и интерфейсы устройств
Достоинством подсистемы ввода-вывода любой ОС является наличие разнообразного набора драйверов для наиболее популярных периферийных устройств.
Чтобы операционная система не испытывала недостатка в драйверах, необходимо наличие четкого, удобного и открытого интерфейса между драйверами и другими компонентами ОС. Открытость и доступность интерфейса драйверов является необходимым условием успешного развития операционной системы.
Драйвер взаимодействует, с одной стороны, с модулями ядра ОС, а с другой стороны — с контроллерами внешних устройств. Поэтому существуют два типа интерфейсов:
интерфейс «драйвер-ядро» (Driver Kernel Interface, DKI) должен быть стандартизован в любом случае;
интерфейс «драйвер-устройство» (Driver Device Interface, DDI)., имеет смысл стандартизировать тогда, когда подсистема ввода-вывода выполняет операции взаимодействия с аппаратурой контроллера самостоятельно. Подсистема ввода-вывода может поддерживать несколько различных типов интерфейсов DKI/DDI, предоставляя специфический интерфейс для устройств определенного класса. Так, в ОС Windows NT для драйверов сетевых адаптеров существует интерфейс стандарта NDIS (Network Driver Interface Specification), в то время как драйверы сетевых транспортных протоколов взаимодействуют с верхними слоями сетевого программного обеспечения по интерфейсу TDI (Transport Driver Interface).
Обычно подсистема ввода-вывода поддерживает большое количество системных функций, которые драйвер может вызывать для выполнения некоторых типовых действий.
Для поддержки процесса разработки драйверов операционной системы обычно выпускается так называемый пакет DDK (Driver Development Kit), представляющий собой набор соответствующих инструментальных средств – библиотек, компиляторов, отладчиков.
Практически обязательным требованием для современных универсальных операционных систем является поддержка динамической загрузки драйверов.
По мере развития операционных систем и усложнения структуры подсистемы ввода-вывода, наряду с традиционными драйверами в операционных системах появились так называемые высокоуровневые драйверы, которые располагаются в общей модели подсистемы ввода-вывода над традиционными драйверами. Вместо того чтобы концентрировать все функции по управлению устройством в одном программном модуле, во многих случаях гораздо эффективней распределить их между несколькими модулями в соседних слоях иерархии. Низкоуровневые операции (традиционные драйвера) составляют фундамент, на котором можно построить тот или иной набор операций в драйверах более высоких уровней.
При таком подходе ходе повышается гибкость и расширяемость функций по управлению устройством – вместо жесткого набора функций администратор может выбрать требуемый набор функций установив нужный высокоуровневый драйвер.
На практике используют от двух до пяти ровней драйверов.
Высокоуровневые драйверы, как правило, не вызываются по прерываниям, так как взаимодействуют с управляемым устройством через посредничество аппаратных драйверов.
В унификацию драйверов большой вклад внесла ОС UNIX, где драйверы разделены на два больших класса
блок-ориентированные (block-oriented). Управляют устройствами прямого доступа (диск). Адресуемость блоков приводит к тому, что для устройств прямого доступа появляется возможность кэширования данных в оперативной памяти, и это обстоятельство значительно влияет на общую организацию ввода-вывода для блок-ориентированных драйверов.
байт-ориентированные (character- oriented). Работают с не адресуемыми устройствами, они генерируют или потребляют последовательности байт (служат терминалы, строчные принтеры, сетевые адаптеры). Только для этого разработана среда STREAMS.
Такое деление очень полезно для структурирования подсистемы управления вводом-выводом.
Буферизация
Подсистемой буферизации (дисковый кэш) - промежуточный программный слой, перехватывающий запросы к блок-ориентированным внешним устройствам с прямым доступом. Располагается между слоем драйверов файловых систем и блок-ориентированными драйверами.
При поступлении запроса на чтение некоторого блока диспетчер дискового кэша просматривает свой буферный пул, находящийся в системной области оперативной памяти, и если требуемый блок имеется в кэше, то диспетчер копирует его в буфер запрашивающего процесса. Операция ввода-вывода считается выполненной, хотя физического обмена с устройством не происходило, при этом выигрыш во времени доступа к файлу очевиден.
Дисковый кэш занимает достаточно большую часть оперативной системной памяти, чтобы максимально повысить вероятность попадания в кэш при выполнении дисковых операций. Например, сервер приложений выделяет под дисковый кэш меньше памяти, чем файловый сервер, чтобы обеспечить более высокую скорость работы приложений за счет предоставления им большего объема оперативной памяти.
Отрицательным последствием использования дискового кэша является потенциальное снижение надежности системы. Обычно для предотвращения потерь все содержимое дискового кэша периодически переписывается на диск. Существуют специальные системные вызовы, которые позволяют организовать принудительное выталкивание всех модифицированных блоков кэша на диск (системный вызов sync в ОС UNIX). Потери данных, хранящихся в кэше, можно существенно сократить при использовании восстанавливаемых файловых систем.
Существуют два способа организации дискового кэша:
традиционный. Основан на автономном диспетчере кэша, обслуживающем набор буферов системной памяти и самостоятельно организующим загрузку блока диска в буфер при необходимости, не обращаясь за помощью к другим подсистемам ОС. По такому принципу был организован дисковый кэш во многих ранних версиях UNIX, а также в ОС семейства NetWare;
основан на использовании возможностей подсистемы виртуальной памяти по отображению файлов в память. При этом способе функции диспетчера дискового кэша значительно сокращаются, так как большую часть работы выполняет подсистема виртуальной памяти, а значит, уменьшается объем ядра ОС и повышается его надежность.