Типы файловых систем — в чем разница между FAT32, NTFS и exFAT. Что надо делать, если пропали данные Что такое фат таблицы

05.05.2024

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

В большинстве случаев пользователи довольствуются знанием, что NTFS «лучше» , и выбирают этот вариант.

Однако иногда им становится интересно, а чем именно лучше?

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

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

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

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

С точки зрения ОС, жесткий диск – это набор кластеров.

Кластер – это область диска определенного размера для хранения данных. Минимальный размер кластера – 512 байт. Поскольку используется двоичная система счисления, то размеры кластеров кратны степени двойки.

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

Для жестких дисков в ПК в данный момент наиболее распространены две файловые системы: FAT или NTFS . Сначала появилась FAT (FAT16) , затем FAT32 , а потом NTFS .

FAT (FAT16) это аббревиатура от File Allocation Table (в переводе Таблица Размещения Файлов ).

Структура FAT была разработана Биллом Гейтсом и Марком МакДональдом в 1977 году. Использовалась в качестве основной файловой системы в операционных системах DOS и Microsoft Windows (до версии Windows ME).

Существует четыре версии FAT - FAT12 , FAT16 , FAT32 и exFAT . Они отличаются количеством бит, отведённых для хранения номера кластера.

FAT12 применяется в основном для дискет, FAT16 - для дисков малого объёма, а новая exFAT преимущественно для флэш-накопителей. Максимальный размер кластера, который поддерживается в FAT, составляет 64Кб. ()

FAT16 впервые представлена в ноябре 1987 года. Индекс 16 в названии показывает, что для номера кластера используется 16 бит. Вследствие этого максимальный объем раздела диска (тома), который может поддерживать эта система, равен 4Гб.

Позже, с развитием технологий и появлением дисков объемом более 4Гб, появилась файловая система FAT32 . Она использует 32-разрядную адресацию кластеров и появилась вместе с Windows 95 OSR2 в августе 1996 года. FAT32 ограничена в размере тома в 128Гб. Также эта система может поддерживать длинные имена файлов. ().

NTFS (аббревиатура New Technology File System - Файловая Система Новой Технологии ) - стандартная файловая система для семейства операционных систем Microsoft Windows NT.

Представлена 27 июля 1993 вместе с Windows NT 3.1. NTFS разработана на основе файловой системы HPFS (аббревиатура High Performance File System - Высокопроизводительная Файловая Система ), создававшейся Microsoft совместно с IBM для операционной системы OS/2.

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

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

Во время установки ОС Windows ХР предлагается отформатировать диск в системе FAT или NTFS . При этом имеется в виду FAT32 .

Все файловые системы построены на принципе: один кластер – один файл. Т.е. один кластер хранит данные только одного файла.

Основное отличие для обычного пользователя между этими системами – размер кластера. «Давным-давно, когда диски были маленькими, а файлы – очень маленькими» это было очень заметно.

Рассмотрим на примере одного тома на диске объемом 120Гб и файла размером 10Кб.

Для FAT32 размер кластера будет 32Кб, а для NTFS – 4Кб.

В FAT32 такой файлзаймет 1 кластер, при этом останется 32-10=22Кб незанятого места.

В NTFS такой файлзаймет 3 кластера, при этом останется 12-10=2Кб незанятого места.

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

Таким образом, переход от FAT32 к NTFS позволяет более оптимально использовать жесткий диск при наличии большого количества мелких файлов в системе.

В 2003 году у меня был диск на 120Гб, разделенный на тома по 40 и 80Гб. Когда я перешел с Windows 98 на Windows ХР и конвертировал диск с FAT32 в NTFS , я получил около 1Гб освободившегося места на диске. В то время это была существенная «прибавка».

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

Том – это синоним раздела диска, пользователи том обычно называют «диск С», «диск Д» и т.д. Пример показан на картинке ниже:

В настоящий момент широко используются диски объемом 320Гб и больше. Поэтому я рекомендую использовать систему NTFS для оптимального использования дискового пространства.

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

В организациях при работе в локальной сети системные администраторы используют и остальные возможности NTFS.

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

При написании статьи использованы материалы сайтов ru.wikipedia.org

Автор статьи: Максим Тельпари
Пользователь ПК с 15-ти летним стажем. Специалист службы поддержки видеокурса "Уверенный пользователь ПК", изучив который Вы научитесь собирать компьютер, устанавливать Windows XP и драйверы, восстанавливать систему, работать в программах и многое другое.

Заработайте на этой статье!
Зарегистрируйтесь в партнерской программе. Замените в статье ссылку на курс на свою партнерскую ссылку. Добавьте статью на свой сайт. Получить версию для перепечатки можно .

Файловая система FAT (File Allocation Table - таблица размещения файлов) по­лучила свое название благодаря простой таблице, в которой указываются:

Непосредственно адресуемые участки логического диска, отведенные для раз­мещения в них файлов или их фрагментов;

Свободные области дискового пространства;

Дефектные области диска (эти области содержат дефектные участки и не га­рантируют чтение и запись данных без ошибок).

В файловой системе FAT дисковое пространство любого логического диска де­лится на две области (рис. 6.1): системную область и область данных.

Рис. 6.1. Структура логического диска в FAT

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


Файловая система FAT________________________________________________ 167

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

Загрузочной записи (Boot Record, BR);

Зарезервированных секторов (Reserved Sectors, ResSec);

Таблицы размещения файлов (File Allocation Table, FAT);

Корневого каталога (Root Directory, RDir).

Таблица размещения файлов

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

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

Каждый файл занимает целое число кластеров. Последний кластер при этом мо­жет быть задействован не полностью, что при большом размере кластера может приводить к заметной потере дискового пространства. На дискетах кластер зани­мает один или два сектора, а на жестких дисках его размер зависит от объема раз­дела (табл. 6.1). В таблице FAT кластеры, принадлежащие одному файлу (или файлу-каталогу), связываются в цепочки. Для указания номера кластера в файло­вой системе FAT 16 используется 16-разрядное слово, следовательно, можно иметь до 2 10 = 65 536 кластеров (с номерами от 0 до 65 535).

Таблица 6.1 . Соотношения между размером раздела и размером кластеров в FAT16

Емкость раздела, Мбайт Количество секторов в кластере Размер кластеров, Кбайт

Заметим, что в Windows NT/2000/XP разделы файловой системы FAT могут иметь размер до 4097 Мбайт. В этом случае кластер будет объединять уже 128 секторов.

Номер кластера всегда относится к области данных диска (пространству, зарезер­вированному для файлов и подкаталогов). Номера кластеров соответствуют эле-


168____________________________________________ Глава 6, Файловые системы

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

Логическое разбиение области данных на кластеры как совокупности секторов взамен использования одиночных секторов имеет следующий смысл:

Прежде всего, уменьшается размер самой таблицы FAT; - уменьшается возможная фрагментация файлов;

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

Однако слишком большой размер кластера ведет к неэффективному использова­нию области данных, особенно в случае большого количества маленьких файлов. Как мы только что заметили, в среднем на каждый файл теряется около половины кластера. Из табл. 6.1 следует, что при размере кластера в 32 сектора (объем разде­ла при этом - от 512 до 1023 Мбайт), то есть 16 Кбайт, средняя величина потерь на файл равняется 8 Кбайт, и при нескольких тысячах файлов 1 потери могут со­ставлять более 100 Мбайт. Поэтому в современных файловых системах размеры кластеров ограничиваются (обычно от 512 байт до 4 Кбайт), либо предоставляет­ся возможность выбирать размер кластера.

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

Рис. 6.2. Иллюстрация основной концепции FAT

Из рисунка видно, что файл MYFILE.TXT размещается, начиная с восьмого кластера. Всего файл MYFILE.TXT занимает 12 кластеров. Цепочка (chain) кластеров для на­шего примера может быть записана следующим образом: 8, 9,0А, 0В, 15,16,17,19,

1 Например, число 10 000-15 000 файлов (или даже более, особенно когда файлы небольшого разме­ра) на логическом диске с объемом в 1000 Мбайт встречается достаточно часто.


Файловая система FAT 169

1А, 1B, 1С, 1D. Кластер с номером 18 помечен специальным кодом F7 как плохой (bad), он не может быть использован для размещения данных. При форматирова­нии обычно проверяется поверхность магнитного диска, и те сектора, при конт­рольном чтении с которых происходили ошибки, помечаются в FAT как плохие. Кластер 1D помечен кодом FF как конечный (последний в цепочке) кластер, принадлежащий данному файлу. Свободные (незанятые) кластеры помечаются кодом 00; при выделении нового кластера для записи файла берется первый сво­бодный кластер. Возможные значения, которые могут приписываться элементам таблицы FAT, приведены в табл. 6.2.

Таблица 6.2. Значения элементов FAT

Значение Описание

OOOOh Свободный кластер

fffOh-fff6h Зарезервированный кластер

fff7h Плохой кластер

fffSh-ffffh Последний кластер в цепочке

0002h-ffefh Номер следующего кластера в цепочке

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

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

В связи с чрезвычайной важностью таблицы FAT она обычно хранится в двух иден­тичных экземплярах, второй из которых непосредственно следует за первым. Об­новляются копии FAT одновременно, используется же только первый экземпляр. Если он по каким-либо причинам окажется разрушенным, то произойдет обраще­ние ко второму экземпляру. Так, например, утилита проверки и восстановления файловой структуры ScanDisk из ОС Windows 9x при обнаружении несоответствия первичной и резервной копии FAT предлагает восстановить главную таблицу, ис­пользуя данные из копии.

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

Для работы с данными на магнитных дисках в системах DOS, которые имеют файло­вую систему FAT, удобно использовать широко известную утилиту Disk Editor из


170___________________________________________ Глава 6. Файловые системы

комплекта утилит Питера Нортона. У нее много достоинств. Прежде всего, она ком­пактна, легко размещается на системной дискете с MS DOS, снабжена встроенной системой подсказок и необходимой справочной информацией. Используя ее, можно сохранять, модифицировать и восстанавливать загрузочную запись, восстанавливать таблицу FAT в случае ее повреждения, а также выполнять много других операций. Основными недостатками этой программы на сегодняшний день являются ограниче­ния на размеры диска и разделов и отсутствие поддержки работы с такими распрост­раненными файловыми системами, как FAT32 и NTFS. Вместо нее теперь часто ис­пользуют утилиту Partition Magic, однако наилучшей альтернативой этой программе на сегодняшний день можно считать утилиту Администратор дисков от Acronis.

Таблица 6.3. Структура элемента каталога

Размер поля данных, байт Содержание поля

11 Имя файла или каталога

1 Атрибуты файла

1 Резервное поле

3 Время создания

2 Дата создания

2 Дата последнего доступа

2 Зарезервировано

2 Время последней модификации

2 Дата последней модификации

2 Номер начального кластера в FAT

4 Размер файла

Структура загрузочной записи DOS

Сектор, содержащий системный загрузчик DOS, является самым первым на логи­ческом диске С:. Напомним, что на дискете системный загрузчик размещается в са­мом первом секторе; его физический адрес равен 0-0-1. Загрузочная запись состо­ит, как мы уже знаем, из двух частей: блока параметров диска (Disk Parameter Block, DPB) и системного загрузчика (System Bootstrap, SB). Блок параметров диска слу­жит для идентификации физического и логического форматов логического диска, а системный загрузчик играет существенную роль в процессе загрузки DOS. Эта информационная структура приведена в табл. 6.4.

Первые два байта загрузочной записи занимает команда безусловного перехода (JMP) на программу SB. Третий байт содержит код 90Н (NOP - нет операции). Да­лее располагается восьмибайтовый системный идентификатор, включающий ин­формацию о фирме-разработчике и версии операционной системы. Затем следует блок параметров диска, а после него - системный загрузчик.

Для работы с загрузочной записью DOS, как и с другими служебными информа­ционными структурами, удобно использовать уже упомянутую программу Disk


Файловая система FAT________________________________________________ 171

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

Таблица 6.4. Структура загрузочной записи для FAT16

Смещение поля, Длина поля, Обозначение Содержимое поля
байт байт поля

ООН (0) 3 JUMP 3EH Безусловный переход на начало

системного загрузчика

ОЗН (3) 8 Системный идентификатор

ОВН (11) 2 SectSize Размер сектора, байт

ООН (13) 1 ClastSize Число секторов в кластере

0ЕН(14) 2 ResSecs Число зарезервированных секторов

10Н (16) 1 FATcnt Число копий FAT

