Лекции по Вычислительным машинам   

8. Операционные системы

8.5.3. Управление вводом–выводом

Функционирование любой вычислительной системы обычно сводится к выполнению двух видов работ: обработке информации и операций по осуществлению ее ввода–вывода. Одной из главных функций ОС при этом является управление всеми устройствами ввода–вывода компьютера. ОС должна передавать устройствам команды, перехватывать прерывания и обрабатывать ошибки; она также должна обеспечивать интерфейс между устройствами и остальной частью системы.
В целях развития интерфейс должен быть одинаковым для всех типов устройств (независимость от устройств).

Физические принципы организации ввода–вывода. Устройства ввода–вывода делятся на два типа: блок–ориентированные и байт–ориентированные. Блок–ориентированные устройства хранят информацию в блоках фиксированного размера, каждый из которых имеет свой собственный адрес. Самое распространенное блок–ориентированное устройство диск. Байт–ориентированные устройства не адресуемы и не позволяют производить операцию поиска, они генерируют или потребляют последовательность байтов. Примерами являются терминалы, строчные принтеры и др. Однако некоторые внешние устройства не относятся ни к одному классу, например, часы, которые, с одной стороны, не адресуемы, а с другой стороны, не порождают потока байтов. Это устройство только выдает сигнал прерывания в некоторые моменты времени.  Внешнее устройство обычно состоит из механического и электронного компонента. Электронный компонент называется контроллером устройства, или адаптером. Механический компонент представляет собственно устройство. Некоторые контроллеры могут управлять несколькими устройствами. Операционная система обычно имеет дело не с устройством, а с контроллером. Контроллер, как правило, выполняет простые функции, например, преобразует поток бит в блоки, состоящие из байт, и осуществляет контроль и исправление ошибок. Каждый контроллер имеет несколько регистров, которые используются для взаимодействия с центральным процессором. В некоторых компьютерах эти регистры являются частью физического адресного пространства. В таких компьютерах нет специальных операций ввода–вывода. В других компьютерах адреса регистров ввода–вывода, называемых портами, образуют собственное адресное пространство за счет введения специальных операций ввода–вывода.

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

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

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

·      шину данных, состоящую из линий данных и служащую для передачи информации между процессором и памятью, процессором
и устройствами ввода–вывода, памятью и внешними устройствами;

·      адресную шину, состоящую из линий адреса и служащую для задания адреса ячейки памяти или указания устройства ввода–вывода, участвующих в обмене информацией;

·      шину управления, состоящую из линий управления локальной магистралью и линий ее состояния, определяющих поведение локальной магистрали.

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

Внешние устройства разнесены пространственно и могут подключаться к локальной магистрали в одной или множестве точек, получивших название портов ввода–вывода. При этом каждый порт получает свой номер или адрес в адресном пространстве портов ввода–вывода.

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

Если же порт отображен в адресное пространство портов ввода–вывода, то процесс обмена информацией инициируется специальными командами ввода–вывода. Что именно должны делать устройства, приняв информацию через свой порт, и каким именно образом они должны поставлять информацию для чтения из порта, определяется электронными схемами устройств, получившими название контроллеров. Контроллер может непосредственно управлять отдельным устройством (например, контроллер диска), а может управлять несколькими устройствами, связываясь с их контроллерами посредством специальных шин ввода–вывода.

Выделим некоторые общие черты контроллеров, необходимые им для взаимодействия с вычислительной системой. Обычно каждый контроллер имеет, по крайней мере, четыре внутренних регистра, называемых регистрами состояния, управления, входных данных и выходных данных. Для доступа к содержимому этих регистров вычислительная система может использовать один или несколько портов. Для простоты изложения будем считать, что каждому регистру соответствует свой порт.

Регистр состояния содержит биты, значение которых определяется состоянием устройства ввода–вывода и которые доступны только для чтения вычислительной системой. Эти биты индицируют завершение выполнения текущей команды на устройстве (бит занятости), наличие очередного данного в регистре выходных данных (бит готовности данных), возникновение ошибки при выполнении команды (бит ошибки) и т. д.

Регистр управления получает данные, которые записываются вычислительной системой для инициализации устройства ввода–вывода или выполнения очередной команды, а также изменения режима работы устройства. Часть битов в этом регистре может быть отведена под код выполняемой команды, часть битов будет кодировать режим работы устройства, бит готовности команды свидетельствует о том, что можно приступить к ее выполнению.

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

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

·процессор читает информацию из порта регистра состояний и проверяет значение бита занятости. Если бит занятости установлен, то это означает, что устройство еще не завершило предыдущую операцию, и процессор повторяет операцию чтения. Если бит занятости сброшен, то устройство готово к выполнению новой операции, и процессор переходит на следующий шаг;

·процессор записывает код команды вывода в порт регистра управления;

·процессор записывает данные в порт регистра входных данных;

·процессор устанавливает бит готовности команды. В следующих шагах процессор не задействован;

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

·контроллер анализирует код команды в регистре управления и обнаруживает, что это команда вывода. Он берет данные из регистра входных данных и инициирует выполнение команды;

·после завершения операции контроллер обнуляет бит готовности команды;

·при успешном завершении операции контроллер обнуляет бит ошибки в регистре состояния, при неудачном завершении команды – устанавливает его;

