8.1. Назначение операционной системы

8.2. Эволюция операционных систем

8.3. Классификация операционных систем

8.4. Основные понятия операционных систем

8.5. Основные подсистемы операционных систем

8.5.1. Управление процессами

8.5.2. Управление памятью

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

8.5.4. Управление файлами

8.5.5. Защитные механизмы операционных систем

8.1. Назначение операционной системы

На современном уровне при рассмотрении ЭВМ выделяют их техническую часть (HardWare) и программное обеспечение (SoftWare), центральная часть которого и представлена операционной системой. Все программное обеспечение принято делить на две части: прикладное и системное. К прикладному программному обеспечению, как правило, относят разнообразные бизнес–программы, игры, текстовые процессоры и т. п. Под системным программным обеспечением понимают программы, способствующие функционированию и разработке прикладных программ. На рисунке 8.1 структура программного обеспечения отображена в виде последовательности слоев, где выделена отдельно наиболее общая часть системного программного обеспечения — операционная система.

Слои программного обеспечения компьютерной системы

Рисунок 8.1 — Слои программного обеспечения компьютерной системы

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

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

8.2. Эволюция операционных систем

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

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

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

Второй период (1955 г.–начало 60–х). С середины 50–х годов начался следующий период в эволюции вычислительной техники, связанный с появлением новой технической базы — полупроводниковых элементов. Размеры компьютеров уменьшились. Снизилась стоимость эксплуатации и обслуживания вычислительной техники. Началось использование ЭВМ коммерческими фирмами. Одновременно наблюдается бурное развитие алгоритмических языков (FORTRAN, LISP, COBOL, ALGOL–60, PL–1 и т.д.). Появляются первые компиляторы, редакторы связей, библиотеки математических и служебных подпрограмм. Упрощается процесс программирования. Именно в этот период происходит разделение персонала на программистов и операторов, специалистов по эксплуатации вычислительных машин.

Изменяется сам процесс выполнения расчетов по программам. Теперь пользователь приносит программу с входными данными в виде колоды перфокарт и указывает необходимые ресурсы. Такая колода получает название задания. Оператор загружает задание в память машины и запускает его на исполнение. Полученные выходные данные печатаются на принтере и пользователь получает их через некоторое (часто продолжительное) время.

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

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

Повышению эффективности использования процессорного времени мешает низкая скорость работы механических устройств ввода–вывода (считыватель перфокарт мог обработать 1200 перфокарт в минуту, принтеры печатали до 600 строк в минуту). Вместо непосредственного чтения пакета заданий с перфокарт в память начинают использовать его предварительную запись, сначала на магнитную ленту, а затем и на диск. Когда в процессе выполнения задания требуется ввод данных, они читаются с диска. Точно так же выходная информация сначала копируется в системный буфер и записывается на ленту или диск, а печатается только после завершения задания. Такой прием получает название spooling (сокращение от Simultaneous Peripheral Operation On Line) или подкачки–откачки данных. Введение техники подкачки–откачки в пакетные системы позволило совместить реальные операции ввода–вывода одного задания с выполнением другого задания, но потребовало обеспечения параллельной работы внешних устройств как друг с другом, так и с ЦП на основе использования аппарата прерываний.

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

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

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

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

Не менее важна в организации мультипрограммирования роль операционной системы. Она отвечает за следующие операции:

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

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

Появление терминалов на основе телетайпов, а позднее — на основе дисплеев поставили на очередь решение этой проблемы. Логическим расширением систем мультипрограммирования стали time–sharing системы, или системы разделения времени. В них процессор переключается между задачами не только на время операций ввода–вывода, но и просто по прошествии определенного времени. Эти переключения происходят так часто, что пользователи могут взаимодействовать со своими программами во время их выполнения, то есть интерактивно.
В результате появляется возможность одновременной работы нескольких пользователей на одной компьютерной системе. Чтобы уменьшить ограничения на количество работающих пользователей, была внедрена идея неполного нахождения исполняемой программы в оперативной памяти. Основная часть программы находится на диске, а фрагмент, который необходимо в данный момент выполнять, должен быть загружен в оперативную память, а ненужный - выгружен обратно на диск. Это реализуется с помощью механизма виртуальной памяти, объем которой складывается из объема реального ОЗУ и части объема ВЗУ. Основным достоинством такого механизма является создание иллюзии неограниченной оперативной памяти ЭВМ.

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

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

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

Компьютеры стали использоваться не только специалистами, что потребовало разработки «дружественного» программного обеспечения.

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