11Н (17) 2 RootSize Максимальное число элементов Rdir

13Н (19) 2 TotSecs Число секторов на логическом диске,

если его размер не превышает 32 Мбайт; иначе 0000Н

15Н (21) 1 Media Дескриптор носителя

16Н(22) 2 FATsize Размер FAT, секторов

18Н(24) 2 TrkSecs Число секторов на дорожке

1АН(26) 2 HeadCnt Число рабочих поверхностей

1СН(28) 4 HidnSecs Число скрытых секторов

20Н (32) 4 Число секторов на логическом диске,

если его размер превышает 32 Мбайт

24Н (36) 1 Тип логического диска (ООН - гибкий,

80Н - жесткий)

25Н (37) 1 Зарезервировано

26Н (38) 1 Маркер с кодом 29Н

27Н (39) 4 Серийный номер тома 1

2ВН (43) 11 Метка тома

36Н (54) 8 Имя файловой системы

ЗЕН (62) Системный загрузчик

1FEH (510) 2 Сигнатура (слово АА55Н)

1 Том (volume) представляет собой единое логическое адресное пространство. Томом может быть обыч­ный логический диск либо несколько дисковых пространств.

ВЛАДИМИР МЕШКОВ

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

Общая характеристика файловой системы FAT. Структура раздела с файловой системой FAT

Файловая система FAT (File Allocation Table) была разработана Биллом Гейтсом и Марком Макдональдом в 1977 году и первоначально использовалась в операционной системе 86-DOS. Чтобы добиться переносимости программ из операционной системы CP/M в 86-DOS, в ней были сохранены ранее принятые ограничения на имена файлов. В дальнейшем 86-DOS была приобретена Microsoft и стала основой для ОС MS-DOS 1.0, выпущенной в августе 1981 года. FAT была предназначена для работы с гибкими дисками размером менее 1 Мб и вначале не предусматривала поддержки жёстких дисков.

Структура раздела FAT изображена на рисунке.

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

  • загрузочная запись (boot record, BR);
  • резервная область;
  • таблицы размещения файлов;
  • область корневого каталога (не существует в FAT32).

Область данных логического диска содержит файлы и каталоги, подчиненные корневому, и разделена на участки одинакового размера – кластеры. Кластер может состоять из одного или нескольких последовательно расположенных на диске секторов. Число секторов в кластере должно быть кратно 2N и может принимать значения от 1 до 64. Размер кластера зависит от типа используемой файловой системы и объема логического диска.

Назначение, структура и типы таблицы размещения файлов

Своё название FAT получила от одноимённой таблицы размещения файлов – File Allocation Table, FAT. В таблице размещения файлов хранится информация о кластерах логического диска. Каждому кластеру соответствует элемент таблицы FAT, содержащий информацию о том, свободен данный кластер или занят данными файла. Если кластер занят под файл, то в соответствующем элементе таблицы размещения файлов указывается адрес кластера, содержащего следующую часть файла. Номер начального кластера, занятого файлом, хранится в элементе каталога, содержащего запись об этом файле. Последний элемент списка кластеров содержит признак конца файла (EOF – End Of File). Первые два элемента FAT являются резервными.

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

Существуют следующие типы FAT – FAT12, FAT16, FAT32. Названия типов FAT ведут свое происхождение от размера элемента: элемент FAT12 имеет размер 12 бит (1,5 байт), FAT16 – 16 бит (2 байта), FAT32 – 32 бита (4 байта). В FAT32 четыре старших двоичных разряда зарезервированы и игнорируются в процессе работы операционной системы.

Корневой каталог

За таблицами размещения файлов следует корневой каталог. Каждому файлу и подкаталогу в корневом каталоге соответствует 32-байтный элемент каталога (directory entry), содержащий имя файла, его атрибуты (архивный, скрытый, системный и «только для чтения»), дату и время создания (или внесения в него последних изменений), а также прочую информацию. Для файловых систем FAT12 и FAT16 положение корневого каталога на разделе и его размер жестко зафиксированы. В FAT32 корневой каталог может быть расположен в любом месте области данных раздела и иметь произвольный размер.

Форматы имен файлов

Одной из характеристик ранних версий FAT (FAT12 и FAT16) является использование коротких имен файлов. Короткое имя состоит из двух полей – 8-байтного поля, содержащего собственно имя файла, и 3-байтного поля, содержащего расширение (формат «8.3»). Если введенное пользователем имя файла короче 8 символов, то оно дополняется пробелами (код 0x20); если введенное расширение короче трёх байтов, то оно также дополняется пробелами.

Структура элемента каталога для короткого имени файла представлена в таблице 1.

Первый байт короткого имени выполняет функции признака занятости каталога:

  • если первый байт равен 0xE5, то элемент каталога свободен и его можно использовать при создании нового файла;
  • если первый байт равен 0x00, то элемент каталога свободен и является началом чистой области каталога (после него нет ни одного задействованного элемента).

Таблица 1. Структура элемента каталога для короткого имени файла

Смещение

Размер (байт) Содержание
0x00 11 Короткое имя файла
0x0B 1 Атрибуты файла
0x0C 1 Зарезервировано для Windows NT.
0x0D 1 Поле, уточняющее время создания файла (содержит десятки миллисекунд). Поле обрабатывается только в FAT32
0x0E 1 Время создания файла. Поле обрабатывается только в FAT32
0x10 2 Дата создания файла. Поле обрабатывается только в FAT32
0x12 2 Дата последнего обращения к файлу для записи или считывания данных. Поле обрабатывается только в FAT32
0x14 2 Старшее слово номера первого кластера файла. Поле обрабатывается только в FAT32
0x16 2 Время выполнения последней операции записи в файл
0x18 2 Дата выполнения последней операции записи в файл
0x1A 2 Младшее слово номера первого кластера файла
0x1C 4 Размер файла в байтах

На использование ASCII-символов в коротком имени накладывается ряд ограничений:

  • нельзя использовать символы с кодами меньше 0x20 (за исключением кода 0x05 в первом байте короткого имени);
  • нельзя использовать символы с кодами 0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x5B, 0x5C, 0x5D, 0x7C;
  • нельзя использовать символ пробела (0x20) в первом байте имени.

В файловых системах FAT32 и VFAT (виртуальная FAT, расширение FAT16) включена поддержка длинных имен файлов (long file name, LFN). Для хранения длинного имени используются элементы каталога, смежные с основным элементом. Имя файла записывается не ASCII-символами, а в Unicode. В одном элементе каталога можно сохранить фрагмент длиной до 13 символов Unicode. Неиспользованный участок последнего фрагмента заполняется кодами 0xFFFF. Структура элемента каталога для длинного имени файла представлена в таблице 2.

Таблица 2. Структура элемента каталога для длинного имени файла

Смещение Размер (байт) Содержание
0x00 1 Номер фрагмента
0x01 10 Символы 1-5 имени файла в Unicode
0x0B 1 Атрибуты файла
0x0C 1 Байт флагов
0x0D 1 Контрольная сумма короткого имени
0x0E 12 Символы 6-11 имени файла в Unicode
0x1A 2 Номер первого кластера (заполняется нулями)
0x1C 4 Символы 12-13 имени файла в Unicode

Загрузочный сектор

В первом секторе логического диска с системой FAT располагается загрузочный сектор и блок параметров BIOS. Начальный участок данного блока для всех типов FAT идентичен (таблица 3). Различия в структуре загрузочных секторов для разных типов FAT начинаются со смещения 0x24. Для FAT12 и FAT16 структура имеет вид, показанный в таблице 4, для FAT32 – в таблице 5.

Таблица 3. Начальный участок загрузочного сектора

Смещение Размер, байт Описание
0x00 3 Безусловный переход (jmp) на загрузочный код
0x03 8 Идентификатор фирмы-изготовителя
0x0B 2 Число байт в секторе (512)
0x0D 1 Число секторов в кластере
0x0E 2 Число резервных секторов в резервной области раздела, начиная с первого сектора раздела
0x10 1 Число таблиц (копий) FAT
0x11 2 Для FAT12/FAT16 - количество 32-байтных дескрипторов файлов в корневом каталоге; для FAT32 это поле имеет значение 0
0x13 2 Общее число секторов в разделе; если данное поле содержит 0, то число секторов задается полем по смещению 0x20
0x15 1 Тип носителя. Для жесткого диска имеет значение 0xF8; для гибкого диска (2 стороны, 18 секторов на дорожке) – 0xF0
0x16 2 Для FAT12/FAT16 это поле содержит количество секторов, занимаемых одной копией FAT; для FAT32 это поле имеет значение 0
0x18 2 Число секторов на дорожке (для прерывания 0x13)
0x1A 2 Число рабочих поверхностей (для прерывания 0x13)
0x1C 4 Число скрытых секторов перед разделом
0x20 4 Общее число секторов в разделе. Поле используется, если в разделе свыше 65535 секторов, в противном случае поле содержит 0.

Таблица 4. Структура загрузочного сектора FAT12/FAT16

Смещение Размер, байт Описание 0x24 1 Номер дисковода для прерывания 0х13 0x25 1 0x26 1 Признак расширенной загрузочной записи (0x29) 0x27 4 Номер логического диска 0x2B 11 Метка диска 0x36 8 Текстовая строка с аббревиатурой типа файловой системы

Таблица 5. Структура загрузочного сектора FAT32

Размер, байт Описание 4 Количество секторов, занимаемых одной копией FAT 2 Номер активной FAT 2 Номер версии FAT32: старший байт - номер версии, младший – номер ревизии. В настоящее время используется значение 0:0 4 Номер кластера для первого кластера корневого каталога 2 Номер сектора структуры FSINFO в резервной области логического диска 2 Номер сектора(в резервной области логического диска), используемого для хранения резервной копии загрузочного сектора 12 Зарезервировано (содержит 0)

Смещение
0x24
0x28
0x2A
0x2С
0x30
0x32
0x34

Кроме перечисленных в таблицах 2-го и 3-го полей, нулевой сектор логического диска должен содержать в байте со смещением 0x1FE код 0x55, а в следующем байте (смещение 0x1FF) – код 0xAA. Указанные два байта являются признаком загрузочного диска.

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

На логическом диске с организацией FAT32 дополнительно присутствует структура FSInfo, размещаемая в первом секторе резервной области. Эта структура содержит информацию о количестве свободных кластеров на диске и о номере первого свободного кластера в таблице FAT. Формат структуры описан в таблице 6.

Таблица 6. Структура сектора FSInfo и резервного загрузочного сектора FAT32

Размер, байт Описание 4 Значение 0x41615252 – сигнатура, которая служит признаком того, данный сектор содержит структуру FSInfo 480 Зарезервировано (содержит 0) 4 Значение 0x61417272 (сигнатура) 4 Содержит текущее число свободных кластеров на диске. Если в поле записано значение 0xFFFFFFFF, то число свободных кластеров неизвестно, и его необходимо вычислять 4 Содержит номер кластера, с которого дисковый драйвер должен начинать поиск свободных кластеров. Если в поле записано значение 0xFFFFFFFF, то поиск свободных кластеров нужно начинать с кластера номер 2 12 Зарезервировано (содержит 0) 4 Сигнатура 0xAA550000 – признак конца структуры FSInfo

Смещение
0x000
0x004
0x1E4
0x1E8
0x1EC
0x1F0
0x1FC

Для доступа к содержимому файла, находящемуся на разделе с файловой системой FAT, необходимо получить номер первого кластера файла. Этот номер, как мы уже установили, входит в состав элемента каталога, содержащего запись о файле. Номеру первого кластера соответствует элемент таблицы FAT, в котором хранится адрес кластера, содержащего следующую часть файла. Элемент FAT, соответствующий последнему кластеру в цепочке, содержит сигнатуру конца файла. Для FAT12 это значение составляет 0xFFF, для FAT16 – 0xFFFF, для FAT32 – 0xFFFFFFFF.

Рассмотрим программную реализацию алгоритма чтения для каждого типа FAT, и начнём с FAT16.

Все исходные тексты, рассматриваемые в статье, доступны на сайте журнала.

Программная реализация алгоритма чтения файла с логического раздела с файловой системой FAT16

Разработаем модуль, выполняющий чтение N первых кластеров файла, созданного на разделе с файловой системой FAT16. Параметр N (число кластеров для считывания) является переменной величиной и задается пользователем. Имя файла соответствует формату «8.3», т.е. является коротким. Модуль функционирует под управлением ОС Linux.