·контроллер сбрасывает бит занятости.

Как видим, процессор ожидает освобождения устройства, непрерывно опрашивая значение бита занятости. Такой способ взаимодействия процессора и контроллера получил название способа опроса устройств.

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

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

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

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

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

Использование механизма прерываний позволяет разумно загружать процессор в то время, когда устройство ввода–вывода занимается своей работой. Однако запись или чтение большого количества информации, например, с диска, приводят к большому количеству операций ввода–вывода, которые должен выполнять процессор. Для освобождения процессора от операций последовательного вывода данных из оперативной памяти или последовательного ввода в нее был предложен механизм прямого доступа внешних устройств к памяти — ПДП или Direct Memory Access — DMA. Выполняется такой доступ через специальный контроллер прямого доступа к памяти, который и управляет такого рода обменом без участия центрального процессора (исключая этапы инициализации и окончания обмена).

Строение жесткого диска. Современный жесткий магнитный диск представляет собой набор круглых пластин, находящихся на одной оси и покрытых с одной или двух сторон специальным магнитным слоем (рисунок 8.10).

Схема жесткого диска

Рисунок 8.10 — Схема жесткого диска

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

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

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

Другим важным вопросом для программного обеспечения ввода–вывода является обработка ошибок. Вообще говоря, ошибки следует обрабатывать как можно ближе к аппаратуре. Если контроллер обнаруживает ошибку чтения, то он должен попытаться ее скорректировать. Если же это ему не удается, то исправлением ошибок должен заняться драйвер устройства. Многие ошибки могут исчезать при повторных попытках выполнения операций ввода–вывода, например, ошибки, вызванные наличием пылинок на головках чтения или на диске. И только если нижний уровень не может справиться с ошибкой, он сообщает об ошибке верхнему уровню.

Еще один ключевой вопрос — это использование блокирующих (синхронных) и неблокирующих (асинхронных) передач. Большинство операций физического ввода–вывода выполняется асинхронно: процессор начинает передачу и переходит на другую работу, пока не наступает прерывание. Пользовательские программы намного легче писать, если операции ввода–вывода блокирующие: после команды READ программа автоматически приостанавливается до тех пор, пока данные не попадут в буфер программы. ОС выполняет операции ввода–вывода асинхронно, но представляет их для пользовательских программ в синхронной форме. Последняя проблема состоит в том, что одни устройства являются разделяемыми, а другие — выделенными. Диски — это разделяемые устройства, так как одновременный доступ нескольких пользователей к диску не представляет собой проблему. Принтеры — это выделенные устройства, потому что нельзя смешивать строчки, печатаемые различными пользователями. Наличие выделенных устройств создает для операционной системы некоторые проблемы. Для решения поставленных проблем целесообразно разделить программное обеспечение ввода–вывода на четыре слоя (рисунок 8.11):

Рисунок 8.11 — Многоуровневая организация подсистемы ввода–вывода  


·      обработка прерываний;

·      драйверы устройств;

·      независимый от устройств слой операционной системы;

·      пользовательский слой программного обеспечения.

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

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

Независимый от устройств слой операционной системы. Большая часть программного обеспечения ввода–вывода является независимой от устройств. Точная граница между драйверами и независимыми от устройств программами определяется системой, так как некоторые функции, которые могли бы быть реализованы независимым способом, в действительности выполнены в виде драйверов для повышения эффективности или по другим причинам.   Типичными функциями для независимого от устройств слоя являются:

·обеспечение общего интерфейса к драйверам устройств;

·именование устройств;

·защита устройств;

·обеспечение независимого размера блока;

·буферизация;

·распределение памяти на блок–ориентированных устройствах;

·распределение и освобождение выделенных устройств;

·уведомление об ошибках.

Остановимся на некоторых функциях данного перечня.

Обеспечение независимого размера блока. Верхним слоям программного обеспечения неудобно работать с блоками разной величины, поэтому данный слой обеспечивает единый размер блока, например, за счет объединения нескольких различных блоков в единый логический блок. В связи с этим верхние уровни имеют дело с абстрактными устройствами, которые используют единый размер логического блока независимо от размера физического сектора.

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

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

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

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

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

Необходимость сокращения времени обмена между оперативной памятью и внешним устройством за счет использования механизма кэширования (с понятием кэш–памяти мы сталкивались при рассмотрении иерархии памяти).

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

Другой категорией программного обеспечения ввода–вывода является подсистема спулинга (spooling). Спулинг — это способ работы с выделенными устройствами в мультипрограммной системе. Рассмотрим типичное устройство, требующее спулинга — строчный принтер. Хотя технически легко позволить каждому пользовательскому процессу открыть специальный файл, связанный с принтером, такой способ опасен из–за того, что пользовательский процесс может монополизировать принтер на произвольное время. Вместо этого создается специальный процесс — монитор, который получает исключительные права на использование этого устройства. Также создается специальный каталог, называемый каталогом спулинга. Для того чтобы напечатать файл, пользовательский процесс помещает выводимую информацию в этот файл и помещает его в каталог спулинга. Процесс–монитор по очереди распечатывает все файлы, содержащиеся в каталоге спулинга.



*****

© 2009-2017 Банк лекций siblec.ru
Лекции для преподавателей и студентов. Формальные, технические, естественные, общественные, гуманитарные, и другие науки.