В середине 80–х стали бурно развиваться сети компьютеров, в том числе персональных, работающих под управлением сетевых или распределенных операционных систем.

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

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

В дальнейшем автономные операционные системы мы будем называть классическими операционными системами.

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

  • планирование заданий и использования процессора;
  • обеспечение программ средствами коммуникации и синхронизации;
  • управление памятью;
  • управление файловой системой;
  • управление вводом–выводом;
  • обеспечение безопасности.

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

8.3. Классификация операционных систем

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

Системы пакетной обработки предназначаются для решения задач в основном вычислительного характера, не требующих быстрого получения результатов. Главной целью и критерием эффективности систем пакетной обработки является максимальная пропускная способность ЭВМ, то есть решение максимального числа задач в единицу времени. Можно сказать, что они направлены на увеличение пропускной способности ЭВМ по потоку задач в целом, а не на ускорение решения отдельной наперед заданной задачи. Для достижения этой цели в системах пакетной обработки используется следующая схема функционирования: в начале работы формируется пакет заданий, каждое задание содержит требование к системным ресурсам; из этого пакета заданий формируется мультипрограммная смесь, то есть множество одновременно выполняемых задач. Для одновременного выполнения выбираются задачи, предъявляющие отличающиеся требования к ресурсам, так, чтобы обеспечивалась сбалансированная загрузка всех устройств вычислительной машины. Таким образом, выбор нового задания из пакета заданий зависит от внутренней ситуации, складывающейся в системе, то есть выбирается «выгодное» задание. Следовательно, в таких ОС невозможно гарантировать выполнение того или иного задания в течение определенного периода времени.

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

Системы разделения времени призваны исправить основной недостаток систем пакетной обработки — изоляцию пользователя–программиста от процесса выполнения его задач. Каждому пользователю системы разделения времени предоставляется терминал, с которого он может вести диалог со своей программой. Так как в системах разделения времени каждой задаче выделяется только квант процессорного времени, ни одна задача не занимает процессор надолго, и время ответа оказывается приемлемым. Если квант выбран небольшим, то у всех пользователей, одновременно работающих на одной и той же машине, складывается впечатление, что каждый из них единолично использует машину. Ясно, что системы разделения времени обладают меньшей пропускной способностью, чем системы пакетной обработки, так как на выполнение принимается каждая запущенная пользователем задача, а не та, которая «выгодна» системе, и, кроме того, имеются накладные расходы вычислительной мощности на более частое переключение процессора с задачи на задачу. Критерием эффективности систем разделения времени является не максимальная пропускная способность, а удобство и эффективность работы пользователя.

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

8.4. Основные понятия операционных систем

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

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

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

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

Файлы. Под файлом в самом общем случае понимают именованную часть пространства на внешнем носителе информации, предназначенную для хранения информации. Главная задача файловой системы (file system) - скрыть особенности ввода–вывода и дать программисту простую модель файлов, независимых от устройств. Для чтения, создания, удаления, записи, открытия и закрытия файлов имеется обширная категория системных вызовов (создание, удаление, открытие, закрытие, чтение и т.д.). Процессы. Понятие процесса в ОС тесно связано с понятием программа. По ходу выполнения программы компьютер обрабатывает различные команды и преобразует значения переменных. Для выполнения программы операционная система должна выделить определенное количество оперативной памяти, закрепить за ней устройства ввода–вывода или файлы, то есть зарезервировать ресурсы из общего числа ресурсов всей вычислительной системы. Для описания выполняющейся программы и используется термин процесс.

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

8.5. Основные подсистемы операционных систем

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

8.5.1. Управление процессами

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

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

В ходе жизненного цикла каждый процесс переходит из одного состояния в другое в соответствии с алгоритмом планирования процессов, реализуемым в данной операционной системе. Типичный граф состояний процесса показан на рисунке 8.1.

Рисунок 8.1 — Граф состояний процесса в многозадачной среде

В состоянии Выполнение в однопроцессорной системе может находиться только один процесс, а в каждом из состояний Ожидание и Готовность — несколько процессов, эти процессы образуют очереди соответственно ожидающих и готовых процессов. Жизненный цикл процесса начинается с состояния Готовность, когда процесс готов к выполнению и ждет своей очереди. При активизации процесс переходит в состояние Выполнение и находится в нем до тех пор, пока либо он сам освободит процессор, перейдя в состояние Ожидание какого–нибудь события, либо будет насильно «вытеснен» из процессора, например, вследствие исчерпания отведенного данному процессу кванта процессорного времени. В последнем случае процесс возвращается в состояние Готовность. В это же состояние процесс переходит из состояния Ожидание, после того как ожидаемое событие прои-зойдет.

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

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