Определим необходимые заголовочные файлы:

#include

#include

#include

#include

#include

#include "split.h"

Заголовочный файл split.h имеет следующее содержание:

#include

#define SHORT_NAME 13 // максимальная длина короткого имени файла

struct split_name {

U8 name; // имя файла

U8 ext; // расширение файла

Int name_len, // длина имени файла

Ext_len; // длина расширения файла

Cтруктура split_name предназначена для хранения составных частей короткого имени файла (имени и расширения) и их длин.

В заголовочном файле определены структурные типы, описывающие основные компоненты файловой системы FAT – загрузочный сектор, сектор FSInfo, структуры элементов каталога для короткого и длинного имён файлов.

Рассмотрим кратко поля, которые входят в каждую из этих структур.

    1. Структура загрузочного сектора struct fat_boot_sector:
      • __s8 system_id – системный идентификатор;
      • __u8 sector_size – размер сектора в байтах;
      • __u8 cluster_size – размер кластера в секторах;
      • __u16 reserved – число резервных секторов в резервной области раздела;
      • __u8 fats – количество копий FAT;
      • __u8 dir_entries – количество 32-байтных дескрипторов файлов в корневом каталоге;
      • __u8 sectors – число секторов на разделе; если это поле равно 0, используется поле total_sect;
      • __u8 media – тип носителя, на котором создана файловая система;
      • __u16 fat_length – размер FAT в секторах;
      • __u32 total_sect – размер раздела FAT в секторах (если поле sectors == 0).
      • __u32 fat32_length – размер FAT32 в секторах;
      • __u32 root_cluster – номер первого кластера корневого каталога;
      • __u16 info_sector – номер сектора, содержащего структуру FSInfo.

Следующие поля данной структуры используются только FAT32:

