Лекции Системное ПО. Лекция Структура и основные компоненты вычислительной системы
Скачать 0.71 Mb.
|
Одноуровневая организация файлов непрерывными сегментами. Ее суть такова — в пределах пространства ВЗУ выделяется некоторая область для хранения данных, которая называется “Каталог”. Каталог имеет следующую структуру
Имя — имя некоторого файла Начальный блок — относительный адрес блока, с которого начинается файл. Конечный блок — относительный адрес последнего блока файла. Соответственно, функция открытия файла сводится к тому, чтобы в этой таблице “Каталог” найти по имени нужный файл и определить начало его размещения и конец размещения. Действие очень простое, так как дополнительных обменов не требуется — весь каталог можно хранить в памяти ОС. Если создается новый файл, то он записывается на свободное место. Альтернативно каталогу имен существует таблица свободных фрагментов пространства ВЗУ. С открытием файла все просто — по имени сразу получается диапазон размещения файла, причем реально данные могут занимать меньше места, чем диапазон начала-конца. Чтение-запись происходят практически без дополнительных обменов, так как для получения координат файла на носители не требуется совершать лишних действий. Но что будет, когда требуется записать в такой файл дополнительную информацию, а свободного пространства за файлом нет? В этом случае файловая система может поступить двояко: в первом случае — она скажет, что места нет, и пользователь должен что-то сделать сам (например, перенести файл на большее место, где хватит места для того, чтобы дописать информацию в файл — но такой перенос дело очень дорогостоящее), во втором случае — будет просто отказано в обмене, то есть при открытии файла мы должны были сразу зарезервировать необходимое место. Итак, организация простая, при обменах — эффективная, но в случае нехватки пространства для файлов начинается неэффективность и при долговременной работе случается фрагментация (когда имеются свободные фрагменты, которые объемом позволяют разместить файл, а расположением — нет). Это та же самая проблема, которая имела место в ОЗУ. Решить данную проблему можно путем компрессии — долгого и опасного для данных процесса, который передвигает блоки по ВЗУ с целью разместить их оптимальным образом. Можно сделать эту компрессию так, чтобы в конец каждого файла был добавлен кусок свободного места (например, по 10% от текущей длины). Такая файловая система может быть пригодна только для однопользовательской системы. Ибо при большом потоке информации, в случае многопользовательской системы, происходит быстрая деградация файлового пространства и требуется долговременный процесс компрессии. Она одноуровневая — то есть не может быть двух файлов с одинаковыми именами. Но она очень проста и требует минимум дополнительных расходов. Файловая система с блочной организацией файлов.
Пространство ВЗУ разделено на блоки (блоки удобных для обмена размеров или кратных им). В файловой системе такого типа происходит аналогично распределению процесса в памяти со страничной организацией. То есть в общем случае с каждым именем файла связан набор номеров блоков устройства, в которых размещены данные этого файла, Name {Блок1, Блок2, ..., БлокM} причем эти блоки имеют произвольный порядок на ВЗУ: ВЗУ:
При такой организации мы имеем потери кратные блоку (если хотя бы один байт блока занят, то он считается непустым и не может быть отдан другому файлу), но при такой схеме нет проблемы фрагментации. Как следствие, нет надобности в компрессии. Следовательно, такая файловая система может использоваться при многопользовательской работе. В последнем случае с каждым файлом у нас связано несколько атрибутов:
И, соответственно, доступ к файлу осуществляется заданием двух параметров. Таким образом, уже необязательна уникальность имен файлов во всей файловой системе, нужна лишь уникальность имен файлов у одного пользователя. У разных пользователей могут быть файлы с одинаковыми именами. Организация таких файлов может быть через каталог. Структура каталога может быть следующая:
Каталог содержит строки, каждая iая строка соответствует iому блоку файловой системы, в этой строке содержится информация о занятости блока. Если он занят, то в этой строке указывается имя файла (или ссылка на него) и имя пользователя, может быть и какая-то дополнительная информация. При открытии файла система может, например, пробегать по ВЗУ и строить таблицу соответствия между логическими блоками файла и физическими (блоками носителя). При данной организации файловой системы мы имеем одноуровневую структуру пользователей и, как следствие, все файлы связаны в группы только по принадлежности какому-либо пользователю. Иерархическая файловая система. Все файлы файловой структуры строятся в дерево. Корнем дерева является так называемый корень файловой системы. Если узел дерева является листом, то это файл, который может содержать либо данные, либо являться каталогом. Узлы, отличные от листьев являются каталогами. Соответственно, именование в такой системе может происходить разными способами. Первый — именование фала относительно ближайшего каталога. Если мы посмотрим файлы, которые являются ближайшими для каталога F0 — это файл F1 (он тоже является каталогом) и файл F2. То есть если мы каким-то образом подразумеваем (системным образом), что работаем в каталоге F0, то можем обращаться к файлам в данном каталоге только по их именам (F1 и F2). Соответственно, на одном уровне имена должны быть уникальны (в пределах одного каталога). Так как мы имеем структуру дерева, то можно говорить о полном имени файла, которое составляет путь от корня дерева, до файла. Например, путь к файлу F3 будет выглядеть, как “/F0/F1/F3”. В одно и то же время мы можем работать как с полным, так и с коротким именем файла. А так как по свойству дерева путь к каждому листу однозначен, то мы сразу решаем проблему унификации имен. Первой такая организация появилась в ОС Multics, которая разрабатывалась в университете Беркли в конце 60х годов. Это было давно, но такое хорошее и красивое решение с тех пор стало появляться во многих ОС. Соответственно с иерархией каждому файлу можно привязывать некоторые атрибуты, связанные с правами доступа, этими атрибутами могут обладать как файлы, так и каталоги. То есть структурная организация такой файловой системы хороша для многопользовательской системы. Ибо с одной стороны нет проблемы именования, а с другой стороны такая система может сильно и хорошо наращиваться. Защита данных в ОС Идентификация — возможность ОС распознать определенного пользователя и выполнять в зависимости от определения нужные действия по защите данных и т.п. Например, MS DOS — однопользовательская ОС. Существуют системы, которые позволяют регистрировать пользователей, но эти пользователи никак между собой не связаны (примером могут являться некоторые ОС фирмы IBM для мейнфреймов), а значит их нельзя организовать в группы. Но было бы удобно выделить в отдельную группу — лабораторию, кафедру, учебную группу студентов и т.п. В иерархической организации пользователей есть понятие группы. А в группе есть реальные пользователи. При регистрации конкретного пользователя его следует отнести к какой-либо группе. Раз пользователи разделены на группе, то по аналогии с разделением между конкретными пользователями, можно разделять ресурсы с группой (то есть пользователь может сделать свои файлы доступными для всех членов какой-то группы. И такое деление на группы может быть также многоуровневым с соответствующим распределением прав и возможностей. Маленькое замечание — сейчас появляются ОС, в которых права доступа могут быть не только иерархическими, но и более сложные — например, нарушая иерархию (какой-то файл может быть доступным конкретному пользователю из группы другой ветви дерева). Вот, наверное, и все, что следовало бы сказать о свойствах и функциях ОС. Естественно, мы рассмотрели далеко не все функции ОС. Что-то было специально упущено, так как мы рассматриваем ОС в упрощенной модели. Ибо наша цель — не изучение конкретной ОС, а научиться классифицировать ОС, с каких точек зрения следует на нее смотреть и сравнивать различные типы ОС. Лекция 7 ОС Unix Сегодня мы с вами переходим к началу рассмотрения ОС Unix, поскольку многие решения, которые принимаются в ОС мы будем рассматривать на примере этой ОС. В середине 60х годов в Bell лаборатории фирмы AT&T проводились исследования и разработка одной из первых ОС в современном ее понимании — ОС Multics. Это ОС разделения времени, многопользовательская, а также в этой системе были предложены фактически основные решения по организации файловых систем. В частности, была предложена иерархическая древообразная файловая система. Это, ориентировочно, 1965 год. От этой разработки через некоторое время получила начало ОС Unix. Одна из предысторий говорит, что на фирме был ненужный компьютер PDP8 с очень малоразвитым программным обеспечением. А требовалась машина, которая бы позволяла организовывать удобную работу пользователя, в частности, удобный ввод информации. И известная группа людей — Томпсон и Ритчи занялись разработкой на этой машине новой ОС. Другой вариант был таков, что они занимались реализацией новой игры, а те средства, которые имелись были недоступны или неудобны, и они решили поиграться с этой машиной. Результатом стало появление ОС Unix. Особенностью этой системой являлось то, что она являлась первой системной программой написанной на языке, отличном от языка ассемблера. Дляцели написания этого системного программного обеспечения, в частности, ОС Unix, также параллельно проводились работы, которые начинались от языка BCPL, из него был образован язык B, который оперировал с машинными словами, далее абстракция машинных слов — BN и, наконец, язык “C”. И после 1973 года ОС Unix была переписана окончательно на язык “С”. В результате появилась ОС, 90% кода которой было написано на языке высокого уровня, языке, не зависящем от архитектуры машины и системы команд, а 10% было написанона ассемблере, в эти 10% входят наиболее критичные к реализации по времени части ядра ОС. Многих программистов в то время это немного шокировало, мало кто верил, что такая ОС способна жить, поскольку всегда язык высокого уровня ассоциировался с большой неэффективностью. Но язык “С” тем не менее был сконструирован таким образом, что позволял писать эффективные программы и транслировать их в также достаточно эффективный машинный код. Из таких конструктивных свойств следует отметить то, что “С” сильно построен на работе с указателями. Когда мы пишем программу на ассемблере, то очень часто для достижения требуемого результата нам нужно манипулировать с адресами. Возможность оперировать указателями — первое свойство “С”, которое позволяет эффективно транслировать программу на этом языке в машинный код. Если мы посмотрим на нормальную программу на ассемблере, то заметим следующее — при программировании каких-то блоков мы часто используем побочный эффект (например, во время вычисления выражения мы можем получать и куда-то откладывать промежуточные результаты), также можно поступать и в языке “С”. Таким образом, понятие выражения в “С” было гораздо шире, чем в других языках того времени. И в выражениях, кроме новых операций, таких как работа с указателем, смещения сдвиги и т.п., появилась принципиально новая операция — операция присваивания. Почему она новая? Потому что во многих языках до “С”, а также и после него не было операции присваивания — был оператор присваивания. Разница в одном — если мы имеем оператор присваивания, во-первых, требуется, чтобы в правой части такой операции уже не было (мы не можем использовать побочный эффект), и второе — левая часть оператора присваивания — это некоторая ссылка на единичную область памяти. Внесение оператора присваивания внутрь выражения позволило решать проблему побочных эффектов (значения подвыражений, которые могут быть использованы во вне — а они в свою очередь сокращают число обменов с ОЗУ), а это средство эффективности. Эти и, наверное, только эти свойства языка определили его живучесть, пригодность для программирования системных компонентов и возможность оптимальной трансляции кода различных машин. С профессиональной точки зрения, язык “С” — ужасный язык. Основным требованием, которое предъявляется сегодня к языкам программирования является безопасность программирования. То есть средства языка должны минимизировать количество возможных ошибок. И свойствам таких языков относится следующее: Жесткий контроль типов. То есть если мы попробуем умножить целочисленную переменную на плавающую, то язык выдаст ошибку. Все преобразования типов по умолчанию недопустимы. Обеспечение контроля за доступом в память программы. Это означает, что если у нас в памяти число было записано, как целое, то и считать его оттуда мы можем только как целое, а не как плавающее или символ. В “С” же и других языках бесконтрольный доступ к памяти предоставляет указатель, более того, через указатель мы с одной стороны теряем любую информацию о типе, а с другой стороны мы можем обманывать функциипо части фактических и формальных параметров. Контроль за взаимодействием модулей. Суть этого свойства в том, что много ошибок появляется в том случае, что если функция продекларировала один набор параметров, а обращение к ней идет с другим набором, причем различие может быть как в количестве, так и в типах. Язык “С”, несмотря даже на версию ANSI C, которая пыталась отчасти решить эту проблему — всегда остается возможность обмануть функцию и передать ей параметр другого типа, вместо шести параметров можно передать один параметр. Вот по этим трем позициям язык “С” является нехорошим языком. Но тем не менее это “менталитет” программистов, который заключается в том, что почему-то наиболее живучими языками являются концептуально плохие языки, к таким языкам помимо “С” можно добавить еще Фортран. Итак, 1973 год. Появление ОС Unix, причем она уже была написана на языке “С”. Какими основными свойствами уже тогда обладала эта ОС. Первое свойство — концепция файлов, основным объектом, которым оперирует ОС — это файл. Файл — это набор данных, файл с точки зрения Unix — это внешнее устройство, файл — это каталог, который содержит информацию о принадлежащих ему файлах и т.д. На сегодняшний день стратегия файлов распространена в Unix’е практически на все. Второе свойство, которое является продолжением или следствием первого, это то, что ОС построена очень интересно. В отличии от предыдущих ОС, где каждая команда была зашита внутрь, и эту команду нельзя было модифицировать, убрать из системы, создать новую команду — вUnix’е проблемы команд пользователя решены очень элегантно за счет двух моментов. Первый — Unix декларирует стандартный интерфейс передачи параметров извне внутрь процесса. Второй — все команды реализованы в виде файлов, это означает, что можно свободно добавлять новые команды в систему, которые будут доступны либо мне, либо группе пользователей, либо всем, а можно удалять команды. Давайте начнем рассмотрение конкретных свойств ОС Unix. Первое, что мы будем рассматривать, это файловая система, организация работы с файлами. Файловая система Unix Файловая система Unix, это иерархическая, многопользовательская файловая система. Ее можно представить в виде дерева: В корне дерева находится “корневой каталог”, узлами, отличными от листьев дерева являются каталоги. Листьями могут являться: файлы (в традиционном понимании — именованные наборы данных), пустые каталоги (каталоги, с которыми не ассоциировано ни одного файла). В системе определено понятие имени файла — это имя, которое ассоциировано с набором данных в рамках каталога, которому принадлежит этот файл. Например, каталогу D1 принадлежат файлы: N1, N2, N3; каталогу D0 принадлежат: N4, N5 и D1, последний тоже является файлом, но специальный. Итак, имя — это имя, которое ассоциировано снабором данных в контексте принадлежности каталогу. Кроме того, есть понятие полного имени. Полное имя — это уникальный путь от корня файловой системы до конкретного файла. Первый символ имени — это корневой каталог “/”, а далее через наклонную черту перечислены все каталоги, пока не дойдет до нужного файла. Например, файл N3 имеет полное имя “/D0/D1/N3”. За счет того, что такой путь для каждого файла в любом каталоге уникален, то мы можем именовать одинаковыми именами файлы в различных каталогах. Например, имя N4 присутствует в каталогах D0 и D4, но это разные файлы, так как полные пути к ним различны (/D4/N4, /D0/N4). Замечание. На самом деле файловая система Unix не является древообразной. Все то, что говорилось выше — правильно, но в системе имеется возможность нарушения красивой и удобной иерархии в виде дерева, так как имеется возможность ассоциировать несколько имен с одним и тем же содержимым файла. И могут возникать такие ситуации, когда, например, “/D4/N3” и “/D0/D1/N1” являются, по сути дела, одним файлом с двумя именами. Еще одно замечание. В ОС Unix используется трехуровневая иерархия пользователей: Первый уровень — все пользователи. Они подразделены на группы и, соответственно, группы состоят из реальных пользователей. В связи с этой трехуровневой организацией пользователей каждый файл обладает тремя атрибутами: 1) Владелец файла. Этот атрибут связан с одним конкретным пользователем, который автоматически назначается системой владельцем файла. Владельцем можно стать по умолчанию, создав файл, а также есть команда, которая позволяет менять владельца файла. 2) Защита доступа к файлу. Доступ к каждому файлу (от файла ядра системы до обыкновенного текстового файла) лимитируется по трем категориям: права владельца (что может делать владелец с этим файлом, в общем случае — не обязательно все, что угодно); права группы, которой принадлежит владелец файла. Владелец сюда не включается (например, файл может быть закрыт на чтение для владельца, а все остальные члены группы могут свободно читать из этого файла; все остальные пользователи системы; По этим трем категориям регламентируются три действия: чтение из файла, запись в файл и исполнение файла (в мнемонике системы R,W,X, соответственно). В каждом файле по этим трем категориям определено — какой пользователь может читать, какой писать, а кто может запускать его в качестве процесса. Это некоторые предварительные данные по файловой системе. Теперь давайте рассмотрим структуру файловой системы на диске. Сначала определим некоторые понятия: Для любой вычислительной системы определено понятие системного внешнего запоминающего устройства (ВЗУ). Это устройство, к которому осуществляет доступ аппаратный загрузчик системы с целью запуска ОС. Суть заключается в следующем — практически любая вычислительная система имеет диапазон адресного пространства оперативной памяти, размещенной в ПЗУ. В ПЗУ размещается небольшая программа (хотя понятие размера относительно, но она действительно небольшая), которая при включении вычислительной машины обращается к фиксированному блоку ВЗУ, считывает его в память и передает управление на фиксированный адрес, относящийся к считанному блоку данных. Считается, что считанный блок данных является программным загрузчиком и программный загрузчик раскручивает запуск ОС. Следует отметить, что если аппаратный загрузчик в подавляющем большинстве машин системно независим (то есть он не знает, какая ОС будет загружена), то программный загрузчик — это уже компонент ОС, ему известно, что будет загружаться конкретная ОС, он знает, где размещаются нужные для загрузки данные. В любой системе принято разбиение пространства ВЗУ на некоторые области данных, которые называются блоками. Размер блока (логического блока в ОС) является фиксированным атрибутом. В ОС Unix в различных ее вариациях размер блока был параметром меняющимся в зависимости от варианта ОС. Для простоты и единообразия мы будем считать, что логический блок ВЗУ равен 512 байт. Итак, рассмотрим структуру файловой системы. Представим адресное пространство системного ВЗУ в виде последовательности блоков.
Будем считать, что этих блоков N+M-1. Первый блок — это блок начальной загрузки. Размещение этого блока в нулевом блоке системного устройства определяется аппаратурой, так как аппаратной загрузчик всегда обращается к конкретному блоку системного устройства (к нулевому блоку). Это последний компонент файловой системы, который зависит от аппаратуры. Следующий блок — суперблок файловой системы. Он содержит оперативную информацию о состоянии файловой системы, а также данные о параметрах настройки файловой системы. В частности суперблок имеет информацию о количестве индексных дескрипторов (ИД) в файловой системе; размере файловой системы; свободных блоках файлов; свободных ИД; еще ряд данных, которые мы не будем перечислять в силу уникальности их назначения. Третий блок — область индексных дескрипторов. ИД — это специальная структура данных файловой системы, которая взаимооднозначно соответствует файлу. С каждым содержимым файла связан один и только один ИД. ИД организуют не один блок, а пространство блоков, размеры которого определяются параметром генерации файловой системы (определяется по количеству ИД,указанном в суперблоке). Соответственно, каждый индексный регистр содержит следующую информацию: поле, определяющее тип файла (каталоги и все остальные файлы); код привилегии/защиты; количество ссылок к данному ИД из всевозможных каталогов файловой системы; длина файла; даты и времена (время последней записи, дата создания и т.д.); поле адресации блоков файла. Далее идут блоки файлов. Это пространство ВЗУ, в котором размещается вся информация, находящаяся в файлах и о файлах, которая не поместилась в уже перечисленных блоках. Последняя область данных (она в разных системах размещается по-разному), но для простоты изложения мы будем считать, что эта область находится сразу за блоками файлов — это область сохранения. Это концептуальная схема структуры файловой системы. Теперь давайте вернемся и рассмотрим некоторые ее части более детально. Прежде всего интерес вызывают области свободных блоков файлов и свободных ИД. В Unix видно влияние двух факторов: первый — это то, что файловая система разрабатывалась тогда, когда ВЗУ объемом 5-10Мб считалось очень большим и в реализации алгоритмов по работе с системой видны старания автором по оптимизации этого процесса; и второй — это свойства файловой системы по оптимизации доступа, критерием которого является количество обменов, которые файловая система производит для своих нужд, не связанных с чтением или записью информации файлов. Суперблок содержит список свободных блоков файлов, он состоит из 50 элементов. Суть работы с этим списком заключается в следующем — в буфере, состоящем из 50 элементов (при условии того, что блок — 512 байт, 1 блок — 16 битное слово), в них записаны номера свободных блоков пространства блоков файлов с 2 до 49. В 0 элементе содержится указатель на продолжение массива, а в последнем элементе содержится указатель на свободный элемент в массиве. Если какому-то процессу для расширения файла требуется свободный блок, то система по указателю N/B (номер блока) выбирает элемент массива, и этот блок предоставляется файлу. Если происходит сокращение файла, то высвободившиеся номера добавляются в массив свободных блоков и корректируется указатель N/B. Так как размер массива — 50 элементов, то возможны две критические ситуации: Когда мы освобождаем блоки файлов, а они не могут поместиться в этом массиве. В этом случае из файловой системы выбирается один свободный блок и заполненный полностью массив свободных блоков копируется в этот блок, после этого значение указателя N/B обнуляется, а в нулевой элемент массива, который находится в суперблоке, записывается номер блока, который мы выбрали для копирования содержимого массива. Таким образом, если мы постоянно освобождаем блоки, то образуется список, в котором будут размещены все свободные блоки файловой системы. Когда мы выбрали все свободные блоки и содержимое элементов массива свободных блоков исчерпалось. Если нулевой элемент массива равен нулю, то это означает, что исчерпано все пространство файловой системы. Если этот элемент нулю не равен, то это означает, что существует продолжение массива. Это продолжение считывается в копию суперблока в оперативной памяти. Для получения свободного блока и его освобождения в большинстве случаев не требуется дополнительного обмена. Дополнительный обмен требуется тогда, когда исчерпается содержимое 49 блоков. У нас получается хорошая буферизация, которая сокращает накладные расходы ОС. Список свободных ИД. Это буфер, состоящий из 100 элементов. В нем находится информация о 100 номерах ИД, которые свободны в данный момент. Соответственно, когда нужен новый ИД, то его номер берется из списка свободных ИД, если номер освобождается, то заносится в этот массив. Если же массив переполнен, а освобождается 101 элемент, то это никуда не записывается. Если список ИД переполняется, то система “пробегает” по списку и формирует содержимое этого буфера заново. В ситуации, когда нужно создать файл и нужен новый ИД, а в массиве нет ни одного элемента — запускается процесс поиска нового ИД, и он ничего не находит. Тогда возможны две ситуации: Больше нет свободных блоков для файлов; Нет больше новых ИД. Вот информация о суперблоке. Какие можно сделать выводы и замечания? суперблок всегда находится в ОЗУ; все операции по освобождению блоков, занятию блоков файлов, по занятию и освобождению ИД происходят в ОЗУ (минимизация обменов с диском). Если же содержимое суперблока не записать на диск и выключить питание, то возникнут проблемы (несоответствие реального состояния файловой системы и содержимого суперблока). Но это уже требование к надежности аппаратуры системы. |