8.5.2. Управление памятью

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

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

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

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

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

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

Оказывается, при таком способе организации по мере снижения скорости доступа к уровню памяти снижается также и частота обращений к нему.

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

Типы адресов. Для идентификации переменных и команд используются символьные имена (метки), виртуальные и физические адреса (рисунок 8.2). Символьные имена присваивает пользователь при написании программы на алгоритмическом языке или языке ассемблера.

Рисунок 8.2 — Типы адресов

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

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

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

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

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

Методы распределения памяти. Все методы управления памятью могут быть разделены на два класса: методы, не использующие перемещение процессов между оперативной памятью и диском, и методы, которые делают это (рисунок 8.3).

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

Рисунок 8.3 – Классификация методов распределения памяти


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

Эта схема была реализована в IBM OS/360 (MFT), DEC RSX–11 и ряде других систем.

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

Очевидный недостаток этой схемы — число одновременно выполняемых процессов ограничено числом разделов.

Распределение памяти разделами переменной величины. В этом случае память машины не делится заранее на разделы, каждой вновь поступающей программе выделяется необходимая ей память. Если достаточный объем памяти отсутствует, то программа не принимается на выполнение и стоит в очереди. После завершения программы память освобождается и на это место может быть загружена другая программа. Таким образом, в произвольный момент времени оперативная память представляет собой случайную случайную последовательность занятых и свободных участков (разделов) произвольного размера (рисунок 8.5).

Рисунок 8.4 — Распределение памяти фиксированными разделами

а) — с общей очередью; б) — с отдельными очередями

Динамика распределения памяти между процессами (серым цветом показана неиспользуемая память)

Рисунок 8.5 Динамика распределения памяти между процессами

Задачами операционной системы при реализации данного метода управления памятью являются:

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

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

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

Хотя процедура сжатия и приводит к более эффективному использованию памяти, она может потребовать значительного времени, что часто перевешивает преимущества данного метода.

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

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

При работе с виртуальной памятью ОС решает следующие задачи:

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

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

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

ВС виртуальная страница; ФС физическая страница;
ВП внешняя память

Рисунок 8.6 — Страничное распределение памяти

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

При активизации очередного процесса в специальный регистр процессора загружается адрес таблицы страниц данного процесса.

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

Рассмотрим механизм преобразования виртуального адреса в физический при страничной организации памяти (рисунок 8.7).

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

Рисунок 8.7 — Механизм преобразования виртуального адреса в физический при страничной организации памяти

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

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

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

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

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


Рисунок 8.8 Распределение памяти сегментами

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

Виртуальный адрес при сегментной организации памяти может быть представлен парой (g, s), где g номер сегмента, а s смещение в сегменте. Физический адрес получается путем сложения начального физического адреса сегмента, найденного в таблице сегментов по номеру g, и смещения s.

Недостатком данного метода распределения памяти является фрагментация на уровне сегментов и более медленное по сравнению со страничной организацией преобразование адреса.

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

Рисунок 8.9 — Странично–сегментное распределение памяти

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

8.5.4. Управление файлами

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

В широком смысле понятие файловая система включает:

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

Перечислим основные функции файловой системы:

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

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

Имена файлов. Файлы идентифицируются именами. Пользователи дают файлам символьные имена, при этом учитываются ограничения ОС как на используемые символы, так и на длину имени. Так, в популярной файловой системе MS DOS — FAT длина имен ограничивается схемой 8.3 (8 символов — собственно имя, 3 символа — расширение имени), в ОС UNIX System V имя не может содержать более 14 символов, ОС Windows NT в файловой системе NTFS устанавливает, что имя файла может содержать до 255 символов. В соответствии со стандартом POSIX популярные ОС в настоящее время оперируют также длинными именами (до 255 символов). Длинные имена поддерживаются не только новыми файловыми системами, но и новыми версиями хорошо известных файловых систем. Например, в ОС Windows 95 используется файловая система VFAT, представляющая собой измененный вариант FAT, обеспечивающая поддержку длинных имен.

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