  1. Структура сектора FSInfo struct fat_boot_fsinfo:
    • __u32 signature1 – сигнатура 0x41615252;
    • __u32 signature2 – сигнатура 0x61417272;
    • __u32 free_clusters – количество свободных кластеров. Если поле содержит -1, поиск свободных кластеров нужно начинать с кластера номер 2.
  2. Структура элемента каталога короткого имени struct msdos_dir_entry:
    • __s8 name,ext – имя и расширение файла;
    • __u8 attr – атрибуты файла;
    • __u8 ctime_ms – это поле уточняет время создания файла до мс (используется только FAT32);
    • __u16 ctime – время создания файла (используется только FAT32);
    • __u16 cdate – дата создания файла (используется только FAT32);
    • __u16 adate – дата последнего доступа к файлу (используется только FAT32);
    • __u16 starthi – старшие 16 бит номера первого кластера файла (используется только FAT32);
    • __u16 time,date,start – время и дата создания файла, номер первого кластер файла;
    • __u32 size – размер файла (в байтах).
  3. Структура элемента каталога длинного имени:
    • __u8 id – номер элемента;
    • __u8 name0_4 – символы 1 – 5 имени;
    • __u8 attr – атрибуты файла;
    • __u8 alias_checksum – контрольная сумма короткого имени;
    • __u8 name5_10 – символы 6 – 11 имени;
    • __u8 name11_12 – символы 12 – 13 имени.

Продолжим рассмотрение программной реализации алгоритма и определим имя раздела, на котором создана файловая система FAT16:

#ifndef FAT16_PART_NAME

#define FAT16_PART_NAME "/dev/hda1"

#endif

Глобальные структуры:

struct fat_boot_sector fbs; // структура загрузочного сектора

struct msdos_dir_entry dentry; // структура элемента каталога

Глобальные переменные:

U16 *fat16; // сюда копируем таблицу FAT16

U16 sector_size; // размер сектора (из FAT16)

U16 dir_entries; // число 32-байтных дескрипторов

// в root-каталоге (0 для FAT32)

U16 sectors; // общее число секторов в разделе

U32 fat16_size; // размер FAT16

U32 root_size; // размер корневого каталога

U16 byte_per_cluster; // размер кластера в байтах

U16 next_cluster; // очередной кластер в цепочке

int fat;

Начнём рассмотрение с главной функции:

int main()

Int num;

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

U8 *full_path = "/Folder1/Folder2/text.txt";

Открываем файл устройства:

Hard = open(FAT16_PART_NAME, O_RDONLY);

If(hard < 0) {

Perror(FAT16_PART_NAME);

Exit(-1);

Считываем первые 10 кластеров файла. Считывание выполняет функция fat16_read_file(). Параметры функции – полное имя файла и число кластеров для чтения. Функция возвращает число прочитанных кластеров или -1, если при чтении произошла ошибка:

Num = fat16_read_file(full_path, 10);

If(num < 0) perror("fat16_read_file");

Else printf("Read %d clusters ", num);

Закрываем файл устройства и выходим:

Close(hard);

Return 0;

Функция чтения кластеров файла имеет следующий вид:

int fat16_read_file(__u8 *full_path, int num)

Struct split_name sn; // структура для хранения составных частей файла

U8 tmp_name_buff; // буфер для временного хранения составных элементов полного пути файла

Static int i = 1;

Int n;

U8 *tmp_buff;

U16 start_cluster, next_cluster;

Параметры функции мы перечислили при рассмотрении функции main.

Подготовительные операции – обнуляем буфер tmp_name_buff и структуру struct split_name sn:

Первым символом в абсолютном путевом имени файла должен быть прямой слэш (/). Проверяем это:

Считываем с раздела загрузочный сектор:

If(read_fbs() < 0) return -1;

Считанный загрузочный сектор находится сейчас в глобальной структуре struct fat_boot_sector fbs. Скопируем из этой структуры размер сектора, число записей в корневом каталоге и общее число секторов на разделе:

Определим размер кластера в байтах:

Byte_per_cluster = fbs.cluster_size * 512

Отобразим информацию, находящуюся в загрузочном секторе:

Printf("System id - %s ", fbs.system_id);

Printf("Sector size - %d ", sector_size);

Printf("Cluster size - %d ", fbs.cluster_size);

Printf("Reserved - %d ", fbs.reserved);

Printf("FATs number - %d ",fbs.fats);

Printf("Dir entries - %d ", dir_entries);

Printf("Sectors - %d ", sectors);

Printf("Media - 0x%X ", fbs.media);

Printf("FAT16 length - %u ", fbs.fat_length);

Printf("Total sect - %u ", fbs.total_sect);

Printf("Byte per cluster - %d ", byte_per_cluster);

Вычисляем размер FAT16 в байтах и считываем её:

Fat16_size = fbs.fat_length * 512;

If(read_fat16() < 0) return -1;

Считываем корневой каталог:

If(read_root_dentry() < 0) return -1;

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

Сохраним (для контроля) содержимое корневого каталога в отдельном файле:

#ifdef DEBUG

Close(fat);

#endif

Вычисляем начало области данных:

Data_start = 512 * fbs.reserved + fat16_size * fbs.fats + root_size;

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

While(1) {

Memset(tmp_name_buff, 0, SHORT_NAME);

Memset((void *)&sn, 0, sizeof(struct split_name));

For(n = 0 ; n < SHORT_NAME; n++, i++) {

If((tmp_name_buff[n] == "/") || (tmp_name_buff[n] == "?")) {

I++;

Break;

Tmp_name_buff[n] = "?";

Заполняем структуру struct split_name sn соответствующей информацией. Заполнение выполняет функция split_name, при этом выполняется проверка имени файла на соответствие формату «8.3»:

< 0) {

Printf("not valid name ");

Return -1;

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

If(get_dentry(&sn) < 0) {

Printf("No such file! ");

Return -1;

Проверяем атрибуты файла. Если это каталог, считываем его содержимое и продолжаем цикл:

If(dentry.attr & 0x10) {

If(read_directory(dentry.start) < 0) return -1;

Continue;

Если это файл – считываем первые num кластеров. Для контроля считанную информацию сохраним в отдельном файле:

If(dentry.attr & 0x20) {

Start_cluster = dentry.start;

Tmp_buff = (__u8 *)malloc(byte_per_cluster); // сюда будет считываться содержимое кластера

N = open("clust", O_CREAT|O_RDWR, 0600); // в этом файле сохраним считанную информацию

If(n < 0) {

Perror("open");

Return -1;

Для считывания кластеров файла организуем цикл:

For(i = 0; i < num; i++) {

Считываем содержимое кластера в буфер tmp_buff и сохраняем его в отдельном файле:

< 0) return -1;

< 0) {

Perror("write");

Close(n);

Return -1;

Считываем из FAT16 номер следующего кластера, занятого под данный файл. Если это последний кластер – прерываем цикл и возвращаемся в главную функцию:

#ifdef DEBUG

Printf("OK. Readed ");

Printf("file`s next cluster - 0x%X .. ", next_cluster);

#endif

If(next_cluster == EOF_FAT16) {

#ifdef DEBUG

Printf("last cluster. ");

#endif

Free(tmp_buff);

Close(n);

Return ++i;

#ifdef DEBUG

Printf("stop reading ");

#endif

Return i;

Чтение загрузочного сектора FAT16 выполняет функция read_fbs(). Результат помещается в глобальную структуру fbs:

int read_fbs()

If(read(hard,(__u8 *)&fbs, sizeof(fbs)) < 0) return -1;

Return 0;

Чтение таблицы размещения файлов файловой системы FAT16 выполняет функция read_fat16():

int read_fat16()

U64 seek = (__u64)(fbs.reserved) * 512; // смещение к FAT16 от начала раздела

Fat16 = (void *)malloc(fat16_size);

If(pread64(hard, (__u8 *)fat16, fat16_size, seek) < 0) return -1;

Return 0;

Чтение корневого каталога выполняет функция read_root_dentry():

int read_root_dentry()

U64 seek = (__u64)fbs.reserved * 512 + fat16_size * fbs.fats; // смещение к корневому каталогу от начала раздела

Root_size = 32 * dir_entries; // вычисляем размер корневого каталога

Dir_entry = (__u8 *)malloc(root_size);

If(!dir_entry) return -1;

Memset(dir_entry, 0, root_size);

If(pread64(hard, dir_entry, root_size, seek) < 0) return -1;

Return 0;

Чтение кластера, принадлежащего файлу, выполняет функция read_cluster(). Входные параметры функции – номер кластера cluster_num и указатель на буфер __u8 *tmp_buff, куда нужно поместить результат чтения. Смещение к кластеру на разделе вычисляется по формуле (см. ):

SEEK = DATA_START + (CLUSTER_NUM - 2) * BYTE_PER_CLUSTER,

  • SEEK – смещение к кластеру на разделе
  • DATA_START – начало области данных
  • CLUSTER_NUM – порядковый номер кластера
  • BYTE_PER_CLUSTER – размер кластера в байтах

int read_cluster(__u16 cluster_num, __u8 *tmp_buff)

U64 seek = (__u64)(byte_per_cluster) * (cluster_num - 2) + data_start; // вычисляем смещение к кластеру

< 0) return -1;

Return 0;

Функция read_directory выполняет чтение записей каталога (не корневого) и помещает результат в область памяти, на которую настроен указатель dir_entry:

int read_directory(__u16 start_cluster)

Int i = 1;

U16 next_cluster;

For(; ;i++) {

Выделяем память для хранения содержимого каталога, считываем содержимое стартового кластера и получаем из таблицы FAT16 значение очередного кластера:

If(!dir_entry) return -1;

< 0) return -1;

Next_cluster = fat16;

Сохраним содержимое каталога в отдельном файле (для контроля):

#ifdef DEBUG

Printf("Next cluster - 0x%X ", next_cluster);

Fat = open("dir16", O_CREAT|O_WRONLY, 0600);

Write(fat, dir_entry, root_size);

Close(fat);

#endif

Если достигнут последний кластер, выходим из цикла, иначе продолжаем чтение каталога, увеличив размер буфера dir_entry ещё на один кластер:

If(next_cluster & EOF_FAT16) break;

Start_cluster = next_cluster;

Return 0;

Поиск в содержимом каталога элемента, соответствующего искомому файлу, выполняет функция get_dentry(). Входные параметры этой функции – указатель на структуру struct split_name *sn, содержащую элементы короткого имени файла:

Int i = 0;

В глобальном буфере dir_entry находится массив элементов каталога, в котором мы собираемся искать запись файла (или каталога). Для поиска организуем цикл. В теле цикла производим копирование элементов каталога в глобальную структуру dentry и сравниваем значение полей name и ext этой структуры с соответствующими полями структуры struct split_name *sn. Совпадение этих полей означает, что мы нашли в массиве элементов каталога запись искомого файла:

for(; ; i++) {

If(!(memcmp(dentry.name, sn->name, sn->name_len)) &&

!(memcmp(dentry.ext, sn->ext, sn->ext_len)))

Break;

If(!dentry.name) return -1;

#ifdef DEBUG

Printf("name - %s ", dentry.name);

Printf("start cluster - 0x%X ", dentry.start);

Printf("file size - %u ", dentry.size);

Printf("file attrib - 0x%X ", dentry.attr);

#endif

Return 0;

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

INCDIR = /usr/src/linux/include

PHONY = clean

Fat16: fat16.o split.o

Gcc -I$(INCDIR) $^ -g -o $@

%.o: %.c

Gcc -I$(INCDIR) -DDEBUG -c $^

Clean:

Rm -f *.o

Rm -f ./fat16

Программная реализация алгоритма чтения файла с логического раздела с файловой системой FAT12

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

  • умножить номер элемента на 1.5;
  • извлечь из FAT 16-разрядное слово, используя в качестве смещения результат предыдущей операции;
  • если номер элемента четный, выполнить операцию AND над считанным словом и маской 0x0FFF. Если номер нечетный, сдвинуть считанное из таблицы слово на 4 бита в сторону младших разрядов.

Базируясь на этом алгоритме, реализуем функцию чтения элементов из таблицы FAT12:

int get_cluster(__u16 cluster_num)

U16 seek;

U16 clust;

Вычисляем смещение в таблице FAT12 и считываем из таблицы 16-разрядное слово:

Seek = (cluster_num * 3) / 2;

Memcpy((__u8 *)&clust, (__u8 *)(fat12 + seek), 2);

Если стартовый номер кластера – четное число, сдвигаем считанное из таблицы значение на 4 бита в сторону младших разрядов, если нечетное – суммируем его с 0x0FFF:

If(cluster_num % 2) clust >>= 4;

Else clust &= 0x0FFF;

Этот фрагмент можно также реализовать на ассемблере:

" xorw %%ax, %%ax "

" btw $0, %%cx "

" jnc 1f "

" shrw $4, %%dx "

" jmp 2f "

"1: andw $0x0FFF, %%dx "

"2: movw %%dx, %%ax "

:"=a" (next)

:"d" (clust), "c" (cluster_num));

Возвращаем результат:

Return clust;

Остановимся чуть подробнее на самом алгоритме. Предположим, что на разделе с FAT12 создан файл, который занимает 9-й и 10-й кластеры. Каждый элемент FAT12 занимает 12 бит. Т.к. из таблицы мы считываем 16-разрядные элементы, то смещение к 9-му элементу будет равно 13 байт (9 * 1.5 = 13, остаток отбрасываем), при этом младшие 4 разряда будут принадлежать 8-му элементу FAT. Их необходимо отбросить, а для этого достаточно сдвинуть считанный элемент на 4 бита в сторону младших разрядов, что и предусмотрено алгоритмом. Смещение к 10-му элементу будет равно 15 байт, и старшие 4 бита будут принадлежать 11-му элементу FAT. Чтобы их отбросить, необходимо выполнить операцию AND над 10-м элементом и маской 0x0FFF, что так же соответствует вышеприведенному алгоритму.

Исходные тексты модуля чтения файла с раздела FAT12 находятся в каталоге FAT12, файл fat12.c.

Программная реализация алгоритма чтения файла с логического раздела с файловой системой FAT32

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

Логическая структура жесткого диска

Рассмотрим логическую структуру жесткого диска, соответствующую стандарту Microsoft – «основной раздел – расширенный раздел – разделы non-DOS».

Пространство на жестком диске может быть организовано в виде одного или нескольких разделов, а разделы могут содержать один или несколько логических дисков.

На жестком диске по физическому адресу 0-0-1 располагается главная загрузочная запись (Master Boot Record, MBR). В структуре MBR находятся следующие элементы:

  • внесистемный загрузчик (non-system bootstrap – NSB);
  • таблица описания разделов диска (таблица разделов, partition table, PT). Располагается в MBR по смещению 0x1BE и занимает 64 байта;
  • сигнатура MBR. Последние два байта MBR должны содержать число 0xAA55.

Таблица разделов описывает размещение и характеристики имеющихся на винчестере разделов. Разделы диска могут быть двух типов – primary (первичный, основной) и extended (расширенный). Максимальное число primary-разделов равно четырем. Наличие на диске хотя бы одного primary-раздела является обязательным. Extended-раздел может быть разделен на большое количество подразделов – логических дисков. Упрощенно структура MBR представлена в таблице 7. Таблица разделов располагается в конце MBR, для описания раздела в таблице отводится 16 байт.

Таблица 7. Структура MBR

Смещение Размер, байт 0 446 0x1BE 16 0x1CE 16 0x1DE 16 0x1EE 16 0x1FE 2

Структура записи элемента таблицы разделов показана в таблице 8.

Таблица 8. Структура записи элемента таблицы разделов

Смещение Размер, байт Содержание
0x00 1 Признак активности (0 - раздел не активный, 0x80 – раздел активный)
0x01 1 Номер головки диска, с которой начинается раздел
0x02 2 Номер цилиндра и номер сектора, с которых начинается раздел
0x04 1 Код типа раздела System ID
0x05 1 Номер головки диска, на которой заканчивается раздел
0x06 2 Номер цилиндра и номер сектора, которыми заканчивается раздел
0x08 4 Абсолютный (логический) номер начального сектора раздела
0x0C 4 Размер раздела (число секторов)

Первым байтом в элементе раздела идет флаг активности раздела (0 – неактивен, 0x80 – активен). Он служит для определения, является ли раздел системным загрузочным и есть ли необходимость производить загрузку операционной системы с него при старте компьютера. Активным может быть только один раздел. За флагом активности раздела следуют координаты начала раздела – три байта, означающие номер головки, номер сектора и номер цилиндра. Номера цилиндра и сектора задаются в формате прерывания Int 0x13, т.е. биты 0-5 содержат номер сектора, биты 6-7 – старшие два бита 10-разрядного номера цилиндра, биты 8-15 – младшие восемь бит номера цилиндра. Затем следует кодовый идентификатор System ID, указывающий на принадлежность данного раздела к той или иной операционной системе. Идентификатор занимает один байт. За системным идентификатором расположены координаты конца раздела – три байта, содержащие номера головки, сектора и цилиндра соответственно. Следующие четыре байта – это число секторов перед разделом, и последние четыре байта – размер раздела в секторах.

Таким образом, элемент таблицы раздела можно описать при помощи следующей структуры:

struct pt_struct {

U8 bootable; // флаг активности раздела

U8 start_part; // координаты начала раздела

U8 type_part; // системный идентификатор

U8 end_part; // координаты конца раздела

U32 sect_before; // число секторов перед разделом

U32 sect_total; // размер раздела в секторах (число секторов в разделе)

Элемент первичного раздела указывает сразу на загрузочный сектор логического диска (в первичном разделе всегда имеется только один логический диск), а элемент расширенного раздела – на список логических дисков, составленный из структур, которые именуются вторичными MBR (Secondary MBR, SMBR).

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

Вернемся к рассмотрению модуля чтения файла с раздела FAT32.

Заголовочные файлы:

#include

#include

#include

#include

#include

Сигнатура MBR:

#define SIGNATURE 0xAA55

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

#define DEVICE "/dev/hda"

Размер элемента таблицы разделов (16 байт):

#define PT_SIZE 0x10

Следующий массив структур устанавливает соответствие между кодом типа раздела и его символьным отображением:

struct systypes {

U8 part_type;

U8 *part_name;

struct systypes i386_sys_types = {

{0x00, "Empty"},

{0x01, "FAT12"},

{0x04, "FAT16 <32M"},

{0x05, "Extended"},

{0x06, "FAT16"},

{0x0b, "Win95 FAT32"},

{0x0c, "Win95 FAT32 (LBA)"},

{0x0e, "Win95 FAT16 (LBA)"},

{0x0f, "Win95 Ext"d (LBA)"},

{0x82, "Linux swap"},

{0x83, "Linux"},

{0x85, "Linux extended"},

{0x07, "HPFS/NTFS"}

Определим число элементов в массиве i386_sys_types при помощи макроса PART_NUM:

#define PART_NUM (sizeof(i386_sys_types) / sizeof(i386_sys_types))

Установим ограничение на количество логических дисков:

#define MAX_PART 20

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

struct pt_struct {

U8 bootable;

U8 start_part;

U8 type_part;

U8 end_part;

U32 sect_before;

U32 sect_total;

} pt_t;

int hard; // дескриптор файла устройства

U8 mbr; // сюда считаем MBR

Номер раздела, на котором создана файловая система FAT32:

#define FAT32_PART_NUM 5

Структуры загрузочного сектора, сектора FSInfo и элемента каталога (определены в файле ):

struct fat_boot_sector fbs;

struct fat_boot_fsinfo fsinfo;

struct msdos_dir_entry dentry;

U32 *fat32 = NULL; // сюда копируем таблицу FAT32

U16 sector_size; // размер сектора (из FAT32)

U16 dir_entries; // 0 для FAT32

U16 sectors; // число секторов на разделе

U32 fat32_size; // размер FAT32

U32 data_start; // начало области данных

U16 byte_per_cluster; // сколько байт в кластере (размер кластера в байтах)

U32 next_cluster; // очередной кластер в цепочке

U32 root_cluster; // ROOT cluster - начальный кластер корневого каталога

U8 *dir_entry = NULL; // указатель на записи каталога

U64 start_seek = 0; // стартовое смещение к разделу (в байтах)

Главная функция:

int main()

Int num = 0;

Int cluster_num = 5; // сколько кластеров считывать из файла

U8 *full_path = "/Folder1/Folder2/readme"; // файл для считывания

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

Hard = open(DEV_NAME, O_RDONLY);

If(hard < 0) {

Perror(DEV_NAME);

Exit(-1);

If(get_pt_info(hard) < 0) {

Perror("get_pt_info");

Exit(-1);

Show_pt_info();

Вычисляем стартовое смещение к разделу:

Start_seek = (__u64)(pt_t.sect_before) * 512;

Считываем кластеры, принадлежащие файлу:

Num = fat32_read_file(full_path, cluster_num);

If(num < 0) perror("fat32_read_file");

Else printf("Read %d clusters\n", num);

Close(hard);

Return 0;

Информацию о таблице разделов считывает функция get_pt_info():

int get_pt_info(int hard)

Int i = 0;

U64 seek;

Считываем таблицу разделов из MBR и проверяем сигнатуру:

Read_main_ptable(hard);

If(check_sign() < 0) {

Printf("Not valid signature!\n");

Return -1;

Ищем идентификатор расширенного раздела. Если таковой имеется, вычисляем смещение к расширенному разделу и считываем информацию о логических дисках:

for(; i < 4; i++) {

If((pt_t[i].type_part == 0xF) || \

(pt_t[i].type_part == 0x5) || \

(pt_t[i].type_part == 0x0C)) {

Seek = (__u64)pt_t[i].sect_before * 512;

Read_ext_ptable(hard, seek);

Break;

Return 0;

Функция чтения таблицы разделов read_main_ptable():

void read_main_ptable(int hard)

If(read(hard, mbr, 512) < 0) {

Perror("read");

Close(hard);

Exit(-1);

Memset((void *)pt_t, 0, (PT_SIZE * 4));

Memcpy((void *)pt_t, mbr + 0x1BE, (PT_SIZE * 4));

Return;

Функция проверки сигнатуры check_sign():

int check_sign()

U16 sign = 0;

Memcpy((void *)&sign, (void *)(mbr + 0x1FE), 2);

#ifdef DEBUG

Printf("Signature - 0x%X\n", sign);

#endif

If(sign != SIGNATURE) return -1;

Return 0;

Функция чтения расширенной таблицы разделов:

void read_ext_ptable(int hard, __u64 seek)

Int num = 4; // начиная с этой позиции, массив структур pt_t будет заполняться информацией о логических дисках

U8 smbr;

Входные данные:

  • hard – дескриптор файла устройства;
  • seek – смещение к расширенному разделу от начала диска (в байтах).

Для получения информации о логических дисках организуем цикл:

For(;;num++) {

Считываем SMBR, находящуюся по смещению seek от начала диска:

Memset((void *)smbr, 0, 512);

Pread64(hard, smbr, 512, seek);

Заполняем два элемента таблицы pt_t, начиная с позиции num. Первый элемент будет указывать на логический диск, а второй – на следующую структуру SMBR:

Memset((void *)&pt_t, 0, PT_SIZE * 2);

Memcpy((void *)&pt_t, smbr + 0x1BE, PT_SIZE * 2);

Вносим поправку в поле «Номер начального сектора» – отсчет ведется от начала диска:

Pt_t.sect_before += (seek / 512);

Если код типа раздела равен нулю, то больше логических дисков нет:

If(!(pt_t.type_part)) break;

Вычисляем смещение к следующему SMBR:

Seek = ((__u64)(pt_t.sect_before + pt_t.sect_total)) * 512;

Return;

Функция show_pt_info() отображает информацию о найденных логических дисках на устройстве:

void show_pt_info()

Int i = 0, n;

#ifdef DEBUG

Printf("Число разделов на диске - %d\n", PART_NUM);

#endif

For(; i < MAX_PART; i++) {

If(!pt_t[i].type_part) break;

Printf("\nТип раздела %d - ", i);

For(n = 0; n < PART_NUM; n++) {

If(pt_t[i].type_part == i386_sys_types[n].part_type) {

Printf("%s\n", i386_sys_types[n].part_name);

Break;

If(n == PART_NUM) printf("unknown type\n");

Printf("Признак загрузки - 0x%X\n", pt_t[i].bootable);

Printf("Секторов в разделе %d - %d\n", i, pt_t[i].sect_total);

Printf("Секторов перед разделом %d - %d\n\n", i, pt_t[i].sect_before);

Return;

Чтение кластеров файла с раздела FAT32 выполняет функция fat32_read_file(). Эта функция имеет много общего с функцией fat16_read_file(), поэтому за подробными комментариями обратитесь к п. 6:

int fat32_read_file(__u8 *full_path, int num)

Struct split_name sn;

U8 tmp_name_buff;

Int i = 1, n;

U32 start_cluster, next_cluster;

U8 *tmp_buff;

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

Memset(tmp_name_buff, 0, SHORT_NAME);

Memset((void *)&sn, 0, sizeof(struct split_name));

If(full_path != "/") return -1;

Считываем загрузочный сектор:

If(read_fbs() < 0) return -1;

Memcpy((void *)§or_size, (void *)fbs.sector_size, 2);

Memcpy((void *)&dir_entries, (void *)fbs.dir_entries, 2);

Memcpy((void *)§ors, (void *)fbs.sectors, 2);

Считываем структуру FSInfo и отобразим сигнатуру, находящуюся в ней:

If(read_fs_info() < 0) return -1;

Printf("Signature1 - 0x%X\n", fsinfo.signature1);

Printf("Signature2 - 0x%X\n", fsinfo.signature2);

Fat32_size = fbs.fat32_length * 512; // размер FAT32 в байтах

Data_start = 512 * fbs.reserved + fat32_size * 2; // начало поля данных

Byte_per_cluster = fbs.cluster_size * 512; // размер кластера в байтах

Root_cluster = fbs.root_cluster; // номер кластера корневого каталога

Считываем FAT32:

If(read_fat32() < 0) return -1;

Выделяем память для записей каталога:

Dir_entry = (__u8 *)malloc(byte_per_cluster);

If(!dir_entry) return -1;

Считываем корневой каталог:

If(read_directory(root_cluster) < 0) return -1;

Проводим разбор полного пути файла и разделение каждого элемента на составляющие:

While(1) {

Memset(tmp_name_buff, 0, SHORT_NAME);

Memset((void *)&sn, 0, sizeof(struct split_name));

For(n = 0 ; n < SHORT_NAME; n++, i++) {

Tmp_name_buff[n] = full_path[i];

If((tmp_name_buff[n] == "/") || (tmp_name_buff[n] == "\0")) {

I++;

Break;

Tmp_name_buff[n] = "\0";

If(split_name(tmp_name_buff, &sn) < 0) {

Printf("not valid name\n");

Return -1;

If(get_dentry(&sn) < 0) {

Printf("No such file!\n");

Return -1;

Для получения стартового номера кластера в файловой системе FAT32 необходимо задействовать старшее слово номера первого кластера файла – поле starthi структуры dentry:

Start_cluster = (((__u32)dentry.starthi << 16) | dentry.start);

Проверяем байт атрибутов:

If(dentry.attr & 0x10) { // это каталог

If(read_directory(start_cluster) < 0) return -1;

Continue;

If(dentry.attr & 0x20) { // а это - файл

Tmp_buff = (__u8 *)malloc(byte_per_cluster);

N = open("clust", O_CREAT|O_RDWR, 0600);

If(n < 0) {

Perror("open");

Return -1;

Printf("file`s first cluster - 0x%X .. ", start_cluster);

For(i = 0; i < num; i++) {

Memset(tmp_buff, 0, byte_per_cluster);

If(read_cluster(start_cluster, tmp_buff) < 0) return -1;

If(write(n, tmp_buff, byte_per_cluster) < 0) {

Perror("write");

Return -1;

If(next_cluster == EOF_FAT32) {

Free(tmp_buff);

Close(n);

Return ++i;

Start_cluster = next_cluster;

Return i;

Назначение следующих трёх функций – получить содержимое системной области, т.е. загрузочного сектора, структуры FSInfo и таблицы FAT32:

1) функция read_fbs() выполняет чтение загрузочного сектора:

int read_fbs()

If(pread64(hard, (__u8 *)&fbs, sizeof(fbs), start_seek) < 0) return -1;

Return 0;

2) функция read_fs_info() считывает структуру FSInfo:

int read_fs_info()

U64 seek = (__u64)fbs.info_sector * 512 + start_seek;

If(pread64(hard, (__u8 *)&fsinfo, sizeof(fsinfo), seek) < 0) return -1;

Return 0;

3) функция read_fat32() считывает таблицу FAT32:

int read_fat32()

U64 seek = (__u64)fbs.reserved * 512 + start_seek;

Fat32 = (void *)malloc(fat32_size);

If(!fat32) return -1;

If(pread64(hard, (__u8 *)fat32, fat32_size, seek) < 0) return -1;

Return 0;

Функция read_cluster() выполняет чтения кластера с указанным номером:

int read_cluster(__u32 cluster_num, __u8 *tmp_buff)

U64 seek = (__u64)(byte_per_cluster) * (cluster_num - 2) + data_start + start_seek;

If(pread64(hard, tmp_buff, byte_per_cluster, seek) < 0) return -1;

Return 0;

Чтением каталогов (в том числе и корневого) занимается функция read_directory():

int read_directory(__u32 start_cluster)

Int i = 2;

U32 next_cluster;

Параметры функции – стартовый кластер каталога. Считываем содержимое каталога в глобальный буфер dir_entry:

If(read_cluster(start_cluster, dir_entry) < 0) return -1;

Next_cluster = fat32;

Если каталог занимает один кластер – выходим, если нет – увеличиваем размер памяти и продолжаем чтение:

For(; ;i++) {

Start_cluster = next_cluster;

Dir_entry = (__u8 *)realloc(dir_entry, i * byte_per_cluster);

If(!dir_entry) return -1;

If(read_cluster(start_cluster, (dir_entry + (i - 1) * byte_per_cluster)) < 0) return -1;

Next_cluster = fat32;

If((next_cluster == EOF_FAT32) || (next_cluster == 0xFFFFFF8)) return 0;

Return 0;

Последняя функция, которую мы рассмотрим, ищет в содержимом каталога элемент, соответствующий искомому файлу:

int get_dentry(struct split_name *sn)

Int i = 0;

Указатель dir_entry настроен на область памяти, содержащую массив записей каталога, в котором мы собираемся искать файл (или каталог). Для поиска организуем цикл и найденную запись поместим в глобальную структуру dentry:

For(;;i++) {

Memcpy((void *)&dentry, dir_entry + i * sizeof(dentry), sizeof(dentry));

If(!(memcmp(dentry.name, sn->name, sn->name_len)) &&

!(memcmp(dentry.ext, sn->ext, sn->ext_len)))

Break;

If(!dentry.name) return -1;

Return 0;

На этом рассмотрение модуля чтения файла с раздела FAT32 завершим.

Исходные тексты модуля находятся в каталоге FAT32, файл fat32.c.

Отличия в организации хранения записей о файлах в каталогах для файловых систем FAT и EXT2

Несколько слов об отличиях в организации хранения записей о файлах в каталогах для файловых систем FAT и EXT2. Структура файловой системы EXT2 была рассмотрена в .

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

Рассмотрим, как обстоят дела в EXT2.

Предположим, у нас есть раздел с файловой системой EXT2, размер блока равен 4096 байт. На этом разделе мы создаем каталог. Размер каталога будет равен размеру блока – 4096 байт. В каталоге операционная система сразу создаёт две записи – запись текущего и запись родительского каталогов. Запись текущего каталога займет 12 байт, в то время как длина записи родительского будет равна 4084 байта. Создадим в этом каталоге какой-нибудь файл. После этого в каталоге будут присутствовать три записи – запись текущего каталога длиной 12 байт, запись родительского каталога длиной уже 12 байт, и запись созданного файла длиной, как вы наверно догадались, 4072 байт. Если мы удалим созданный файл, длина записи родительского каталога опять возрастёт до 4084 байт.

Таким образом, при создании файла драйвер файловой системы EXT2 ищет в каталоге запись максимальной длины и расщепляет её, выделяя место для новой записи. Ну, а если всё-таки места не хватает, под каталог отводится ещё один блок, и длина каталога становится равной 8192 байт.

И в заключение – небольшая правка к статье «Архитектура файловой системы EXT2» .

Эта правка касается функции определения номера inode по имени файла get_i_num(). Старый вариант этой функции выглядел так:

int get_i_num(char *name)

Int i = 0, rec_len = 0;

Struct ext2_dir_entry_2 dent;

For(; i < 700; i++) {

If(!memcmp(dent.name, name, dent.name_len)) break;

Rec_len += dent.rec_len;

Return dent.inode;

Исправленный вариант:

int get_i_num(char *name)

* Параметр функции - имя файла. Возвращаемое значение - номер inode файла.

Int rec_len = 0;

Struct ext2_dir_entry_2 dent; // эта структура описывает формат записи корневого каталога:

* В глобальном буфере buff находится массив записей каталога. Для определения порядкового номера inode файла необходимо найти

* в этом массиве запись с именем этого файла. Для этого организуем цикл:

For(;;) {

/* Копируем в структуру dent записи каталога: */

Memcpy((void *)&dent, (buff + rec_len), sizeof(dent));

* Длина имени файла равная нулю означает, что мы перебрали все записи каталога

* и записи с именем нашего файла не нашли. Значит, пора возвращаться:

If(!dent.name_len) return -1;

/* Поиск выполняется путем сравнения имен файлов. Если имена совпадают - выходим из цикла: */

If(!memcmp(dent.name, name, strlen(name))) break;

/* Если имена не совпали - смещаемся к следующей записи: */

Rec_len += dent.rec_len;

/* В случае успеха возвращаем номер inode файла: */

Return dent.inode;

Литература:

  1. В.Кулаков. Программирование на аппаратном уровне: специальный справочник. 2-е изд. / – СПб.: Питер, 2003 г. – 848 с.
  2. А.В.Гордеев, А.Ю.Молчанов. Системное программное обеспечение / – СПб.: Питер – 2002 г.
  3. Мешков В. Архитектура файловой системы ext2. – Журнал «Системный администратор», № 11(12), ноябрь 2003 г. – 26-32 с.

Вконтакте

Материал к обзорной лекции № 33

для студентов специальности

«Программное обеспечение информационных технологий»

доцента кафедры ИВТ, к.т.н. Ливак Е.Н.

СИСТЕМЫ УПРАВЛЕНИЯ ФАЙЛАМИ

Основные понятия, факты

Назначение. Особенности файловыхсистем FAT , VFAT , FAT 32, HPFS , NTFS . Файловые системы ОС UNIX (s5, ufs), ОС Linux Ext2FS.Системные области диска (раздела, тома). Принципы размещения файлов и хранения информации о расположении файлов. Организация каталогов. Ограничение доступа к файлам и каталогам.

Навыки и умения

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

Файловые системы. Структура файловой системы

Данные на диске хранятся в виде файлов. Файл - это именованная часть диска.

Для управления файлами предназначены системы управления файлами.

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

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

Система управления файлами является основной подсистемой в абсолютном большинстве современных ОС.

С помощью системы управления файлами

· связываются по данным все системные обрабатывающие программы;

· решаются проблемы централизованного распределения дискового пространства и управления данными;

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

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

Постараемся различать файловую систему и систему управления файлами.

Термин «файловая система» определяет принципы доступа к данным, организованным в файлы.

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

Итак, для работы с файлами, организованными в соответствии с некоторой файловой системой, для каждой ОС должна быть разработана соответствующая система управления файлами. Эта система УФ будет работать только в той ОС, для которой она создана.

Для семейства ОС Windows в основном используются файловые системы: VFAT , FAT 32, NTFS .

Рассмотрим структуру этих файловых систем.

В файловой системе FAT дисковое пространство любого логического диска делится на две области:

· системную область и

· область данных.

Системная область создается и инициализируется при форматировании, а впоследствии обновляется при манипулировании файловой структурой.

Системная область состоит из следующих компонентов:

· загрузочного сектора, содержащего загрузочную запись (boot record );

· зарезервированных секторов (их может и не быть);

· таблицыразмещенияфайлов (FAT, File Allocation Table);

· корневогокаталога (Root directory, ROOT).

Эти компоненты расположены на диске друг за другом.

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

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

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

· уменьшить размер таблицы FAT ;

· уменьшить фрагментацию файлов;

· сокращается длина цепочек файла Þ ускоряется доступ к файлу.

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

В современных файловых системах (FAT 32, HPFS , NTFS ) эта проблема решается за счет ограничения размера кластера (максимум 4 Кбайта)

Картой области данных являетсяТ аблица размещения файлов (File Allocation Table - FAT) Каждый элемент таблицы FAT (12, 16 или 32 бит) соответствует одному кластеру диска и характеризует его состояние: свободен, занят или является сбойным кластером (bad cluster).

· Если кластер распределен какому-либо файлу (т.е., занят), то соответствующий элемент FAT содержит номер следующего кластера файла;

· последний кластер файла отмечается числом в диапазоне FF8h - FFFh (FFF8h - FFFFh);

· если кластер является свободным, он содержит нулевое значение 000h (0000h);

· кластер, непригодный для использования (сбойный), отмечается числом FF7h (FFF7h).

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

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

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

В связи с тем, что FAT используется очень интенсивно при доступе к диску, она обычно загружается в ОП (в буфера ввода/вывода или кэш) и остается там настолько долго, насколько это возможно.

Основной недостаток FAT - медленная работа с файлами. При создании файла работает правило - выделяется первый свободный кластер. Это ведет к фрагментации диска и сложным цепочкам файлов. Отсюда следует замедление работы с файлами.

Для просмотра и редактирования таблицы FAT можно использовать утилиту Disk Editor .

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

Корневой каталог описываетфайлы и другие каталоги. Элементом каталога является дескриптор (описатель) файла.

Дескриптор каждого файла и каталога включает его

· имя

· расширение

· дату создания или последней модификации

· время создания или последней модификации

· атрибуты (архивный, атрибут каталога, атрибут тома, системный, скрытый, только для чтения)

· длину файла (для каталога - 0)

· зарезервированное поле, которое не используется

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

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

Для просмотра и редактирования корневого каталога ROOT можно также использовать утилиту Disk Editor .

Файловая система VFAT

Файловая система VFAT (виртуальная FAT ) впервые появилась в Windows for Workgroups 3.11 и была предназначена для файлового ввода/вывода в защищенном режиме.

Используется эта файловая система в Windows 95.

Поддерживается она также и в Windows NT 4.

VFAT - это «родная» 32-разрядная файловая система Windows 95. Ее контролирует драйвер VFAT .VXD .

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

НО, элементы таблицы размещения файлов остаются 12- или 16-разрядными, поэтому на диске используется та же структура данных (FAT ). Т.е. формат таблицы VFAT такой же , как и формат FAT .

VFAT наряду с именами «8.3» поддерживает длинные имена файлов . (Часто говорят, что VFAT - это FAT с поддержкой длинных имен).

Основной недостаток VFAT - большие потери на кластеризацию при больших размерах логического диска и ограничения на сам размер логического диска.

Файловая система FAT 32

Это новая реализация идеи использования таблицы FAT .

FAT 32 - это полностью самостоятельная 32-разрядная файловая система.

Впервые использовалась в Windows OSR 2 (OEM Service Release 2).

В настоящее время FAT 32 используется в Windows 98 и Windows ME .

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

1. Намного эффективнее расходует дисковое пространство за счет того, что использует кластеры меньшего размера (4 Кб) - подсчитано, что экономится до 15%.

2. Имеет расширенную загрузочную запись, которая позволяет создавать копии критических структур данных Þ повышает устойчивость диска к нарушениям структур диска

3. Может использовать резервную копию FAT вместо стандартной.

4. Может перемещать корневой каталог, другими словами, корневой каталог может находиться в произвольном месте Þ снимает ограничение на размер корневого каталога (512 элементов, т.к. ROOT должен был занимать один кластер).

5. Усовершенствована структура корневого каталога

Появились дополнительные поля, например, время создания, дата создания, дата последнего доступа, контрольная сумма

По-прежнему для длинного имени файла используется несколько дескрипторов.

Файловая система HPFS

HPFS (High Performance File System ) - вы­сокопроизводительная файловая система.

HPFS впервые появилась в OS/2 1.2 и LAN Manager .

Перечислим основные особенности HPFS.

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

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

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

Экстенты (extent ) - фрагменты файла, располагающиеся в смежных секторах диска. Файл имеет по крайней мере один экстент, если он не фрагментирован, а в противномслучае - несколько экстентов.

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

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

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

C труктура раздела HPFS


В начале раздела с установленной HPFS расположено три управляющих блока:

· загрузочный блок (boot block ),

· дополнительный блок (super block ) и

· запас­ной (резервный) блок (spare block ).

Они занимают 18 секторов.

Все остальное дис­ковое пространство в HPFS разбито на части из смежных секторов - полосы (band - полоса, лента). Каждая полоса занимает на диске 8 Мбайт.

Каждая полоса и имеет свою собственную битовую карту распределе­ния секторов .Битовая карта показывает, какие секторы данной полосы за­няты, а какие - свободны. Каждому сектору полосы данных соответствует один бит в ее битовой карте. Если бит = 1, то сектор занят, если 0 - свободен.

Битовые карты двух полос располагаются на диске рядом, так же располагаются и сами полосы. То есть последовательность полос и карт выглядит как на рис.

Сравним с FAT . Там на весь диск только одна «битовая карта» (таблица FAT ). И для работы с ней приходится перемещать головки чте­ния/записи в среднем через половину диска.

Именно для того, чтобы сократить время позиционирования головок чтения/записи жесткого диска, в HPFS диск разбит на полосы.

Рассмотрим управляющие блоки .

Загрузочный блок (boot block )

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

Программа начальной загрузки на­ходит файл OS 2 LDR , считывает его в память и передает управление этой про­грамме загрузки ОС, которая, в свою очередь, загружает с диска в память ядро OS/2 - OS 2 KRNL . И уже OS 2 KRIML с помощью сведений из файла CONFIG . SYS за­гружает в память все остальные необходимые программные модули и блоки дан­ных.

Загрузочный блок располагается в секторах с 0 по 15.

Супер Блок (super block )

Содержит

· указатель на список битовых карт (bitmap block list ). В этом списке перечислены все блоки на диске, в которых расположены би­товые карты, используемые для обнаружения свободных секторов;

· указатель на список дефектных блоков (bad block list ). Когда система обнаруживает поврежденный блок, он вносится в этот список и для хранения информации больше не используется;

· указатель на группу каталогов (directory band ),

· указатель на файловый узел (F -node ) корневого каталога,

· дату последней проверки раздела програм­мой CHKDSK ;

· информацию о размере полосы (в текущей реализации HPFS - 8 Мбайт).

Super block размещается в 16 секторе.

Резервный блок (spare block)

Содержит

· указатель на карту аварийного замеще­ния (hotfix map или hotfix -areas );

· указатель на список свободных запасных бло­ков (directory emergency free block list );

· ряд системных флагов и дескрипторов.

Этот блок разме­щается в 17 секторе диска.

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

Принцип размещения файлов

Экстенты (extent ) - фрагменты файла, располагающиеся в смежных секторах диска. Файл имеет по крайней мере один экстент, если он не фрагментирован, а в противномслучае - несколько экстентов.

Для сокращения времени позиционирования головок чтения/записи жесткого диска система HPFS стремится

1)расположить файл в смежных блоках;

2)если такой возможности нет, то разместить экстенты фрагментированного файла как можно ближе друг к другу,

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

Принципы хранения информации о расположении файлов

Каждый файл и каталог диска имеет свой файловый узел F-Node . Это структура, в которой содержится информация о располо­жении файла и о его расширенных атрибутах.

Каждый F-Node занимает один сектор и всегда располагается поблизости от своего файла или каталога (обычно - непосредственно перед файлом или ка­талогом). Объект F-Node содержит

· длину,

· первые 15 символов имени файла,

· специальную служебную информацию,

· статистику по доступу к файлу,

· расши­ренные атрибуты файла,

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

· ассоциативную информацию о расположении и подчине­нии файла и т. д.

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

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

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

Структура и размещение каталогов

Для хранения каталогов используется полоса, находящаяся в центре диска .

Эта полоса называетсяdirectory band .

Если она полностью заполнена, HPFS начинает располагать каталоги файлов в других полосах.

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

Однако существенно больший (по сравнению с размещением Directory Band в середине логического диска) вклад в производительность HPFS дает использо­вание метода сбалансированных двоичных деревьев для хранения и поиска ин­формации о местонахождении файлов.

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

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

Каждая за­пись, входящая в состав дерева, содержит

· атрибуты файла,

· указатель на соответствующий файловый узел,

· информацию о времени и дате создания фай­ла, времени и дате последнего обновления и обращения,

· длине данных, содержа­щих расширенные атрибуты,

· счетчик обращений к файлу,

· длине имени файла

· само имя,

· и другую информацию.

Файловая система HPFS при поиске файла в каталоге просматривает только не­обходимые ветви двоичного дерева. Такой метод во много раз эффек­тивнее, чем последовательное чтение всех записей в каталоге, что имеет место в системе FAT .

Размер каждого из блоков, в терминах которых выделяются каталоги в текущей реализации HPFS, равен 2 Кбайт. Размер записи, описывающей файл, зависит от размера имени файла. Если имя занимает 13 байтов (для формата 8.3), то блок из 2 Кбайт вмещает до 40 описателей файлов. Блоки связаны друг с другом по­средством списка.

Проблемы

При переименовании файлов может возникнуть так называемая перебаланси­ровка дерева. Создание файла, переименование или стирание может приводить к каскадированию блоков каталогов . Фактически, переименование может потер­петь неудачу из-за недостатка дискового пространства, даже если файл непо­средственно в размерах не увеличился. Во избежание этого «бедствия» HPFS поддерживает небольшой пул свободных блоков, которые могут использовать­ся при «аварии». Эта операция может потребовать выделения дополнительных блоков на заполненном диске. Указатель на этот пул свободных блоков сохраня­ется в SpareBlock ,

Принципы размещения файлов и каталогов на диске в HPFS :

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

· каталоги размещаются в середине дискового пространства;

· каталоги хранятся в виде бинарного сбалансированного дерева с записями, расположенными в алфавитном порядке.

Надежность хранения данных в HPFS

Любая файловая система должна обладать средствами исправления ошибок, возникаю­щих при записи информации на диск. Система HPFS для этого использует меха­низм аварийного замещения ( hotfix ).

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

Эта карта представляет собой просто пары двойных слов, каждое из которых является 32-битным номером сектора.

Первый номер указывает на дефектный сек­тор, а второй - на тот сектор среди имеющихся запасных секторов, который был выбран для его замены.

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

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

Файловая система NTFS

Файловая система NTFS (New Technology File System) содержит ряд значительных усовер­шенствований и изменений, существенно отличающих ее от других файловых систем.

Заметим, что за редкими исключениями, с разделами NTFS можно работать напрямую только из Windows NT , хотя и имеются для ряда ОС соответствующие реализа­ции систем управления файлами для чтения файлов из томов NTFS.

Однако полноценных реализаций для работы с NTFS вне системы Windows NT пока нет.

NTFS не поддерживается в широко распространенных ОС Windows 98 и Windows Millennium Edition .

Основные особенности NT FS

· работа на дисках большого объема происходит эффективно (намного эффективнее, чем в FAT );

· имеются средства для ограничения доступа к файлам и катало­гам Þ раз­делы NTFS обеспечивают локальную безопасность как файлов, так и каталогов;

· введен механизм транзакций, при котором осуществляется журналирование файловых операций Þ существенное увеличение надежности;

· сняты многие ограничения на максимальное количество дисковых секто­ров и/или кластеров;

· имя файла в NTFS, в отличие от файловых систем FAT и HPFS , может содержать любые символы, включая полный набор национальных алфавитов, так как данные представлены в Unicode - 16-битном представлении, которое дает 65535 разных символов. Максимальная длина имени файла в NTFS - 255 символов.

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

Структура тома с файловой системой NTFS

Раздел NTFS называется томом (volume ). Максимально возможные размеры тома (и размеры файла) составляют 16 Эбайт (экзабайт 2**64).

Как и другие системы, NTFS делит дисковое пространство тома на кластеры - блоки данных, адресуемые как единицы данных. NTFS поддержива­ет размеры кластеров от 512 байт до 64 Кбайт; стандартом же считается кластер размером 2 или 4 Кбайт.

Все дисковое пространство в NTFS делится на две неравные части.


Первые 12 % диска отводятся под так называемую MFT-зону - пространство, которое может занимать, увеличиваясь в размере, главный служебный метафайл MFT .

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

Остальные 88 % тома представляют собой обычное пространство для хранения файлов.

MFT (master file table - общая таблица файлов) по сути - это каталог всех остальных файлов диска, в том числе и себя самого. Он предназначен для определения расположения файлов.

MFT состоит из записей фиксированного размера. Размер записи MFT (минимум 1 Кб и максимум 4 Кб) оп­ределяется во время форматирования тома.

Каждая запись соответ­ствует какому-либо файлу.

Первые 16 записей но­сят служебный характер и недоступны операционной системе - они называются метафайлами, причем самый первый метафайл - сам MFT.

Эти первые 16 эле­ментов MFT - единственная часть диска, имеющая строго фиксированное поло­жение. Копия этих же 16 записей хранится в середине тома для надежности.

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

Метафайлы носят служебный характер - каждый из них отвечает за какой-либо аспект работы системы. Метафайлы нахо­дятся в корневом каталоге NTFS-тома. Все они начинаются с символа имени «$», хотя получить какую-либо информацию о них стандартными средствами сложно. В табл. приведены основные метафайлы и их назначение.

Имя метафайла

Назначение метафайла

$MFT

Сам Master File Table

$MFTmirr

Копия первых 16 записей MFT, размещенная посередине тома

$LogFile

Файл поддержки операций журналирования

$Volume

Служебная информация - метка тома, версия файловой системы и т. д.

$AttrDef

Список стандартных атрибутов файлов на томе

Корневой каталог

$Bitmap

Карта свободного места тома

$Boot

Загрузочный сектор (если раздел загрузочный)

$Quota

Файл, в котором записаны права пользователей на использование дискового пространства (этот файл начал работать лишь в Windows 2000 с системой NTFS 5.0)

$Upcase

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

В соответствующей записи MFT хранится вся информация о файле:

· имя файла,

· размер;

· атрибуты файла;

· положение на диске отдельных фрагментов и т. д.

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

Если файл имеет не очень большой размер, то данные файла хранятся прямо в MFT, в оставшемся от основных данных месте в пределах одной записи MFT.

Файл в томе с NTFS идентифицируется так называемой файловой ссылкой (File Reference ), которая представляется как 64-разрядное число.

· номера файла, который соответствует номеру записи в MFT,

· и номера последовательности. Этот номер увеличивается всякий раз, когда данный номер в MFT используется повторно, что позволяет файловой системе NTFS выполнять внутренние проверки целостности.

Каждый файл в NTFS представлен с помощью потоков (streams ), то есть у него нет как таковых «просто данных», а есть потоки.

Один из потоков - это и есть данные файла.

Большинство атрибутов файла - это тоже потоки.

Таким об­разом, получается, что базовая сущность у файла только одна - номер в MFT, а все остальное, включая и его потоки, - опционально.

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

Стандартные атрибуты для файлов и каталогов в томе NTFS имеют фиксиро­ванные имена и коды типа.

Каталог в NTFS представляет собой специальный файл, хранящий ссылки на другие файлы и каталоги.

Файл каталога разделен на блоки, каждый из которых содержит

· имя файла,

· базовые атрибуты и

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

Внутренняя структура каталога представляет собой бинарное дерево, как в HPFS.

Количество файлов в корневом и некорневом каталогах не ограни­чено.

Файловая система NTFS поддерживает объектную модель безопасности NT : NTFS рассматривает каталоги и файлы как разнотипные объекты и ведет отдельные (хотя и перекры­вающиеся) списки прав доступа для каждого типа.

NTFS обеспечивает безопасность на уровне файлов; это означает, что права доступа к томам, каталогам и файлам могут зависеть от учетной записи пользователя и тех групп, к которым он принадлежит. Каждый раз, когда пользователь обращается к объекту файловой системы, его права доступа проверяются по списку разреше­ний данного объекта. Если пользователь обладает достаточным уровнем прав, его запрос удовлетворяется; в противном случае запрос отклоняется. Эта модель безопасности применяется как при локальной регистрации пользователей на компьютерах с NT , так и при удаленных сетевых запросах.

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

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

Основной недостаток файловой системы NTFS - служебные данные занимают много места (например, каждый элемент каталога занимает 2 Кбайт) - для малых раз­делов служебные данные могут занимать до 25% объема носителя.

Þ система NTFS не может использоваться для форматирования флоппи-дисков. Не стоит пользоваться ею для форматирования разделов объемом менее 100 Мбайт.

Файловая система ОС UNIX

В мире UNIX существует несколько разных видов файловых систем со своей структурой внешней памяти. Наиболее известны традиционная файловая система UNIX System V (s5) и файловая система семейства UNIX BSD (ufs).

Рассмотрим s 5.

Файл в системе UNIX представляет собой множество символов с произвольным доступом.

Файл имеет такую структуру, которую налагает на него пользователь.

Файловая система Unix, это иерархическая, многопользовательская файловая система.

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

Замечание. На самом деле файловая система Unix не является древообразной. Дело в том, что в системе имеется возможность нарушения иерархии в виде дерева, так как имеется возможность ассоциировать несколько имен с одним и тем же содержимым файла .

Структура диска

Диск разделен на блоки. Размер блока данных определяется при форматировании файловой системы командой mkfs и может быть установлен 512, 1024, 2048, 4096 или 8192 байтов.

Считаем по 512 байт (размер сектора).

Дисковое пространство делится на следующие области (см. рис.):

· загрузочный блок;

· управляющий суперблок;

· массив i -узлов;

· область для хранения содержимого (данных) файлов;

· совокупность свободных блоков (связанных в список);

Блокначальной загрузки

Суперблок

i - узел

. . .

i - узел

Замечание. Для файловой системы UFS - все это для группы цилиндров повторяется (кроме Boot -блока) + выделена специальная область для описания группы цилиндров

Блок начальной загрузки

Блок размещен в блоке №0. (Вспомним, что размещение этого блока в нулевом блоке системного устройства определяется аппаратурой, так как аппаратной загрузчик всегда обращается к нулевому блоку системного устройства. Это последний компонент файловой системы, который зависит от аппаратуры.)

Boot -блок содержит программу раскрутки, которая служит для первоначального запуска ОС UNIX . В файловых системах s 5 реально используется boot -блок только корневой файловой системы. В дополнительных файловых системах эта область присутствует, но не используется.

Суперблок

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

В частности суперблок содержит следующую информацию

· количество i -узлов (индексных дескрипторов);

· размер раздела???;

· список свободных блоков;

· список свободных i -узлов;

· и другое.

Обратим внимание! Свободное пространство на диске образует связанный список свободных блоков . Этот список хранится в суперблоке.

Элементами списка являются массивы из 50 элементов(если блок = 512 байт, то элемент = 16 бит):

· в элементах массива №№1-48 записаны номера свободных блоков пространства блоков файлов с 2 до 49.

· в №0 элементе содержится указатель на продолжение списка, а

· в последнем элементе (№49) содержится указатель на свободный элемент в массиве.

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

Так как размер массива - 50 элементов, то возможны две критические ситуации:

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

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

Список свободных i -узлов . Это буфер, состоящий из 100 элементов. В нем находится информация о 100 номерах i -узлов, которые свободны в данный момент.

Суперблок всегда находится в ОЗУ

Þ все операции (освобождение и занятие блоков и i -узлов происходят в ОЗУ Þ минимизация обменов с диском.

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

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

Область индексных дескрипторов

Это массив описаний файлов, называемых i -узлами (i - node ) .(64-х байтные?)

Каждый индексный описатель (i -узел) файла содержит:

· Тип файла (файл/каталог/специальный файл/fifo/socket)

· Атрибуты (права доступа) - 10

· Идентификатор владельца файла

· Идентификатор группы-владельца файла

· Время создания файла

· Время модификации файла

· Время последнего доступа к файлу

· Длина файла

· Количество ссылок к данному i -узлу из различных каталогов

· Адреса блоков файла

! Обратите внимание . Здесь нет имени файла

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

Если файл превышает десять блоков, то начинает работать следующий механизм: 11-й элемент поля содержит номер блока, в котором размещены 128(256) ссылок на блоки данного файла. В том случае, если файл еще больше - то используется 12й элемент поля- он содержит номер блока, в котором содержится 128(256) номеров блоков, где каждый блок содержит 128(256) номеров блоков файловой системы. А если файл еще больше, то используется 13 элемент - где глубина вложенности списка увеличена еще на единицу.

Таким образом мы можем получить файл размером (10+128+128 2 +128 3)*512.

Это можно представить в следующем виде:

Адрес 1-го блока файла

Адрес 2-го блока файла

Адрес 10-го блока файла

Адрес блока косвенной адресации (блока с 256 адресами блоков)

Адрес блока 2-й косвенной адресации (блока с 256 адресами блоков с адресами)

Адрес блока 3-й косвенной адресации (блока с адресами блоков с адресами блоков с адресами)

Защита файла

Теперь обратим внимание на идентификаторы владельца и группы и биты защиты.

В ОС Unix используется трехуровневая иерархия пользователей :

Первый уровень - все пользователи.

Второй уровень - группы пользователей. (Все пользователи подразделены на группы.

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

1) Владелец файла. Этот атрибут связан с одним конкретным пользователем, который автоматически назначается системой владельцем файла. Владельцем можно стать по умолчанию, создав файл, а также есть команда, которая позволяет менять владельца файла.

2) Защита доступа к файлу. Доступ к каждому файлу ограничивается по трем категориям:

· права владельца (что может делать владелец с этим файлом, в общем случае - не обязательно все, что угодно);

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

· все остальные пользователи системы;

По этим трем категориям регламентируются три действия: чтение из файла, запись в файл и исполнение файла (в мнемонике системы R,W,X, соответственно). В каждом файле по этим трем категориям определено - какой пользователь может читать, какой писать, а кто может запускать его в качестве процесса.

Организация каталогов

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

Элемент каталога состоит из двух полей:

1)номер i -узла (порядковый номер в массиве i -узлов)и

2)имя файла:

Каждый каталог содержит два специальных имени: ‘.’ - сам каталог; ‘..’ - родительский каталог.

(Для корневого каталога родитель ссылается на него же самого.)

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

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

Итак, чтобы получить доступ к файлу по имени, операционная система

1. находит это имя в каталоге, содержащем файл,

2. получает номер i -узла файла,

3. по номеру находит i- узел в области i-узлов,

4. из i-узла получает адреса блоков, в которых расположены данные файла,

5. по адресам блоков считывает блоки из области данных.

Структура дискового раздела в EXT 2 FS

Все пространство раздела делится на блоки. Блок может иметь размер от 1, 2 или 4 килобайта. Блок является адресуемой единицей дискового пространства.

Блоки, в свою область объединяются в группы блоков. Группы блоков в файловой системе и блоки внутри группы нумеруются последовательно, начиная с 1. Первый блок на диске имеет номер 1 и принадлежит группе с номером 1. Общее число блоков на диске (в разделе диска) является делителем объема диска, выраженного в секторах. А число групп блоков не обязано делить число блоков, потому что последняя группа блоков может быть не полной. Начало каждой группы блоков имеет адрес, который может быть получен как ((номер группы - 1)* (число блоков в группе)).

Каждая группа блоков имеет одинаковое строение. Ее структура представлена в таблице.

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

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

Вслед за суперблоком расположено описание группы блоков (Group Descriptors). Это описание содержит:

Адрес блока, содержащего битовую карту блоков (block bitmap) данной группы;

Адрес блока, содержащего битовую карту индексных дескрипторов (inode bitmap) данной группы;

Адрес блока, содержащего таблицу индексных дескрипторов (inode table) данной группы;

Счетчик числа свободных блоков в данной группе;

Число свободных индексных дескрипторов в данной группе;

Число индексных дескрипторов в данной группе, которые являются каталогами

и другие данные.

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

Файловая система Ext 2 характеризуется:

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

Внутреннее представление файлов

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

Индексные дескрипторы файлов

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

Индексный дескриптор файла содержит следующую информацию:

- Тип и права доступа к данному файлу.

Идентификатор владельца файла (Owner Uid).

Размер файла в байтах.

Время последнего обращения к файлу (Access time).

Время создания файла.

Время последней модификации файла.

Время удаления файла.

Идентификатор группы (GID).

Счетчик числа связей (Links count ).

Число блоков, занимаемых файлом.

Флагифайла (File flags)

Зарезервировано для ОС

Указатели на блоки, в которых записаны данные файла (пример прямой и косвенной адресации на рис.1)

Версия файла (для NFS)

ACL файла

ACL каталога

Адресфрагмента (Fragment address)

Номерфрагмента (Fragment number)

Размер фрагмента (Fragment size )

Каталоги

Каталоги являются файлами.

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

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

Дополнительные возможности EXT2 FS

В дополнение к стандаpтным возможностям Unix, EXT2fs пpедоставляет некотоpые дополнительные возможности, обычно не поддеpживаемые файловыми системами Unix.

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

Во вpемя монтиpования системы могут быть установлены некотоpые особенности, связанные с файловыми атpибутами. Опция mount позволяет администpатоpу выбpать особенности создания файлов. В файловой системе с особенностями BSD, файлы создаются с тем же идентификатоpом гpуппы, как и у pодительского каталога. Особенности System V несколько сложнее. Если у каталога бит setgid установен, то создаваемые файлы наседуют идентификатоp гpуппы этого каталога, а подкаталоги наследуют идентификатоp гpуппы и бит setgid. В пpотивном случае, файлы и каталоги создаются с основным идентификатоpом гpуппы вызывающего пpоцесса.

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

EXT2fs позволяет пpи создании файловой системы выбpать pазмеp логического блока. Он может быть pазмеpом 1024, 2048 или 4096 байт. Использование блоков большого объема пpиводит к ускоpению опеpаций ввода/вывода (так как уменьшается количество запpосов к диску), и, следовательно, к меньшему пеpемещению головок. С дpугой стоpоны, использование блоков большого объема пpиводит к потеpе дискового пpостpанства. Обычно последний блок файла используется не полностью для хpанения инфоpмации, поэтому с увеличением объема блока, повышается объем теpяемого дискового пpостpанства.

EXT2fs позволяет использовать ускоpенные символические ссылки. Пpи пpименении таких ссылок, блоки данных файловой системы не используются. Имя файла назначения хpанится не в блоке данных, а в самом индексном дескpиптоpе. Такая стpуктуpа позволяет сохpанить дисковое пpостpанство и ускоpить обpаботку символических ссылок. Конечно, пpостpанство, заpезеpвиpованное под дескpиптоp, огpаничено, поэтому не каждая ссылка может быть пpедставлена как ускоpенная. Максимальная длина имени файла в ускоpенной ссылке pавна 60 символам. В ближайшем будующем планиpуется pасшиpить эту схему для файлов небольшого объема.

EXT2fs следит за состоянием файловой системы. Ядpо использует отдельное поле в супеpблоке для индикации состояния файловой системы. Если файловая система смонтиpована в pежиме read/write, то ее состояние устанавливается как "Not Clean". Если же она демонтиpована или смонтиpована заново в pежиме read-only, то ее состояние устанавливается в "Clean". Во вpемя загpузки системы и пpовеpке состояния файловой системы, эта инфоpмация используется для опpеделения необходимости пpовеpки файловой системы. Ядpо также помещает в это поле некотоpые ошибки. Пpи опpеделении ядpом несоответствия, файловая система помечается как "Erroneous". Пpогpамма пpовеpки файловой системы тестиpует эту инфоpмацию для пpовеpки системы, даже если ее состояние является в действительности "Clean".

Длительное игноpиpование тестиpования файловой системы иногда может пpивести к некотоpым тpудностям, поэтому EXT2fs включает в себя два метода для pегуляpной пpовеpки системы. В супеpблоке содеpжится счетчик монтиpования системы. Этот счетчик увеличивается каждый pаз, когда система монтиpуется в pежиме read/write. Если его значение достигает максимального (оно также хpанится в супеpблоке), то пpогpамма тестиpования файловой системы запускает ее пpовеpку, даже если ее состояние является "Clean". Последнее вpемя пpовеpки и максимальный интеpвал между пpовеpками также хpанится в супеpблоке. Когда же достигается максимальный интеpвал между пpовеpками, то состояние файловой системы игноpиpуется и запускается ее пpовеpка.

Оптимизация пpоизводительности

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

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

Система EXT2fs также содеpжит большое количество оптимизаций pазмещения инфоpмации. Гpуппы блоков используются для объединения соответствующих индексных дескpиптоpов и блоков данных. Ядpо всегда пытается pазместить блоки данных одного файла в одной гpуппе, так же как и его дескpиптоp. Это пpедназначено для уменьшения пеpемещения головок пpивода пpи считывании дескpиптоpа и соответствующих ему блоков данных.

Пpи записи данных в файл, EXT2fs заpанее pазмещает до 8 смежных блоков пpи pазмещении нового блока. Такой метод позволяет достичь высокой пpоизводительности пpи сильной загpуженности системы. Это также позволяет pазмещать смежные блоки для файлов, что укоpяет их последующее чтение.

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

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

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

Как было уже выше сказано, записать и прочитать можно только кратно 512 байтам, т.е. 1 сектор. Также есть понятие — кластер это тупо несколько секторов, например если размер кластера 16кБ, то значит что в нем 16000/512 = 31.25, точнее 32 сектора, а реальный размер кластера 16384 байта. Все файлы занимают размер кратно размеру кластера. Даже если файл размером 1кБ, а кластер 16кБ, то файл будет занимать все 16кБ.

Логично было бы делать кластеры, маленького размера, то тут вступает в дело ограничение на максимальное количество файлов и на их размер. FAT16 оперирует 16 битными данными, поэтому нельзя запихать больше чем 2^16 кластеров. Поэтому чем меньше их размер, тем более эффективно используется место под мелкие файлы, но тем меньше информации можно запихать на диск. И наоборот, чем больше размер, тем больше информации можно впихать, но тем менее эффективно используется место под мелкие файлы. Максимальный размер кластера 64кБ, поэтому максимум для FAT16 64кб*2^16 = 4Гб.

Исходные данные: имеется карта памяти micro SD на 1Гб. Имеет метку MYDISK, отформатирована полностью, размер кластера 16кБ.

Понадобится Hex редактор, но любой не подойдет, нужен такой, который может просматривать диск целиком, а не только файлы на диске. Из того что мне удалось найти: WinHex самый годный, но платный; HxD простой, бесплатный, но мне так и не удалось заставить его сохранять изменения на диске; DMDE — немного не user friendly, бесплатный и позволяет сохранить изменения. В общем я остановился на HxD.

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

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

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

Наиболее интересные данные указаны в таблице

Первое что нам нужно, это узнать размер загрузочной области. Смотрим адрес 0x0E и видим, что под загрузочную область выделено 4 сектора, т.е. с адреса 4*512 = 0x800 начинается область FAT.

Количество таблиц FAT можно определить по адресу 0x10 загрузочной области. В нашем примере их две, почему две, потому что каждая таблица дублируется резервной, что бы в случае сбоя можно было восстановить данные. Размер таблицы указан по адресу 0x16. Таким образом размер фата 512*2*0xEE = 0x3B800, а корневой каталог начинается с адреса: 0x800 + 0x3B800 = 0x3C000

Внутри корневого каталога все элементы разбиты по 32 байта. Первый элемент, это метка тома, а вот последующие элементы это файлы и папки. Если название файла начинается с 0xE5, то это значит что файл удален. Если название начинается с 0x00, то это значит, что предыдущий файл был последним.

Довольно интересная структура корневого каталога получилась у меня. Карта была отформатирована полностью, затем создано 2 текстовых файла, которые переименованы в MyFile.txt и BigFile.txt.

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

Самое важное, что можно здесь подчерпнуть, это адрес первого кластера, с которого начинаются данные нашего файла. Адрес всегда находится по смещению 0x1A. Например, имя нашего файла MyFile.txt расположено по адресу 0x3C100, к нему прибавляем 0x1A, там видим номер первого кластера. = 0x0002 т.е. второй кластер. Для файла BigFile.txt, данные начинаются с третьего кластера.

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

Размер указан в загрузочном секторе по адресу 0x11(2байта) = 0x0200*32 = 0x4000 или 16384 байт.

Прибавим к адресу корня его размер: 3С000 + 4000 = 40000 это адрес первого кластера данных, но нам нужен второй, чтобы найти MyFile.txt. Количество секторов в кластере 32, размер кластера = 32*512 = 16384 или 0x4000, поэтому прибавим к адресу первого кластера, его размер т.е. с 0x44000 по идее должен начаться второй кластер.

Идем по адресу 0x44000 и видим, что данные принадлежат BigFile.txt (в нем просто мусор)

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

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

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

Первые восемь байт 0xF8FFFFFF это идентификатор начала таблицы фат. Дальше идет 2 байта, которые относятся к MyFile.txt, то что в них записано 0xFFFF означает, что файл занимает всего один кластер. А вот следующий файл BigFile.txt начинается в третьем кластере, это мы помним из корневой директории, продолжается в четвертом, далее идет в 5,6,7… и заканчивается в 12, т.е. занимает 10 кластеров.

Проверим, действительно ли это так. Файл весить 163кБ, т.е. занимает 163000/(32*512) = 9.9 кластеров, что вполне походит на ожидаемое. Повторимся еще раз, что один элемент в таблице FAT занимает 2 байта, т.е. 16 бит, отсюда и пошло название FAT16. Соответственно максимальный адрес равен 0xFFFF, т.е. максимальный объем для FAT16 0xFFFF*размер кластера.

Перейдем к FAT32. Загрузочная часть немного изменена.

Есть некоторые принципиальные изменения. Имя файловой системы перекочевало по адресу 0x52, размер корневого теперь игнорируется. Область данных находится сразу за таблицами FAT, корневой каталог находится внутри области данных. Кроме того корневой каталог не имеет фиксированного размера.

Адрес области данных вычисляется:
размер загрузочного сектора + таблицы FAT, в моем случае получилось:
746496 + (3821056 * 2) = 0x800000

Адрес корневого каталога вычисляется:
(номер первого кластера корневого каталога — 2) * размер кластера + адрес начала области данных,
т.е. в данном примере он будет совпадать с началом области данных.

Как и прежде данные в корневом занимают 32байта, как и прежде «удаленные» магические файлы, предполагаю это временные файлы блокнота.

А вот начало первого кластера в MYFILE.txt определяется теперь двумя байтами, старший по смещению 0x14, младший как и прежде 1A. Поэтому номер первого кластера данных для файла будет:
8000A0 + 0x14 = 0x8000B4 — старший байт
8000A0 + 0x1A = 0x8000BA — младший байт
В моем случае карта была всего с одним файлом, поэтому это третий кластер.

Таблица FAT ищется как и в предыдущем случае, только теперь элементы занимают 4 байта, отсюда и название FAT32. Идеология расположения элементов в точности как в предыдущем случае.

Полезняшки для таблицы
F8 FF FF F0 — первый кластер
FF FF FF 0F — последний кластер
FF FF FF F7 — поврежденный кластер

Где же находятся данные?
начало области данных + размер кластера * (номер кластера корневого — 1)
= 0x800000 + (2*4096) = 0x801000

Надеюсь в общих чертах стало понятно, вроде как ничего сверхестественного нет. Кто прочитал и повторил может скушать печеньку 🙂

© omutsu.ru, 2024
Компьютерные подсказки - Оmutsu