Ввод-вывод. Ввод вывод и файловая система
Скачать 44.78 Kb.
|
Ввод - вывод и файловая система Одной из главных задач ОС является обеспечение обмена данными между приложениями и периферийными устройствами компьютера. Собственно ради выполнения этой задачи и были разработаны первые системные программы, послужившие прототипами операционных систем. В современной ОС функции обмена данными с внешними устройствами выполняет подсистема ввода - вывода. Клиентами этой подсистемы являются не только пользователи и приложения, но и некоторые компоненты самой ОС, которой требуется получение системных данных или их вывод, например подсистеме управления процессами при смене активного процесса необходимо записать на диск контекст приостанавливаемого процесса и считать с диска компонент активизируемого процесса. Основными компонентами системы ввода — вывода являются драйверы, управляющие внешними устройствами, и файловая система. К подсистеме ввода - вывода можно также с некоторой долей условности отнести и диспетчер прерываний, рассмотренный выше. Условность заключается в том, что диспетчер прерываний обслуживает не только модули подсистемы ввода - вывода, но и другие модули ОС, в частности такой важный модуль, как планировщик - диспетчер потоков. Но из - за того, что планирование работ подсистемы ввода - вывода составляет основную долю нагрузки диспетчера прерываний, его вполне логично рассматривать как её составную часть ( к тому же' первопричиной появления в компьютерах системы прерываний были в своё время именно операции с устройствами ввода — вывода). Файловая система ввиду её сложности, специфичности и важности как основного хранилища всей информации вычислительной системы заслуживают отдельного рассказа. Тем не менее, здесь файловая система рассматривается совместно с другими компонентами подсистемы ввода - вывода по двум причинам. В -первых, файловая система активно использует остальные части подсистемы ввода - вывода, а во - вторых, модель файла лежит в основе большинства механизмов доступа к устройствам, используемым в подсистемах ввода -вывода. Задачи ОС по управлению файлами и устройствами Подсистема ввода - вывода (Input - Output Subsystem) мультипрограммной ОС при обмене данными с внешними устройствами компьютера должна решать ряд общих задач, из которых наиболее важными являются следующие: - Организация параллельной работы устройств ввода - вывода и процессора; - Согласование скоростей обмена и кэширование данных; - Разделение устройств и данных между процессами; - Обеспечение удобного логического интерфейса между устройствами и остальной частью системы; - Поддержка широкого спектра драйверов с возможностью простого включения в систему нового драйвера; - Динамическая загрузка и выгрузка драйверов; - Поддержка нескольких файловых систем;. - Поддержка синхронных и асинхронных операций ввода-вывода; Организация параллельной работы устройств ввода - вывода и процессора Каждое устройство ввода – вывода вычислительной системы – диск, принтер, терминал и т. п. – снабжено специализированным блоком управления, называемым контроллером. Контроллер взаимодействует с драйвером – системным, программным модулем, предназначенным для управления данными устройством. Контроллер периодически принимает от драйвера выводимую на устройство информацию, а также команды управления, которые говорят о том, что с этой информацией нужно сделать (например, вывести в виде текста в определённую область терминала или записать в определенный сектор диска). Под управлением контроллера устройство может некоторое время выполнять свои операции автономно, не требуя внимания со стороны центрального процессора. Это время зависит от многих факторов - объема выводимой информации, степени интеллектуальности управляющего устройством контроллера, быстродействия устройства и т. п. Даже самый примитивный контроллер, выполняющий простые функции, обычно тратит много времени на самостоятельную реализацию подобной функции после получения очередной команды процессора. Это же справедливо и для сложных контроллеров, так как скорость работы любого устройства ввода - вывода, даже самого скоростного, обычно существенно ниже скорости работы процессора. Процессы, происходящие в контроллерах, протекают в периоды между выдачами команд независимо от ОС. От подсистемы ввода — вывода требуется спланировать в реальном масштабе времени (в котором работают внешние устройства) запуск и приостановку большого количества разнообразных драйверов, обеспечив приемлемое время реакции каждого драйвера на независимые события контроллера. С другой стороны, необходимо минимизировать загрузку процессора задачами ввода - вывода, оставив как можно больше процессорного времени на выполнение пользовательских потоков. Данная задача является классической задачей планирования систем реального времени и обычно решается на основе приоритетной многоуровневой схемы обслуживания по прерываниям. Для обеспечения приемлемого уровня реакции все драйверы (или части драйверов) распределяются по нескольким приоритетным уровням в соответствии с требованиями ко времени реакции и временем использования процессора. Для реализации приоритетной схемы обычно задействуется общий диспетчер прерываний ОС. Согласование скоростей обмена и кэширование данных При обмене данными всегда возникает задача согласования скорости. Например, если один пользовательский процесс вырабатывает некоторые данные и передает их другому пользовательскому процессу через оперативную память, то в общем случае скорости генерации данных и их чтения не совпадают. Согласование скорости обычно достигается за счет буферизации данных в оперативной памяти и синхронизации доступа процессов к буферу. В подсистеме ввода - вывода для согласования скоростей обмена также широко используется буферизация данных в оперативной памяти. В тех специализированных операционных системах, в которых обеспечение высокой скорости ввода – вывода является первоочередной задачей (управление в реальном времени, услуги сетевой файловой службы и т. п.), большая часть оперативной памяти отводится не под коды прикладных программ, а под буферизацию данных. Однако буферизация только на основе оперативной памяти в подсистеме ввода - вывода оказывается недостаточной - разница между скоростью обмена с оперативной памятью, куда процессы помещают данные для обработки, и скоростью работы внешнего устройства часто становится слишком значительной, чтобы в качестве временного буфера использовать оперативную память – ее объёма может просто и не хватить. Для таких случаев необходимо предусмотреть особые меры, и часто в качестве буфера используется дисковый файл, называемый также спул - файлом (от spool - шпулька, тоже буфер, только для ниток). Типичный пример применения спулинга дает организация вывода данных на принтер. Для печатаемых документов объём в несколько десятков мегабайт не редкость поэтому для их временного хранения (а печать каждого документа занимает от нескольких минут до десятков минут) объёма оперативной памяти явно недостаточно. Другим решением этой проблемы является использование большой буферной памяти в контроллерах внешних устройств. Такой подход особенно полезен в тех случаях, когда помещение данных на диск слишком замедляет обмен (или когда данные вводятся на сам диск). Например, в контроллерах графических дисплеев применяется буферная память, соизмеримая по объёму с оперативной, и это существенно ускоряет вывод графики на экран. Буферизация данных позволяет не только согласовать скорости работы процессора и внешнего устройства, но и решить другую задачу — сократить количество реальных операций ввода - вывода за счет кэширования данных. Дисковый кэш является неизменным атрибутом подсистем ввода - вывода практически всех операционных систем, значительно сокращая время доступа к хранимым данным. Разделение устройств и данных между процессами Устройства ввода – вывода норм разделяется процессам, как в монопольное, так и в совместное (разделяемое) использование. При этом ОС должна обеспечивать контроль доступа теми же способами, что и при доступе процессов к другим ресурсам вычислительной системы - путем проверки прав пользователя или группы пользователей, от имени которых действует процесс, на выполнение той или иной операции над устройством. Например, определенной группе пользователей разрешено захватывать в монопольное владение последовательный порт, другим же пользователям это запрещено. Операционная система может контролировать доступ не только к устройству в целом, но и к отдельным порциям данных, хранимых или отображаемых этим устройством. Диск является типичным примером устройства, для которого важно контролировать доступ не к устройству в целом, а к отдельным каталогам и файлам. При выводе информации на графический дисплей отдельные окна экрана также представляют собой ресурсы, к которым необходимо обеспечить тот или иной вид доступа для протекающих в системе процессов. При этом для каждой порции данных или части устройства могут быть заданы свои права доступа, не связанные прямо с правами доступа к устройству в целом. Так, в файловой системе обычно для каждого каталога и файла можно задать индивидуальные права доступа. Очевидно, что для организации совместного доступа к частям устройства или частям данных, хранящихся на нем, непременным условием является задание режима совместного использования устройства в целом. Одно и то же устройство в разные периоды времени может использоваться как в разделяемом, так и в монопольном режимах- Тем не менее, существуют устройства, для которых обычно характерен один из этих режимов, например последовательные порты и алфавитно-цифровые терминалы чаще используются в монопольном режиме, а диски - в режиме совместного доступа. Операционная система должна предоставлять эти устройства в обоих режимах, осуществляя отслеживание процедур захвата и когда подсистема ввода - вывода не разрешает драйверу непосредственно взаимодействовать с аппаратурой контроллера, а выполняет эти операции самостоятельно. Экранирование драйвера от аппаратуры является весьма полезной функцией, так как драйвер а этом случае становиться независимым от аппаратной платформы. Подсистема ввода - вывода может поддерживать несколько различных типов интерфейсов DKI/ DDI, представляя специфический интерфейс для устройств определенного класса. Так в ОС Windows NT для драйверов сетевых адаптеров существует интерфейс стандарта NDIS (Network Driver Interface Specification), в то время как драйверы сетевых транспортных протоколов взаимодействуют с верхними слоями сетевого программного обеспечения по интерфейсу ТЕМ (Transport Driver Interface). Обычно подсистема ввода - вывода поддерживает большое количество системных функций, которые драйвер может вызывать для выполнения некоторых типовых действий. Примерами могут служить упомянутые операции обмена с регистрами контроллера, ведение буферов для промежуточного хранения данных ввода - вывода, синхронизация работы нескольких драйверов, копирование данных из пользовательского пространства в пространство системы и т. д. Для поддержки процесса разработки драйверов операционной системы обычно выпускается так называемый пакет DDK (Driver Development Kit), представляющий собой набор соответствующих инструментальных средств — библиотек, компиляторов и отладчиков. Динамическая загрузка и выгрузка драйверов Кроме проблемы разработки новых драйверов существует также проблема включения драйвера в состав модулей работающей ОС, т. е. Динамической загрузки - выгрузки драйвера. Так как набор потенциально поддерживаемых данной ОС периферийных устройств всегда существенно шире набора устройств, которыми ОС должна управлять при установке на конкретной машине, то ценным качеством ОС является возможность динамически загружать в оперативную память требуемый драйвер (без остановки ОС) и выгружать его после того, как потребность в поддержке устройства миновала, что может существенно сэкономить системную область памяти. Альтернативой динамической загрузке драйверов при изменении текущей конфигурации внешних устройств компьютера является повторная компиляция кода ядра с требуемым набором драйверов, что создаёт между всеми компонентами ядра статические связи вместо динамических. Например, таким образом, решалась данная проблема в ранних версиях операционной системы UNIX. При статических связях между ядром и драйверами структура ОС упрощается, но этот подход требует наличия исходных кодов модулей операционной системы, доступность которых скорее является исключением (для некоммерческих версий UNIX), а не правилом. Кроме того, в этом варианте работающую предыдущую версию операционной системы необходимо остановить и заменить новой, а перерывы в работе ОС в некоторых применениях могут и не допускаться. Поддержка динамической загрузки драйверов является практически обязательным требованием для современных универсальных операционных систем. Поддержка нескольких файловых систем Диски представляют особый род периферийных устройств, так как именно на них хранится большая часть как пользовательских, так и системных данных. Данные на дисках организуются в файловые системы, и свойства файловой системы во многом определяют свойства сомой ОС, - её отказоустойчивость, быстродействие, максимальный объём хранимых данных. Популярность файловой системы часто приводит к её миграции из «родной» ОС в другие операционные системы — например файловая система FAT появилась первоначально в MS - DOS, но затем была реализована в OS/2, семействе MS -Windows и многих реализациях UNDC. Ввиду этого поддержка нескольких популярных файловых систем для подсистемы ввода - вывода также важна, как и поддержка широкого спектра периферийных устройств. Важно также, чтобы архитектура подсистемы ввода - вывода позволяла достаточно просто включать в её состав новые типы файловых систем, без необходимости переписывания кода. Обычно в операционной системе имеется специальный слой программного обеспечения, отвечающий за решение данной задачи, например слой WS (Virtual File System) в версиях UNIX на основе кода System V Release 4. Многоуровневые драйверы Первоначально термин «драйвер» применялся в достаточно узком смысле: под драйвером понимался модуль, который: - Входит в состав ядра операционной системы, работая в привилегированном режиме. - Непосредственно управляет внешним устройством, взаимодействуя с его контроллером с помощью команд ввода - вывода компьютера. - Обрабатывает прерывания от контроллера устройства. - Предоставляет прикладному программисту удобный логический интерфейс работы с устройством, экранируя от него низкоуровневые детали управления устройством и организации его данных. - Взаимодействует с другими модулями ядра ОС с помощью строго оговорённого интерфейса, описывающего формат передаваемых данных, структуру буферов, способы включения драйвера в состав ОС, способы вызова драйвера, набор общих процедур подсистемы ввода - вывода, которыми драйвер может пользоваться, и т. п. Согласно этому определению драйвер вместе с контроллером устройства и прикладной программой воплощали идею многослойного подхода к организации программного обеспечения. Контроллер представлял нижний слой управления устройством, выполняющий операции в терминах блоков и агрегатах устройства (например, передвижение головки дисковода, побитную передачу байта по двухпроводному кабелю). Драйвер выполнял более сложные операции, преобразуя, например, данные, адресуемые в терминах адресов цилиндров, головок и секторов диска, в линейную последовательность блоков или устанавливая логическое соединение между двумя модемами используя телефонную сеть. В результате прикладная программа уже работает с данными, преобразованными в достаточно понятную для человека форму, - файлами, таблицами баз данных, текстовыми окнами на мониторе и т. п., не вдаваясь в детали представления этих данных в устройствах ввода - вывода. Кроме того, помещение драйвера в привилегированный режим и запрет для пользовательских процессов выполнять операции ввода - вывода защищают критически важные для работы ОС устройства ввода - вывода от ошибок прикладных программ, а также позволяют ОС надежно контролировать процесс разделения устройств и их данных между пользователями и процессами. В описанной схеме драйверы не делились на слои. При этом они выполняли задачи разного уровня сложности: как самые примитивные, например, просто передавали контроллеру байты для дальнейшего использования, так и достаточно сложные, связанные с отработкой протокола взаимодействия между модемами или вычерчиванием на экране математических кривых. Постепенно, по мере развития операционных систем и усложнения структуры подсистемы ввода - вывода, наряду с традиционными драйверами в операционных системах появились высокоуровневые драйверы, которые располагаются в общей модели подсистемы ввода - вывода над традиционными драйверами. Появление высокоуровневых драйверов можно считать дальнейшим развитием идеи многослойной организации подсистемы ввода - вывода. Вместо того чтобы концентрировать все функции по управлению устройством в одном программном модуле, во многих случаях гораздо эффективней распределить их между модулями в соседних слоях иерархии. Традиционные драйверы, которые стали называть аппаратными драйверами, низкоуровневыми драйверами, или драйверами устройств, подчеркивая их непосредственную связь с управляемым устройством, освобождаются от высокоуровневых функций и занимаются только низкоуровневыми операциями. Эти низкоуровневые операции составляют фундамент, на котором можно построить тот или иной набор операций в драйверах более высоких уровней. При таком подходе повышается гибкость и расширяемость функций по управлению устройством — вместо жесткого набора функций, сосредоточенных в единственном драйвере, администратор ОС может выбрать требуемый набор функций, установив требуемый высокоуровневый драйвер. Если различным приложениям необходимо работать с разными логическими моделями одного и того же устройства, то для этого достаточно установить в системе несколько драйверов на одном уровне, работающих над одним аппаратным драйвером. Количество уровней драйверов в подсистеме ввода — вывода обычно не ограничивается каким либо пределом, но на практике чаще всего используют от двух до пяти уровней драйверов — слишком большое количество уровней может снизить скорость операций ввода - вывода. Несколько драйверов, управляющих отдельным устройством, но на разных уровнях, можно рассматривать как набор отдельных драйверов или как один многоуровневый драйвер. Высокоуровневые драйверы оформляются по тем же правилам и придерживаются тех же внутренних интерфейсов, что и аппаратные драйверы. Единственным отличием является то, что высокоуровневые драйверы, как правило, не вызываются по прерываниям, так как взаимодействуют с управляемым устройством через посредничество аппаратных драйверов. Менеджер ввода - вывода управляет драйверами однотипно, независимо от того, к какому уровню он относится. При наличии большого количества драйверов разного уровня усложняются связи между ними, что, в свою очередь усложняет их взаимодействие и именно эта •ситуация привела к стандартизации внутреннего интерфейса в подсистеме ввода - вывода и выделения специальной оболочки в виде менеджера ввода -вывода, выполняющего системные функции по организации работы драйверов. В подсистеме управления графическими устройствами, такими как графические мониторы и принтеры, также существует несколько уровней драйверов. На нижнем уровне работают аппаратные драйверы, которые позволяют управлять конкретным графическим адаптером или принтером определённого типа, заставляя их выполнять некоторый набор примитивных графических операций: вывод точки, окружности, заполнение области цветом и т.п. Высокоуровневые графические драйверы строят на базе этих операций более мощные операции, например масштабирование изображения, преобразование графического формата в соответствии с разрешающими способностями устройства и т.п. Самый верхний уровень подсистемы составляет менеджер окон, который создает для каждого приложения виртуальный образ экрана в виде набора окон, в которые приложение может выводить свои графические данные. Менеджер управляет окнами, отображая их в определённую область физического экрана или делая их невидимыми, а также предоставляет к ним совместный доступ с контролем прав доступа. В подсистеме управления дисками аппаратные драйверы поддерживают для верхних уровней представление диска как последовательного набора блоков одинакового размера, преобразуя вместе с контроллером номер блока в более сложный адрес, состоящий из номеров цилиндра, головки и сектора. Однако такие понятия, как «файл» и «файловая система», аппаратные драйверы не поддерживают - эти удобные для пользователя и программиста логические абстракции создаются на более высоком уровне программным обеспечением файловых систем, которое в современных ОС также оформляется как драйвер, только высокоуровневый. Необязательно все модули подсистемы вода — вывода оформляются в виде драйверов. Например, в подсистеме управления дисками имеется такой модуль, как дисковый кэш, который служит для кэширования блоков дисковых файлов в оперативной памяти. Достаточно специфические функции КЭШа делают нецелесообразным оформление его в виде драйвера, взаимодействующего с другими модулями ОС только с помощью услуг менеджера ввода - вывода. Другим примером модуля, который чаще всего не оформляется в виде драйвера, является диспетчер окон графического интерфейса. Иногда этот модуль вообще выносится из ядра ОС и реализуется в виде пользовательского процесса. Таким образом, был реализован диспетчер окон (а также высокоуровневые графические драйверы) в Windows NT 3.5 и 3.51, но этот микроядерный подход заметно замедлял графические операции, поэтому в Windows NT 4.0 диспетчер окон и высокоуровневые графические драйверы, а также графическая библиотека GDI были перенесены в пространство ядра. Аппаратные драйверы после запуска операции ввода — вывода должны своевременно реагировать на завершение контроллером заданного действия, и для решения этой задачи они взаимодействуют с системой прерываний. Драйверы более высоких уровней вызываются уже не по прерываниям, а по инициативе аппаратных драйверов или драйверов вышележащего уровня. Не все процедуры аппаратного драйвера нужно вызывать по прерываниям, поэтому драйвер обычно имеет определенную структуру, в которой выделяется секция обработки прерываний (Interrupt Service Routine, ISR), которая и вызывается при поступлении запроса от соответствующего устройства диспетчером прерываний. Диспетчер прерываний можно считать частью подсистемы ввода — вывода, а можно считать и независимым модулем ядра ОС, так как он служит не только для вызова секции обработки прерываний драйверов, но и для диспетчеризации прерываний других типов. В унификацию драйверов большой вклад внесла операционная система UNIX. В ней все драйверы были разделены на два больших класса: Блок — ориентированные (block — oriented) драйверы и байт — ориентированные (character - oriented) драйверы. Блок — ориентированные драйверы управляют устройствами прямого доступа, которые хранят информацию в блоках фиксированного размера, каждый из которых имеет фиксированный адрес. Самое распространенное внешнее устройство прямого доступа - диск. Адресуемость блоков приводит к тому, что для устройства прямого доступа появляется возможность кэширования данных в оперативной памяти, и это обстоятельство значительно влияет на общую организацию ввода - вывода для блок -ориентированных драйверов. Устройства с которыми работают байт — ориентированные драйверы, не адресуемы и не позволяет производить операцию поиска данных, они генерируют или потребляют последовательности байт. Примерами таких устройств, служат терминалы, строчные принтеры, сетевые адаптеры. |