Типы файлов. Основные типы файлов: регулярные (обычные) файлы, специальные файлы и директории (каталоги). Обычные файлы в свою очередь подразделяются на текстовые и двоичные (бинарные). Текстовые файлы содержат символьные строки, которые можно распечатать, увидеть на экране или редактировать обычным текстовым редактором. Это могут быть документы, исходные тексты программ и т.п. Другой тип обычных файлов нетекстовые, или двоичные файлы. Обычно они имеют некоторую внутреннюю структуру, например, объектный код программы или архивный файл. Обычно прикладные программы, работающие с файлами, распознают тип файла по его имени в соответствии с общепринятыми соглашениями. Например, файлы с расширениями .c, .pas, .txt — ASCII–файлы, файлы с расширениями .exe —исполняемые, файлы с расширениями .rar, .zip — архивные и т. д. Специальные файлы — это файлы, ассоциированные с устройствами ввода–вывода, которые позволяют выполнять операции ввода–вывода с использованием обычных команд записи в файл или чтения из файла. Эти команды обрабатываются вначале программами файловой системы, а затем преобразуются ОС в команды управления соответствующим устройством. Специальные файлы так же, как и устройства ввода–вывода, делятся на блок–ориентированные и байт–ориентированные. Директория (каталог) — это, с одной стороны, группа файлов, объединенных пользователем исходя из некоторых соображений (например, файлы, содержащие программы игр, или файлы, составляющие один программный пакет), а с другой стороны, — это файл, содержащий системную информацию о группе файлов, его составляющих. В каталоге содержится список файлов, входящих в него, и устанавливается соответствие между файлами и их характеристиками (атрибутами).

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

Каталоги могут образовывать иерархическую структуру за счет того, что каталог более низкого уровня может входить в каталог более высокого уровня (рисунок 8.12). Иерархия каталогов может быть деревом или сетью. Каталоги образуют дерево, если файлу разрешено входить только в один каталог, и сеть, если файл может входить сразу в несколько каталогов. В MS–DOS и Windows каталоги образуют древовидную структуру, а в UNIX сетевую. Как и любой другой файл, каталог имеет символьное имя и однозначно идентифицируется составным именем, содержащим цепочку символьных имен всех каталогов, через которые проходит путь от корня до данного каталога.

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

а) одноуровневая; b) иерархическая (дерево); c) иерархическая (сеть)

Рисунок 8.12 Организация файловой системы

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

На рисунке 8.13 показаны несколько схем логической организации файла. Записи могут быть фиксированной или переменной длины, могут быть расположены в файле последовательно (последовательная организация) или в более сложном порядке, с использованием так называемых индексных таблиц, позволяющих обеспечить быстрый доступ к отдельной логической записи (индексно–последовательная организация). Для идентификации записи может быть использовано специальное поле записи, называемое ключом. В файловых системах ОС UNIX и MS–DOS файл имеет простейшую логическую структуру — последовательность однобайтовых записей.

Рисунок 8.13 — Способы логической организации файлов

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

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

Блок наименьшая единица данных, которой внешнее устройство обменивается с оперативной памятью.

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

Контроль доступа к файлам. Наличие в системе многих пользователей предполагает организацию контролируемого доступа к файлам.

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

Различают два основных подхода к определению прав доступа:

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

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


Рисунок 8.14 Общая модель файловой системы

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

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

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

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

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

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

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

Рисунок 8.15 Архитектура современной файловой системы

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

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

8.5.5. Защитные механизмы операционных систем

Перейдем к описанию системы защиты операционных систем. Ее основными задачами являются идентификация, аутентификация, авторизация определение полномочий и уровня доступа пользователя к ресурсам, протоколирование и аудит.

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

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

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

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

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

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

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

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

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

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

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

Большинство операционных систем реализуют дискреционное управление доступом. Главное его достоинство — гибкость, основные недостатки — рассредоточенность управления и сложность централизованного контроля.

Домены безопасности. Чтобы рассмотреть схему дискреционного доступа более детально, введем понятие домена безопасности. Каждый домен определяет набор объектов и типов операций, которые могут производиться над каждым объектом. Возможность выполнять операции над объектом есть права доступа, каждое из которых есть упорядоченная пара <имя объекта, вид доступа>. Домен, таким образом, есть набор прав доступа. Hапример, если домен D имеет права доступа <file F, {read, write}>, это означает, что процесс, выполняемый в домене D, может читать или писать в файл F, но не может выполнять других операций над этим объектом. Пример доменов можно увидеть на рисунке 8.16.

Специфицирование прав доступа к ресурсам

Рисунок 8.16 Специфицирование прав доступа к ресурсам

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

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

Матрица доступа. Список доменов безопасности может быть представлен в виде матрицы, называемой матрицей доступа. Эту матрицу можно разложить по столбцам, в результате чего получим списки

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

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

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

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

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

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

Любая проблема, обнаруженная сканером безопасности, может быть как ликвидирована автоматически, так и передана для решения менеджеру системы.