The design of the unix operating system by Maurice J
Вид материала | Реферат |
- Лекция 10. Файловые системы Unix, 116.79kb.
- Уровни рассмотрения, 314.07kb.
- Курс по операционным системам (на примере ос windows) Основан на учебном курсе Windows, 29.21kb.
- Выполнил ученик 11 «А» класса, 443.51kb.
- Ос лекция 1 (2-й семестр – временно), 101.4kb.
- Operating System, 7686.97kb.
- Unix-подобные операционные системы, характеристики, особенности, разновидности, 40.63kb.
- 1. ms sql server. Общие сведения, 66.03kb.
- Shanti ananda maurice, 89.84kb.
- Методические материалы, 3002.45kb.
Обычные файлы и каталоги хранятся в системе UNIX на устройс-
твах ввода-вывода блоками, таких как магнитные ленты или диски.
Поскольку существует некоторое различие во времени доступа к этим
устройствам, при установке системы UNIX на лентах размещают фай-
ловые системы. С годами бездисковые автоматизированные рабочие
места станут общим случаем, и файлы будут располагаться в удален-
ной системе, доступ к которой будет осуществляться через сеть
(см. главу 13). Для простоты, тем не менее, в последующем тексте
подразумевается использование дисков. В системе может быть нес-
колько физических дисков, на каждом из которых может размещаться
одна и более файловых систем. Разбивка диска на несколько файло-
вых систем облегчает администратору управление хранимыми данными.
На логическом уровне ядро имеет дело с файловыми системами, а не
с дисками, при этом каждая система трактуется как логическое уст-
ройство, идентифицируемое номером. Преобразование адресов логи-
ческого устройства (файловой системы) в адреса физического уст-
ройства (диска) и обратно выполняется дисковым драйвером. Термин
"устройство" в этой книге используется для обозначения логическо-
го устройства, кроме специально оговоренных случаев.
Файловая система состоит из последовательности логических
блоков длиной 512, 1024, 2048 или другого числа байт, кратного
512, в зависимости от реализации системы. Размер логического бло-
ка внутри одной файловой системы постоянен, но может варьировать-
ся в разных файловых системах в данной конфигурации. Использова-
ние логических блоков большого размера увеличивает скорость пере-
дачи данных между диском и памятью, поскольку ядро сможет
передать больше информации за одну дисковую операцию, и сокращает
количество продолжительных операций. Например, чтение 1 Кбайта с
диска за одну операцию осуществляется быстрее, чем чтение 512
байт за две. Однако, если размер логического блока слишком велик,
полезный объем памяти может уменьшиться, это будет показано в
главе 5. Для простоты термин "блок" в этой книге будет использо-
ваться для обозначения логического блока, при этом подразумевает-
ся логический блок размером 1 Кбайт, кроме специально оговоренных
случаев.
----------T---------T---------------T-------------┐
│ │ │ │ │
L---------+---------+---------------+--------------
блок супер- список индексов информационные
загрузки блок блоки
Рисунок 2.3. Формат файловой системы
Файловая система имеет следующую структуру (Рисунок 2.3).
* Блок загрузки располагается в начале пространства, отведенного
под файловую систему, обычно в первом секторе, и содержит прог-
рамму начальной загрузки, которая считывается в машину при заг-
рузке или инициализации операционной системы. Хотя для запуска
системы требуется только один блок загрузки, каждая файловая
система имеет свой (пусть даже пустой) блок загрузки.
* Суперблок описывает состояние файловой системы - какого она
размера, сколько файлов может в ней храниться, где располагает-
ся свободное пространство, доступное для файловой системы, и
другая информация.
* Список индексов в файловой системе располагается вслед за су-
перблоком. Администраторы указывают размер списка индексов при
генерации файловой системы. Ядро операционной системы обращает-
ся к индексам, используя указатели в списке индексов. Один из
индексов является корневым индексом файловой системы: это ин-
декс, по которому осуществляется доступ к структуре каталогов
файловой системы после выполнения системной операции mount
(монтировать) (раздел 5.14).
* Информационные блоки располагаются сразу после списка индексов
и содержат данные файлов и управляющие данные. Отдельно взятый
информационный блок может принадлежать одному и только одному
файлу в файловой системе.
2.2.2 Процессы
В этом разделе мы рассмотрим более подробно подсистему управ-
ления процессами. Даются разъяснения по поводу структуры процесса
и некоторых информационных структур, используемых при распределе-
нии памяти под процессы. Затем дается предварительный обзор диаг-
раммы состояния процессов и затрагиваются различные вопросы, свя-
занные с переходами из одного состояния в другое.
Процессом называется последовательность операций при
выполнении программы, которые представляют собой наборы байтов,
интерпретируемые центральным процессором как машинные инструкции
(т.н. "текст"), данные и стековые структуры. Создается впечатле-
ние, что одновременно выполняется множество процессов, поскольку
их выполнение планируется ядром, и, кроме того, несколько процес-
сов могут быть экземплярами одной программы. Выполнение процесса
заключается в точном следовании набору инструкций, который явля-
ется замкнутым и не передает управление набору инструкций другого
процесса; он считывает и записывает информацию в раздел данных и
в стек, но ему недоступны данные и стеки других процессов. Одни
процессы взаимодействуют с другими процессами и с остальным миром
посредством обращений к операционной системе.
С практической точки зрения процесс в системе UNIX является
объектом, создаваемым в результате выполнения системной операции
fork. Каждый процесс, за исключением нулевого, порождается в ре-
зультате запуска другим процессом операции fork. Процесс, запус-
тивший операцию fork, называется родительским, а вновь созданный
процесс - порожденным. Каждый процесс имеет одного родителя, но
может породить много процессов. Ядро системы идентифицирует каж-
дый процесс по его номеру, который называется идентификатором
процесса (PID). Нулевой процесс является особенным процессом, ко-
торый создается "вручную" в результате загрузки системы; после
порождения нового процесса (процесс 1) нулевой процесс становится
процессом подкачки. Процесс 1, известный под именем init, являет-
ся предком любого другого процесса в системе и связан с каждым
процессом особым образом, описываемым в главе 7.
Пользователь, транслируя исходный текст программы, создает
исполняемый файл, который состоит из нескольких частей:
* набора "заголовков", описывающих атрибуты файла,
* текста программы,
* представления на машинном языке данных, имеющих начальные
значения при запуске программы на выполнение, и указания на то,
сколько пространства памяти ядро системы выделит под неинациали-
зированные данные, так называемые bss (*) (ядро устанавливает их
в 0 в момент запуска),
* других секций, таких как информация символических таблиц.
Для программы, приведенной на Рисунке 1.3, текст исполняемого
файла представляет собой сгенерированный код для функций main и
copy, к определенным данным относится переменная version (встав-
ленная в программу для того, чтобы в последней имелись некоторые
определенные данные), а к неопределенным - массив buffer. Компи-
лятор с языка Си для системы версии V создает отдельно текстовую
секцию по умолчанию, но не исключается возможность включения инс-
трукций программы и в секцию данных, как в предыдущих версиях
системы.
Ядро загружает исполняемый файл в память при выполнении сис-
темной операции exec, при этом загруженный процесс состоит по
меньшей мере из трех частей, так называемых областей: текста,
данных и стека. Области текста и данных корреспондируют с секция-
ми текста и bss-данных исполняемого файла, а область стека созда-
ется автоматически и ее размер динамически устанавливается ядром
системы во время выполнения. Стек состоит из логических записей
активации, помещаемых в стек при вызове функции и выталкиваемых
из стека при возврате управления в вызвавшую процедуру; специаль-
ный регистр, именуемый указателем вершины стека, показывает теку-
щую глубину стека. Запись активации включает параметры передавае-
------------------------------------------------
(*) Сокращение bss имеет происхождение от ассемблерного псевдоо-
ператора для машины IBM 7090 и расшифровывается как "block
started by symbol" ("блок, начинающийся с символа").
мые функции, ее локальные переменные, а также данные, необходимые
для восстановления предыдущей записи активации, в том числе зна-
чения счетчика команд и указателя вершины стека в момент вызова
функции. Текст программы включает последовательности команд, уп-
равляющие увеличением стека, а ядро системы выделяет, если нужно,
место под стек. В программе на Рисунке 1.3 параметры argc и argv,
а также переменные fdold и fdnew, содержащиеся в вызове функции
main, помещаются в стек, как только встретилось обращение к функ-
ции main (один раз в каждой программе, по условию), так же и па-
раметры old и new и переменная count, содержащиеся в вызове функ-
ции copy, помещаются в стек в момент обращения к указанной функ-
ции.
Поскольку процесс в системе UNIX может выполняться в двух ре-
жимах, режиме ядра или режиме задачи, он пользуется в каждом из
этих режимов отдельным стеком. Стек задачи содержит аргументы,
локальные переменные и другую информацию относительно функций,
выполняемых в режиме задачи. Слева на Рисунке 2.4 показан стек
задачи для процесса, связанного с выполнением системной операции
write в программе copy. Процедура запуска процесса (включенная в
библиотеку) обратилась к функции main с передачей ей двух пара-
метров, поместив в стек задачи запись 1; в записи 1 есть место
для двух локальных переменных функции main. Функция main затем
вызывает функцию copy с передачей ей двух параметров, old и new,
и помещает в стек задачи запись 2; в записи 2 есть место для ло-
кальной переменной count. Наконец, процесс активизирует системную
операцию write, вызвав библиотечную функцию с тем же именем. Каж-
дой системной операции соответствует точка входа в библиотеке
системных операций; библиотека системных операций написана на
языке ассемблера и включает специальные команды прерывания, кото-
рые, выполняясь, порождают "прерывание", вызывающее переключение
аппаратуры в режим ядра. Процесс ищет в библиотеке точку входа,
соответствующую отдельной системной операции, подобно тому, как
он вызывает любую из функций, создавая при этом для библиотечной
функции запись активации. Когда процесс выполняет специальную ин-
струкцию, он переключается в режим ядра, выполняет операции ядра
и использует стек ядра.
Стек ядра содержит записи активации для функций, выполняющих-
ся в режиме ядра. Элементы функций и данных в стеке ядра соот-
ветствуют функциям и данным, относящимся к ядру, но не к програм-
ме пользователя, тем не менее, конструкция стека ядра подобна
конструкции стека задачи. Стек ядра для процесса пуст, если про-
цесс выполняется в режиме задачи. Справа на Рисунке 2.4 представ-
лен стек ядра для процесса выполнения системной операции write в
программе copy. Подробно алгоритмы выполнения системной операции
write будут описаны в последующих разделах.
Стек задачи Направление Стек ядра
---------------┐ увеличения стека -------------------┐
│ Локальные │ │ │
│ переменные │ │ │ │
│ (не показаны)│ │ │ . │
│--------------│ │ │ . │
│Адрес записи 2│ │ │ . │
│--------------│ │ │ . │
│Адрес возврата│ │ │ . │
│ после вызова │ │ │ . │
│ write │ │ │ . │
│--------------│ │ │ . │
│параметры, пе-│ │ │ . │
│ редаваемые │ │ │ . │
│ write │ │ │ . │
│(new, buffer, │ │ │ v │
│ count) │ Запись 3 │ │
+--------------+ call write() Запись 3 +------------------+
│ Локальные │ │ Локальные │
│ переменные │ │ переменные │
│ (count) │ │ │
│--------------│ │------------------│
│Адрес записи 1│ │ Адрес записи 1 │
│--------------│ │------------------│
│Адрес возврата│ │ Адрес возврата │
│ после вызова │ │ после вызова │
│ copy │ │ func2 │
│--------------│ │------------------│
│параметры, пе-│ │ параметры, пере- │
│ редаваемые │ │ даваемые функции │
│ copy │ │ ядра func2 │
│ (old, new) │ Запись 2 Запись 2 │ │
+--------------+ call copy() call func2() +------------------+
│ Локальные │ │ Локальные │
│ переменные │ │ переменные │
│(fdold, fdnew)│ │ │
│--------------│ │------------------│
│Адрес записи 0│ │ Адрес записи 0 │
│--------------│ │------------------│
│Адрес возврата│ │ Адрес возврата │
│ после вызова │ │ после вызова │
│ main │ │ func1 │
│--------------│ │------------------│
│параметры, пе-│ │ параметры, пере- │
│ редаваемые │ │ даваемые функции │
│ main │ │ ядра func1 │
│ (argc, argv) │ Запись 1 Запись 1 │ │
L--------------- call main() call func1() L-------------------
Запись 0 Запись 0
Старт Интерфейс
обращений к
операционной
системе
Рисунок 2.4. Стеки задачи и ядра для программы копирования.
промежуточная
таблица облас- таблица
тей процессов областей
----------------------┐ --------------┐ -------------┐
│ часть адресного про-│ │ │ │ │
│ странства задачи, │ │ │ │ │
│ выделенная процессу │ │ │ │ │
L---------------------- +-------------+ +------------+
---+-> ---+-----+-> │
│ │ +-------------+ +-----+------+
-----------+----------┐ +--+-> ---+--┐ │ │ │
│ │ │ │ +-------------+ │ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ +-----+------+
+----------+----------+ │ │ │ L--+-> │ │
│ v -----+--- │ │ +-----+---+--+
+---------------------+ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ L-------------- L-----+---+---
│ │ │ │
L---------------------- │ │
таблица процессов --------------------------+---+--┐
│ оперативная память v v │
L---------------------------------
Рисунок 2.5. Информационные структуры для процессов
Каждому процессу соответствует точка входа в таблице процес-
сов ядра, кроме того, каждому процессу выделяется часть оператив-
ной памяти, отведенная под задачу пользователя. Таблица процессов
включает в себя указатели на промежуточную таблицу областей про-
цессов, точки входа в которую служат в качестве указателей на
собственно таблицу областей. Областью называется непрерывная зона
адресного пространства, выделяемая процессу для размещения текс-
та, данных и стека. Точки входа в таблицу областей описывают ат-
рибуты области, как например, хранятся ли в области текст прог-
раммы или данные, закрытая ли эта область или же совместно ис-
пользуемая, и где конкретно в памяти размещается содержимое об-
ласти. Внешний уровень косвенной адресации (через промежуточную
таблицу областей, используемых процессами, к собственно таблице
областей) позволяет независимым процессам совместно использовать
области. Когда процесс запускает системную операцию exec, ядро
системы выделяет области под ее текст, данные и стек, освобождая
старые области, которые использовались процессом. Если процесс
запускает операцию fork, ядро удваивает размер адресного прост-
ранства старого процесса, позволяя процессам совместно использо-
вать области, когда это возможно, и, с другой стороны, производя
физическое копирование. Если процесс запускает операцию exit, яд-
ро освобождает области, которые использовались процессом. На Ри-
сунке 2.5 изображены информационные структуры, связанные с запус-
ком процесса. Таблица процессов ссылается на промежуточную
таблицу областей, используемых процессом, в которой содержатся
указатели на записи в собственно таблице областей, соответствую-
щие областям для текста, данных и стека процесса.
Запись в таблице процессов и часть адресного пространства за-
дачи, выделенная процессу, содержат управляющую информацию и дан-
ные о состоянии процесса. Это адресное пространство является
расширением соответствующей записи в таблице процессов, различия
между данными объектами будут рассмотрены в главе 6. В качестве
полей в таблице процессов, которые рассматриваются в последующих
разделах, выступают:
* поле состояния,
* идентификаторы, которые характеризуют пользователя, являю-
щегося владельцем процесса (код пользователя или UID),
* значение дескриптора события, когда процесс приостановлен
(находится в состоянии "сна").
Адресное пространство задачи, выделенное процессу, содержит
описывающую процесс информацию, доступ к которой должен обеспечи-
ваться только во время выполнения процесса. Важными полями явля-
ются:
* указатель на позицию в таблице процессов, соответствующую
текущему процессу,
* параметры текущей системной операции, возвращаемые значения
и коды ошибок,
* дескрипторы файла для всех открытых файлов,
* внутренние параметры ввода-вывода,
* текущий каталог и текущий корень (см. главу 5),
* границы файлов и процесса.
Ядро системы имеет непосредственный доступ к полям адресного
пространства задачи, выделенного выполняемому процессу, но не
имеет доступ к соответствующим полям других процессов. С точки
зрения внутреннего алгоритма, при обращении к адресному прост-
ранству задачи, выделенному выполняемому процессу, ядро ссылается
на структурную переменную u, и, когда запускается на выполнение
другой процесс, ядро перенастраивает виртуальные адреса таким об-
разом, чтобы структурная переменная u указывала бы на адресное
пространство задачи для нового процесса. В системной реализации
предусмотрено облегчение идентификации текущего процесса благода-
ря наличию указателя на соответствующую запись в таблице процес-
сов из адресного пространства задачи.
2.2.2.1 Контекст процесса
Контекстом процесса является его состояние, определяемое
текстом, значениями глобальных переменных пользователя и информа-
ционными структурами, значениями используемых машинных регистров,
значениями, хранимыми в позиции таблицы процессов и в адресном
пространстве задачи, а также содержимым стеков задачи и ядра, от-
носящихся к данному процессу. Текст операций системы и ее гло-
бальные информационные структуры совместно используются всеми
процессами, но не являются составной частью контекста процесса.
Говорят, что при запуске процесса система исполняется в кон-
тексте процесса. Когда ядро системы решает запустить другой про-
цесс, оно выполняет переключение контекста с тем, чтобы система
исполнялась в контексте другого процесса. Ядро осуществляет пе-
реключение контекста только при определенных условиях, что мы
увидим в дальнейшем. Выполняя переключение контекста, ядро сохра-
няет информацию, достаточную для того, чтобы позднее переключить-
ся вновь на первый процесс и возобновить его выполнение. Анало-
гичным образом, при переходе из режима задачи в режим ядра, ядро
системы сохраняет информацию, достаточную для того, чтобы позднее
вернуться в режим задачи и продолжить выполнение с прерванного
места. Однако, переход из режима задачи в режим ядра является
сменой режима, но не переключением контекста. Если обратиться еще
раз к Рисунку 1.5, можно сказать, что ядро выполняет переключение
контекста, когда меняет контекст процесса A на контекст процесса
B; оно меняет режим выполнения с режима задачи на режим ядра и