Рекомендации по реализации функций подсистемы управления памятью
Компонентами модели виртуальной памяти являются:
- модель оперативной памяти (массив объемом 4096 байт);
- модель файла-подкачки (файл с именем swap.dat объемом 61440 Байт).
Таким образом, объем виртуальной памяти в модели ОС составляет 64 кБайт. При страничной организации памяти она разделяется на 256 страниц по 256 байт, 16 из которых могут находиться в оперативной памяти, а остальные - в файле подкачки.
Будем считать, что в ядре ОС имеются 8 процессов, которые могут осуществлять следующие системные вызовы:
int MyGetMem(int PID, int Size); //Выделение, как минимум, Size байт для процесса с идентификатором PID. Функция возвращает виртуальный адрес начала выделенного блока данных в контексте процесса. Функция возвращает –1, если выделить память не удалось. Для страничной или сегментно-страничной адресации допустимо выделение памяти, кратное размеру страницы. Будем считать, что для сегментной и сегментно-страничной адресации функция MyGetMem всегда порождает новый сегмент;
int MyFreeMem(int PID, int addr); //Освобождает участок виртуальной памяти в контексте процесса PID начиная с виртуального адреса addr до конца сегмента или страницы;
int MyReadMem (int PID, int addr); //Чтение слова из оперативной памяти
int MyWriteMem(int PID, int addr, int data); //Запись слова в оперативную память.
В модели подсистемы управления памятью каждому из восьми процессов должен соответствовать экземпляр класса TMemoryMap. Класс TMemoryMap включает в себя:
§ безразмерную таблицу дескрипторов страниц или сегментов процесса;
§ метод для создания нового дескриптора;
§ метод для удаления существующего дескриптора.
Дескриптор сегмента - это экземпляр класса, включающий в себя:
§ номер сегмента;
§ длину сегмента;
§ адрес сегмента в памяти (файле подкачки) при сегментной организации памяти;
§ признак загружен/выгружен при сегментной организации памяти;
§ указатель на таблицу дескрипторов страниц сегмента при сегментно-страничной организации памяти.
Дескриптор страницы - это экземпляр класса, в котором содержится:
§ номер виртуальной страницы;
§ номер страницы в памяти или файле подкачки;
§ признак загружен/выгружен.
Как и в реальной операционной системе, модель управления памятью оперирует двумя типами адресов: виртуальными и физическими. Формат виртуального адреса зависит от способа организации виртуальной памяти (Рисунок 1.8)
Рисунок 1.8 - Вариант структуры виртуального адреса при различных способах организации виртуальной памяти
При страничной организации памяти в нашей системе может существовать до 256 страниц (16 в оперативной памяти и 240 в файле подкачке). Таким образом, в рамках одного процесса для кодирования номера страницы может потребоваться до 8 бит, для задания смещения внутри страницы тоже потребуется 8 бит.
При сегментной организации, в крайнем случае, программа может использовать все 4096 Байт памяти в рамках одного сегмента. Соответственно, для указания смещения внутри сегмента потребуется 12 разрядов (мы выделяем 16). Остальные 16 разрядов отдаются под номер сегмента.
При сегментно-страничной адресации виртуальный адрес состоит из трех частей - номера сегмента, номера страницы и смещения внутри страницы. Исходя из размера страницы 256 Байт, выделяем под смещение и номер страницы - 8 разрядов, а под номер сегмента - 16 разрядов. Таким образом, у процесса может быть до 65535 сегментов, в каждом сегменте - до 256 страниц.
Модель подсистемы управления памятью должна включать карту свободного пространства виртуальной памяти. Карта может быть представлена как массив векторов. Каждый вектор описывает координаты начала и конца свободного участка.
Рассмотрим процесс функционирования модели управления памятью на примере сегментно-страничной адресации. При старте модели мы считаем, что память не распределена. Вызов функции MyGetMem(1,2000) выполняется примерно по следующему алгоритму:
§ вычисляем количество страниц: ]2000/256[=8;
§ создаем дескриптор сегмента в контексте процесса 1: сегмент 0, длина - 2048 (реальный объем памяти для 8 страниц); создаем указатель на таблицу страниц сегмента;
§ для каждой из восьми страниц сегмента в таблице страниц сегмента 0 определяем ее место в физической памяти:
N вирт. стр | N физ. стр | Устройство |
Mem | ||
Mem | ||
Mem | ||
Mem | ||
Mem | ||
Mem | ||
Mem | ||
Mem |
§ корректируем карту свободной памяти
§ возращаем результат: виртуальный адрес начала зарезервированного участка = 0001 0000
Повторяем тот же системный вызов: MyGetMem(1,2000) :
§ вычисляем количество страниц: ]2000/256[=8;
§ создаем дескриптор сегмента в контексте процесса 1: сегмент 1, длина - 2048 (реальный объем памяти для 8 страниц); создаем указатель на таблицу страниц сегмента;
§ для каждой из восьми страниц сегмента в таблице страниц сегмента 1определяем ее место в физической памяти:
N вирт. стр | N физ. стр | Устройство |
Mem | ||
Mem | ||
A | Mem | |
B | Mem | |
C -->2 | Mem -->File | |
D | Mem | |
E | Mem | |
F | Mem |
§ корректируем карту свободной памяти
§ возращаем результат: виртуальный адрес начала зарезервированного участка = 0001 0000
Теперь модифицируем системный вызов: MyGetMem(0,3000) :
§ вычисляем количество страниц: ]3000/256[=12;
§ создаем дескриптор сегмента в контексте процесса 0: сегмент 0, длина - 3072 (реальный объем памяти для 12 страниц); создаем указатель на таблицу страниц сегмента;
§ для каждой из двенадцати страниц сегмента в таблице страниц сегмента 0определяем ее место в физической памяти:
N вирт. стр | N физ. стр | Устройство |
File | ||
File | ||
2-->C | File-->Mem | |
File | ||
... | ... | File |
A | A | File |
B | B | File |
C | C | File |
§ корректируем карту свободной памяти
§ возвращаем результат: виртуальный адрес начала зарезервированного участка = 0000 0000
Как видим, для различных процессов функция MyGetMem(PID,size) может возвращать абсолютно одинаковый результат.
Теперь проиллюстрируем работу функции MyWriteMem (0,0x00000220,0x55). Помним о том, что все функции управления памятью ОС предоставляют пользователю виртуальные адреса. Тогда в соответствии с рисунком 1.8 определяем, что № сегмента=0, №страницы =2, Смещение на странице =0х20. Страница 2 нулевого сегмента процесса 0 располагается в файле подкачки. Для того чтобы записать в эту страницу число 0х55 необходимо:
1) Отыскать "жертву" среди страниц процессов, занимающих оперативную память. Предположим, алгоритм свопинга использует принцип Random - "жертвой" выбрана страница 0хС. Она меняется местами со страницей 2 в файле подкачки;
2) Корректируем информацию в таблицах страниц процессов 0 и 1. Страница 4 сегмента процесса 1 перемещается в страницу 2 файла подкачки, а страница 2 процесса 0 - в страницу 0хС модели оперативной памяти;
3) Записываем в массив памяти по адресу 0хС20 ( ячейку 3104) число 0х55.
Интерфейс пользователя.Интерфейсная часть должна обеспечивать возможность вызывать функции управления памятью и просматривать таблицы дескрипторов процессов для контроля функционирования системы. Как и в подсистеме управления процессами, предполагаем разделение интерфейса на 2 части: результат выполнения API-функций модели выводится в системный терминал, а ввод команд управления и состояние системных таблиц - на интерфейс фрейма (Рисунок 1.9).
Рисунок 1.9 - Интерфейс подсистемы управления памятью
Управление файлами
Файловая система - это часть операционной системы, назначение которой состоит в том, чтобы обеспечить пользователю удобный интерфейс при работе с данными, хранящимися на диске, и обеспечить совместное использование файлов несколькими пользователями и процессами.
В широком смысле понятие "файловая система" включает:
- совокупность всех файлов на диске,
- наборы структур данных, используемых для управления файлами, такие, например, как каталоги файлов, дескрипторы файлов, таблицы распределения свободного и занятого пространства на диске,
- комплекс системных программных средств, реализующих управление файлами, в частности: создание, уничтожение, чтение, запись, именование, поиск и другие операции над файлами.
Имена файлов
Файлы идентифицируются именами. Пользователи дают файлам символьные имена, при этом учитываются ограничения ОС, как на используемые символы, так и на длину имени. До недавнего времени эти границы были весьма узкими. Так в популярной файловой системе FAT длина имен ограничивается известной схемой 8.3 (8 символов - собственно имя, 3 символа - расширение имени), а в ОС UNIX System V имя не может содержать более 14 символов. Однако пользователю гораздо удобнее работать с длинными именами, поскольку они позволяют дать файлу действительно мнемоническое название, по которому даже через достаточно большой промежуток времени можно будет вспомнить, что содержит этот файл. Поэтому современные файловые системы, как правило, поддерживают длинные символьные имена файлов. Например, Windows NT в своей новой файловой системе NTFS устанавливает, что имя файла может содержать до 255 символов, не считая завершающего нулевого символа.
При переходе к длинным именам возникает проблема совместимости с ранее созданными приложениями, использующими короткие имена. Чтобы приложения могли обращаться к файлам в соответствии с принятыми ранее соглашениями, файловая система должна уметь предоставлять эквивалентные короткие имена (псевдонимы) файлам, имеющим длинные имена. Таким образом, одной из важных задач становится проблема генерации соответствующих коротких имен.
Длинные имена поддерживаются не только новыми файловыми системами, но и новыми версиями хорошо известных файловых систем. Например, в ОС Windows 95 используется файловая система VFAT, представляющая собой существенно измененный вариант FAT. Среди многих других усовершенствований одним из главных достоинств VFAT является поддержка длинных имен. Кроме проблемы генерации эквивалентных коротких имен, при реализации нового варианта FAT важной задачей была задача хранения длинных имен при условии, что принципиально метод хранения и структура данных на диске не должны были измениться.
Обычно разные файлы могут иметь одинаковые символьные имена. В этом случае файл однозначно идентифицируется так называемым составным именем, представляющем собой последовательность символьных имен каталогов. В некоторых системах одному и тому же файлу не может быть дано несколько разных имен, а в других такое ограничение отсутствует. В последнем случае операционная система присваивает файлу дополнительно уникальное имя, так, чтобы можно было установить взаимно-однозначное соответствие между файлом и его уникальным именем. Уникальное имя представляет собой числовой идентификатор и используется программами операционной системы. Примером такого уникального имени файла является номер индексного дескриптора в системе UNIX.
Типы файлов
Файлы бывают разных типов: обычные файлы, специальные файлы, файлы-каталоги.
Обычные файлы в свою очередь подразделяются на текстовые и двоичные. Текстовые файлы состоят из строк символов, представленных в ASCII-коде. Это могут быть документы, исходные тексты программ и т.п. Текстовые файлы можно прочитать на экране и распечатать на принтере. Двоичные файлы не используют ASCII-коды, они часто имеют сложную внутреннюю структуру, например, объектный код программы или архивный файл. Все операционные системы должны уметь распознавать хотя бы один тип файлов - их собственные исполняемые файлы.
Специальные файлы - это файлы, ассоциированные с устройствами ввода-вывода, которые позволяют пользователю выполнять операции ввода-вывода, используя обычные команды записи в файл или чтения из файла. Эти команды обрабатываются вначале программами файловой системы, а затем на некотором этапе выполнения запроса преобразуются ОС в команды управления соответствующим устройством. Специальные файлы, так же как и устройства ввода-вывода, делятся на блок-ориентированные и байт-ориентированные.
Каталог - это, с одной стороны, группа файлов, объединенных пользователем исходя из некоторых соображений (например, файлы, содержащие программы игр, или файлы, составляющие один программный пакет), а с другой стороны - это файл, содержащий системную информацию о группе файлов, его составляющих. В каталоге содержится список файлов, входящих в него, и устанавливается соответствие между файлами и их характеристиками (атрибутами).
В разных файловых системах могут использоваться в качестве атрибутов разные характеристики, например:
- создатель файла,
- признак "только для чтения",
- признак "скрытый файл",
- признак "системный файл",
- времена создания, последнего доступа и последнего изменения,
- текущий размер файла.
Каталоги могут непосредственно содержать значения характеристик файлов, как это сделано в файловой системе MS-DOS, или ссылаться на таблицы, содержащие эти характеристики, как это реализовано в ОС UNIX (рисунок 1.10). Каталоги могут образовывать иерархическую структуру за счет того, что каталог более низкого уровня может входить в каталог более высокого уровня.
Рисунок. 1.10 - Структура каталогов:
(а) - структура записи каталога MS-DOS (32 байта); ( б) - структура записи каталога ОС UNIX
Иерархия каталогов может быть деревом или сетью. Каталоги образуют дерево, если файлу разрешено входить только в один каталог, и сеть - если файл может входить сразу в несколько каталогов. В MS-DOS каталоги образуют древовидную структуру, а в UNIX'е - сетевую. Как и любой другой файл, каталог имеет символьное имя и однозначно идентифицируется составным именем, содержащим цепочку символьных имен всех каталогов, через которые проходит путь от корня до данного каталога.