Физическая организация FAT-системы
Для обеспечения доступа приложений к файлам операционная система с файловой системой FAT использует следующие структуры:
- загрузочные секторы главного и дополнительных разделов;
- загрузочные секторы логических дисков (разделов);
- корневой каталог;
- область данных;
- цилиндр для выполнения диагностических операций чтения-записи.
На дискетах, в отличие от жесткого диска, нет загрузочных секторов главного и дополнительных разделов и диагностического цилиндра. Эти структуры создаются программой Fdisk, которая не применяется для дискет, так как они на разделы не разбиваются. Чтобы установить на один жесткий диск несколько операционных систем, его надо разбить на разделы. В загрузочном секторе главного раздела создается таблица списка разделов.
Загрузочный сектор главного раздела (называемый главной загрузочной записью – Master Boot Record – MBR) является первым сектором на жестком диске (цилиндр 0, головка 0, сектор 1) и состоит из двух элементов:
- таблица главного раздела, содержащая список разделов (максимум четыре) и расположение загрузочных секторов соответствующих логических дисков (первая и последняя головки, первый и последний цилиндры с соответствующими значениями секторов, а также количество секторов);
- главный загрузочный код – небольшая программа, которая выполняется системой BIOS. Основная функция этого кода – передача управления в раздел, который обозначен как активный (загрузочный).
Загрузочный сектор раздела содержит:
- блок параметров диска, в котором содержится информация о разделе (размер, количество секторов, размер кластера, метка тома и др.);
- загрузочный код – программу, с которой начинается процесс загрузки операционной системы (для Ms-Dos и Windows 9x – файл Io.sys).
Загрузочные секторы логических дисков создаются программой Format. Они похожи на загрузочные диски разделов. Однако при загрузке выполняется код только того сектора, который находится в активном разделе.
Логический диск, отформатированный программой Fdisk, состоит из следующих областей (рис. 7.20):
- загрузочный сектор;
- основная FAT-таблица, содержащая информацию о размещении файлов и каталогов на диске;
- копия FAT-таблицы;
- корневой каталог – фиксированная область (16 Кбайт для жесткого диска), позволяющая хранить 512 записей о файлах и каталогах (каждая запись состоит из 32 байтов);
- область данных для размещения всех файлов и каталогов, кроме корневого каталога.
Первые две записи FAT зарезервированы и содержат информацию о самой FAT, все остальные указывают на соответствующие кластеры диска. Индексный указатель принимает значение, характеризующее состояние связанного с ним кластера (для FAT 16):
- кластер свободен (0000h);
- кластер используется (любое значение, кроме специальных);
- последний кластер файла (FFF8h – FFFFh);
- кластер поврежден (FFF7h);
- резервный кластер (FFF6h).
Рис. 7.20.FAT-система
Размер FAT-таблицы определяется количеством кластера. Разрядность индексного указателя FAT-таблицы должна быть такой, чтобы можно было задать максимальный номер кластера диска определенного объема. В соответствии с разрядностью дискового указателя существуют несколько разновидностей FAT: FAT12, FAT16, FAT32 (соответственно 212, 216 и 232 кластеров). Тип используемой FAT определяется программой Fdisk, хотя и записываются они в процессе форматирования высокого уровня программы Format. На всех дискетах применяется FAT 12, на жестких дисках до 512 Мбайт – FAT16, на жестких дисках, имеющих большую емкость при использовании Windows 95 OSR2 и Windows98 – FAT 32 (вообще размер кластера может быть от 1 до 128 секторов или от 512 байт до 64 Кбайт). Максимальный размер раздела FAT16 ограничен объемом 4 Гбайт (216 = 65536 кластеров по 64 Кбайт). Максимальный размер раздела FAT 32 практически не ограничен (232 кластеров по 32 Кбайт).
За копией FAT-таблицы следует корневой каталог – база данных, содержащая информацию о записанных на диске данных. Каждая запись в ней имеет длину 32 байта и содержит всю информацию о файле, которой располагает операционная система. Формат записи приведен ниже.
Смещение | Описание | ||
Hex | Dec | Длина поля | |
00h | 8 байт | Имя файла | |
08h | 3 байт | Расширение файла | |
0Bh | 1 байт | Атрибуты файла | |
0Ch | 10 байт | Зарезервировано | |
16h | 2 байт | Время создания | |
18h | 2 байт | Дата создания | |
1Ah | 2 байт | Начальный кластер | |
1Ch | 4 байт | Размер файла в байтах |
Информация о расположении файла, то есть о расположении оставшихся кластеров, содержится в FAT-таблице. В процессе работы системы кластеры файла могут оказаться не в смежных областях, а будут чередоваться с кластерами других файлов. Однако эту цепочку кластеров легко выделить, зная начальный кластер файлов. На рис. 7.21 показан пример размещения двух файлов.
В корневом каталоге имеются записи не только о файлах, но и подкаталогах. Эти записи имеют точно такую же структуру, что и записи корневого каталога. Признак подкаталогов указывается в атрибутах файла, т.е. можно считать, что подкаталог – это специальный файл. Структура атрибутивного байта показана ниже.
Позиция бита в шестнадцатеричном формате | Значение | Описание | |||||||
01h | Только чтение | ||||||||
02h | Скрытый | ||||||||
04h | Системный | ||||||||
08h | Метка тома | ||||||||
10h | Подкаталог | ||||||||
20h | Архивный (измененный) | ||||||||
40h | Зарезервировано | ||||||||
80h | Зарезервировано |
Рис. 7.21.Пример размещения двух файлов
Файловые системы FAT 12 и FAT16 оперируют с именами файлов, составленных по схеме 8.3 (имя, расширение). В Windows 95 с появлением 32-разрядной виртуальной FAT-VFAT (Virtual file allocation table) поддерживаются имена длиной 255 символов (заметим, что изменился лишь программный код, поддерживающий FAT16, он стал 32-м). Для обеспечения обратной совместимости ОС создает его псевдоним, удовлетворяющий стандарту 8.3. Делается это следующим образом.
1. Первые 3 символа после последней точки в длинном имени файла становятся расширением псевдонима.
2. Первые шесть символов длинного имени файла, за исключением пробелов, которые игнорируются, преобразуются в символы верхнего регистра и становятся шестью символами стандартного имени файла. Недопустимые символы (+ , ; =), которые могут использоваться в Windows 95, преобразуются в символы подчеркивания.
3. Добавляются символы ~1 (седьмой и восьмой) к псевдониму имени файла.
Если первые шесть символов нескольких файлов одни и те же, то добавляются символы ~2, ~3 и т.д.
VFAT хранит псевдонимы длинных имен в поле стандартных имен файлов записи каталога файла. Таким образом, все версии DOS и Windows могут получить доступ к файлу под длинным именем с помощью его псевдонима. Остается проблема: как хранить 255 символов имени файлов 32 байт записи каталога? Разработчики файловой системы решили эту проблему следующим образом: были добавлены дополнительные записи каталога для хранения длинных имен файлов. Чтобы предыдущие версии не повредили эти дополнительные записи каталога, VFAT устанавливает для них атрибуты, которые нельзя использовать для обычного файла: только для чтения, скрытый, системный и метка тома. Такие атрибуты DOS игнорирует, а следовательно, длинные имена файлов остаются нетронутыми. Подобным же образом решается проблема длинных имен в Windows NT/2000/2003/XP, применяющих для хранения имен двухбайтовый формат на каждый символ – Unicode.
Как уже отмечалось, выбор типа FAT-системы во многом определяется емкостью жесткого диска. При использовании FAT16 нельзя создать раздел емкостью более 2-х Гбайт. Для устранения этого ограничения фирма Microsoft разработала FAT 32. Она работает как FAT 16, но имеет отличие в организации хранения данных. Кроме того, FAT 32 можно установить с помощью программы Fdisk. Впервые FAT 32 была реализована в Windows 95 OEM Service Release 2 (OSR2). Она встроена и в Windows 98/Ме/NT/2000.
Основное преимущество FAT 32 – возможность использования 32-разрядных записей вместо 16-разрядных, что приводит к увеличению кластеров (вместо 216=65536) до 268 435 456 в разделе. Это значение в Windows 95 OSR2 эквивалентно 228, а не 232, поскольку 4 бита из 32 зарезервированы для других целей.
При работе в FAT 32 размер раздела может достигать 2 Tбайт при кластере размером 8, 16 или 32 Кбайт. Новая файловая система может иметь 232 кластеров размером 512 байт, а размер единичного файла может составить 4 Гбайт. Реально FAT 32 поддерживает максимальный размер тома до 32 Гбайт. Это связано с тем, что в Windows 2000 это ограничение обусловлено программой Format. Вообще максимально возможный том – 2 Tбайт при кластере 32 Кбайт.
Существует важное отличие FAT 32 от ее предшественниц – положение корневого каталога: он может располагаться в любом месте раздела и иметь любой раздел. Это обеспечивает динамическое изменение размера раздела. Независимые разработчики использовали это свойство. Так, фирма Power-Quest создала программу Partion Magic, позволяющую переопределять разделы после их создания.
Файловая система FAT 32 также использует преимущество двух копий FAT. Как и в FAT 16, в FAT 32 первая копия является основной и периодически копирует данные в дополнительную копию FAT. При проблемах с главной копией FAT системы переключаются в дополнительную копию, которая становится главной.
Примечание: программа Fdisk автоматически определяет размер кластера на основе выбранной файловой системы и размерам раздела. Однако существует недокументированный параметр команды Format, позволяющий явно указать размер кластера: Format/z:n, где n –размер кластера в байтах, кратный 512.
Файловые операции
Набор файловых операций
Файловая система ОС должна предоставлять пользователям набор операций для работы с файлами, оформленный в виде системных вызовов. В различных ОС имеются различные наборы файловых операций. Наиболее часто встречающимися системными вызовами для работы с файлами являются:
1. Create (создание). Файл создается без данных. Этот системный вызов объявляет о появлении нового файла и позволяет установить некоторые его атрибуты;
2. Delete (удаление). Ненужный файл удаляется, чтобы освободить пространство на диске;
3. Open (открытие). До использования файла его нужно открыть. Данный вызов позволяет прочитать атрибуты файла и список дисковых адресов для быстрого доступа к содержимому файла;
4. Close (закрытие). После завершения операций с файлом его атрибуты и дисковые адреса не нужны. Файл следует закрыть, чтобы освободить пространство во внутренней таблице;
5. Read (чтение). Файл читается с текущей позиции. Процесс, работающий с файлом, должен указать (открыть) буфер и количество читаемых данных;
6. Write (запись). Данные записываются в файл в текущую позицию. Если она находится в конце файла, его размер автоматически увеличивается. В противном случае запись производится поверх существующих данных;
7. Append (добавление). Это усеченная форма предыдущего вызова. Данные добавляются в конец файла;
8. Seek (поиск). Данный системный вызов устанавливает файловый указатель в определенную позицию;
9. Get attributes (получение атрибутов). Процессам для работы с файлами бывает необходимо получить их атрибуты;
10. Set attributes (установка атрибутов). Этот вызов позволяет установить необходимые атрибуты файлу после его создания;
11. Rename (переименование). Этот системный вызов позволяет изменить имя файла. Однако такое действие можно выполнить копированием файла. Поэтому данный системный вызов не является необходимым;
12. Execute (выполнить). Используя этот системный вызов, файл можно запустить на выполнение.
Рассмотрим примеры файловых операций в ОС Windows 2000 и UNIX. Как и в других ОС, в Windows 2000 есть свой набор системных вызовов, которые она может выполнять. Однако корпорация Microsoft никогда не публиковала список системных вызовов Windows, кроме того, она постоянно меняет их от одного выпуска к другому. Вместо этого Microsoft определила набор функциональных вызовов, называемый Win 32 API (Win 32 Application Programming Interface). Эти вызовы опубликованы и полностью документированы. Они представляют собой библиотечные процедуры, которые либо обращаются к системным вызовам, чтобы выполнить требуемую работу, либо выполняют ее прямо в пространстве пользователя.
Философия Win 32 API заключается в предоставлении всеобъемлющего интерфейса, с возможностью выполнить одно и то же требование несколькими (тремя-четырьмя) способами. В ОС UNIX все системные вызовы формируют минимальный интерфейс: удаление даже одного из них приведет к снижению функциональности ОС.
Многие вызовы API создают объекты ядра того или иного типа (файлы, процессы, потоки, каналы и т.д.). Каждый вызов, создающий объект, возвращает вызывающему процессу результат, называемый дескриптором (небольшое целое число). Дескриптор используется впоследствии для выполнения операций с объектами. Он не может быть передан другому процессу и использован им. Однако при определенных обстоятельствах дескриптор может быть дублирован и передан другому процессу защищенным способом, что предоставляет второму процессу контролируемый доступ к объекту, принадлежащему первому процессу. С каждым объектом ассоциирован дескриптор безопасности, описывающий, кто и какие действия может, а какие не может выполнять с данным объектом.
Основные функции Win 32 API для файлового ввода-вывода и соответствующие системные вызовы ОС UNIX приведены ниже.
Функция Win 32 API | Системные вызовы UNIX | Описание |
CreateFile | open | Создать или открыть файл; вернуть дескриптор файла |
DeleteFile | unlink | Удалить существующий файл |
CloseHandle | close | Закрыть файл |
ReadFile | read | Прочитать данные из файла |
WriteFile | write | Записать данные в файл |
SetFilePointer | lseek | Установить указатель в файле в определенную позицию |
GetFileAttributes | stat | Вернуть атрибуты файла |
LockFile | fcntl | Заблокировать область файла для обеспечения взаимного исключения |
UnlockFile | fcntl | Отменить блокировку области файла |
Аналогично файловым операциям обстоит дело с операциями управления каталогами. Основные функции Win 32 API и системные вызовы UNIX для управления каталогами приведены ниже.
Функция Win 32 API | Системные вызовы UNIX | Описание |
CreateDirectory | mkdir | Создать новый каталог |
RemoveDirectory | rmdir | Удалить пустой каталог |
FindFirstFile | opendir | Инициализация, чтобы начать чтение записей каталога |
FindNextFile | readdir | Прочитать следующую запись каталога |
MoveFile | rename | Переместить файл из одного каталога в другой |
SetCurrentDirectory | chdir | Изменить текущий рабочий каталог |
Способы выполнения файловых операций
Чаще всего с одним и тем же файлом пользователь выполняет не одну, а последовательность операций. Независимо от набора этих операций операционной системе необходимо выполнить ряд постоянных (универсальных) для всех операций действий.
1. По символьному имени файла найти его характеристики, которые хранятся в файловой системе на диске.
2. Скопировать характеристики в оперативную память, поскольку только в этом случае программный код может их использовать.
3. На основании характеристик файла проверить права пользователя на выполнение запрошенной операции.
4. Очисть область памяти, отведенную под временное хранение характеристик файла.
Кроме того, каждая операция включает ряд уникальных для нее действий, например, чтение определенного набора кластеров диска, удаление файла, изменение его атрибутов и т.п.
ОС может выполнить последовательность действий над файлами двумя способами (см. рис. рис. 7.22).
1. Для каждой операции выполняются как универсальные, так и уникальные действия. Такая схема иногда называется схемой без заполнения состояния операции (stateless).
2. Все универсальные действия выполняются в начале и конце последовательности операций, а для каждой промежуточной операции выполняются только уникальные действия.
Рис. 7.22.Варианты выполнения последовательности действий над файлами
Подавляющее большинство файловых систем поддерживает второй способ, как более экономичный и быстрый. Однако первый способ более устойчив к сбоям в работе системы, так как каждая операция является самодостаточной и не зависит от результата предыдущей. Поэтому первый способ иногда применяется в распределенных сетевых файловых системах, когда сбои из-за потерь пакетов или отказов одного из сетевых узлов более вероятны, чем при локальном доступе к данным.
При втором способе в ФС вводится два специальных системных вызова: open и close. Первый выполняется перед началом любой последовательности операций с файлом, а второй – после окончания работы с файлом.
Основной задачей вызова open является преобразование символьного имени файла в его уникальное числовое имя, копирование характеристик файла из дисковой области в буфер оперативной памяти и проверка прав пользователя на выполнение запрошенной операции. Вызов close освобождает буфер с характеристиками файла и делает невозможным продолжение операций с файлами без его повторного открытия.
Приведем несколько примеров системных вызовов для работы с файлами. Системный вызов create в ОС UNIX работает с двумя аргументами: символьным именем открываемого файла и режимом защиты. Так команда
fd = create ("abc", mode);
создает файл abc с режимом защиты, указанным в переменной mode. Биты mode определяют круг пользователей, которые могут получить доступ к файлам, и уровень предоставляемого им доступа. Системный вызов create не только создает новый файл, но также открывает его для записи. Чтобы последующие системные вызовы могли получить доступ к файлу, успешный системный вызов create возвращает небольшое неотрицательное целое число – дескриптор файла – fd. Если системный вызов выполняется с существующим файлом, длина этого файла уменьшается до 0, а все содержимое теряется.
Чтобы прочитать данные из существующего файла или записать в него данные, файл сначала нужно открыть с помощью системного вызова open с двумя аргументами: символьным именем файла и режимом открытия файла (для записи, чтения или того т другого), например
fd = open ("file", how);
Системные вызовы create и open возвращают наименьший неиспользуемый в данный момент дескриптор файла. Когда программа начинает выполнение стандартным образом, файлы с дескрипторами 0, 1 и 2 уже открыты для стандартного ввода, стандартного вывода и стандартного потока сообщений об ошибках.
В стандарте языка Си отсутствуют средства ввода-вывода. Все операции ввода-вывода реализуются с помощью функций, находящихся в библиотеке языка, поставляемой в составе системы программирования Си. На стандартный поток ввода ссылаются через указатель stdin, вывода – stdout, сообщений об ошибках – stderr. По умолчанию потоку ввода stdin ставится в соответствие клавиатура, а потокам stdout и stderr – экран дисплея.
Для ввода-вывода данных с помощью стандартных потоков в библиотеке Си определены функции:
- getchar ( )/putchar ( ) – ввод-вывод отдельного символа;
- gets ( )/ puts ( ) – ввод-вывод строки;
- scanf ( )/ printf ( ) – ввод-вывод в режиме форматирования данных.
Процесс в любое время может организовать ввод данных из стандартного файла ввода, выполнить символьный вызов:
read (stdin, buffer, nbyts);
Аналогично организуется вывод в стандартный файл вывода
write (stdout, buffer, nbytes).
При работе в Windows 2000 с помощью функции CreateFile можно создать файл и получить дескриптор к нему. Эту же функцию следует применять и для открытия уже существующего файла, так как в Win 32 API нет специальной функции File Open. Параметры функций, как правило, многочисленны, например, функция CreateFile имеет семь параметров:
1. указатель на имя файла, который нужно создать или открыть;
2. флаги (биты), указывающие, может ли с этим файлом выполняться чтение, запись или то и другое;
3. флаги, указывающие, может ли этот файл одновременно открываться несколькими процессами;
4. указатель на описатель защиты, сообщение, кто может получать доступ к файлу;
5. флаги, сообщающие, что делать, если файл существует или, наоборот, не существует;
6. флаги, управляющие архивацией, сжатием и т.д.;
7. дескриптор файла, чьи атрибуты должны быть клонированы для нового файла,
Fd = CreateFile ("data", GENERIC_READ, O, NULL, OPEN_EXSTING, O, NULL).
Дата добавления: 2018-05-10; просмотров: 1576;