Где хранятся атрибуты файлов в файловой системе fat

Обновлено: 02.07.2024

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

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

Логично было бы делать кластеры, маленького размера, то тут вступает в дело ограничение на максимальное количество файлов и на их размер. FAT16 оперирует 16 битными данными, поэтому нельзя запихать больше чем 2^16 кластеров. Поэтому чем меньше их размер, тем более эффективно используется место под мелкие файлы, но тем меньше информации можно запихать на диск. И наоборот, чем больше размер, тем больше информации можно впихать, но тем менее эффективно используется место под мелкие файлы. Максимальный размер кластера 64кБ, поэтому максимум для FAT16 64кб*2^16 = 4Гб.

fdisk

Исходные данные: имеется карта памяти micro SD на 1Гб. Имеет метку MYDISK, отформатирована полностью, размер кластера 16кБ.

fat16_struct

Для начала стоит рассмотреть структуру FAT16, картинка показывает в каком порядке расположены различные части файловой системы.

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

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

boot_sector

Наиболее интересные данные указаны в таблице

Смещение Размер в байтах Описание
0x0D 1 количество секторов в кластере = 0x20 или 32
0x0E 2 количество зарезервированных секторов = 0x0004 или 4
0x10 1 0x02 количество таблиц FAT
0x11 2 0x0200*32 размер корневой директории
0x16 2 количество секторов для одной таблицы FAT = 0x00EE или 238
0x36 8 используется FAT16
0x1FE 2 0x55AA конец загрузочного сектора

Первое что нам нужно, это узнать размер загрузочной области. Смотрим адрес 0x0E и видим, что под загрузочную область выделено 4 сектора, т.е. с адреса 4*512 = 0x800 начинается область FAT.

Количество таблиц FAT можно определить по адресу 0x10 загрузочной области. В нашем примере их две, почему две, потому что каждая таблица дублируется резервной, что бы в случае сбоя можно было восстановить данные. Размер таблицы указан по адресу 0x16. Таким образом размер фата 512*2*0xEE = 0x3B800, а корневой каталог начинается с адреса: 0x800 + 0x3B800 = 0x3C000

Внутри корневого каталога все элементы разбиты по 32 байта. Первый элемент, это метка тома, а вот последующие элементы это файлы и папки. Если название файла начинается с 0xE5, то это значит что файл удален. Если название начинается с 0x00, то это значит, что предыдущий файл был последним.

data_fat16

Довольно интересная структура корневого каталога получилась у меня. Карта была отформатирована полностью, затем создано 2 текстовых файла, которые переименованы в MyFile.txt и BigFile.txt.

root_dir

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

Самое важное, что можно здесь подчерпнуть, это адрес первого кластера, с которого начинаются данные нашего файла. Адрес всегда находится по смещению 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 по идее должен начаться второй кластер.

cluster2

Идем по адресу 0x44000 и видим, что данные принадлежат BigFile.txt (в нем просто мусор)

cluster1

Оказывается есть небольшая тонкость, нумерация кластеров начинается со второго, не понятно зачем так сделано но факт, т.е. на самом деле мы перешли на третий кластер. Вернемся на один кластер назад на адрес 0x40000 и видим ожидаемые данные.

Теперь спрашивается. Зачем же нам нужна таблица FAT? Дело в том, что данные могут быть фрагментированы, т.е. начало файла может находиться в одном кластере, а конец в совсем другом. Причем это могут быть совершенно разные кластеры. Их может быть несколько, разбросанных в разных областях данных. Таблица FAT это своего рода карта, которая нам указывает, как нам перемещаться между кластерами.

fat16_table

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

Проверим, действительно ли это так. Файл весить 163кБ, т.е. занимает 163000/(32*512) = 9.9 кластеров, что вполне походит на ожидаемое. Повторимся еще раз, что один элемент в таблице FAT занимает 2 байта, т.е. 16 бит, отсюда и пошло название FAT16. Соответственно максимальный адрес равен 0xFFFF, т.е. максимальный объем для FAT16 0xFFFF*размер кластера.

fat32_boot

Перейдем к FAT32. Загрузочная часть немного изменена.

Смещение Размер в байтах Описание
0x52 8 Имя файловой системы
0x24 4 Количество секторов занимаемых одной FAT
0x0E 2 количество резервных секторов
0x10 2 число таблиц FAT
0x0D 1 секторов в кластере
0x2C 4 номер первого кластера корневого каталога

Есть некоторые принципиальные изменения. Имя файловой системы перекочевало по адресу 0x52, размер корневого теперь игнорируется. Область данных находится сразу за таблицами FAT, корневой каталог находится внутри области данных. Кроме того корневой каталог не имеет фиксированного размера.

Адрес области данных вычисляется:
размер загрузочного сектора + таблицы FAT, в моем случае получилось:
746496 + (3821056 * 2) = 0x800000

fat32_table

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

Надеюсь в общих чертах стало понятно, вроде как ничего сверхестественного нет. Кто прочитал и повторил может скушать печеньку 🙂

6 комментариев: Файловая система FAT

Да похоже на то, просто этот момент как то вскользь везде упоминается, поэтому я решил тоже его не затрагивать

Почему в программе по адресу 0х0Е написано значение 04, по адресу 0х0F 00 соответственно 0400, а вы пишите 0х0004? Здесь запутался как располагаются байтики по адресам в памяти?

если число двухбайтное то справа налево, поэтому 0x04 младший байт, а 00 старший байт

Читайте о системных структурах файловой системы FAT: загрузочный сектор, FSINFO, таблица FAT и записи каталогов. Описание, размерность полей и интерпретация Процесс поиска удаленных файлов состоит из обнаружения и интерпретации содержимого диска. Этой статьей мы откроем цикл, в котором расскажем, как найти и правильно «прочитать» системную информацию. Существует четыре версии FAT — FAT8, FAT12, FAT16 и FAT32. Мы проведем анализ FAT32 диска, расположенного на SD-карте памяти фотоаппарата.

Загрузочный сектор, FSINFO, таблица FAT и записи каталогов FAT

Логический диск под управление FAT32 можно разделить на 3 логических части, которые идут последовательно друг за другом:

  • Зарезервированная область;
  • Область FAT;
  • Область данных (содержит корневой каталог и содержимое файлов);

Структура данных FAT

Рис.1 Физическая структура FAT.

Система FAT очень проста и условно в ней можно выделить 4 структуры:

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

Загрузочный сектор занимает 1 сектор (чаще всего 512 байт) и располагается в первом секторе. Давайте рассмотрим подробнее его содержимое.

Смещение Размер Описание Обязательное
0 3 Ссылка на загрузочный код Нет
3 8 Метка ОС I Нет
11 2 Сколько байт в секторе Да
13 1 Сколько секторов в кластере II Да
14 2 Размер резервной области в секторах Да
16 1 Сколько копий FAT-таблицы Да
17 2 Сколько объектов в корневом каталоге III Да
19 2 Сколько секторов на диске IV Да
21 1 Метка носителя V Нет
22 2 Размер таблицы FAT в секторах III Да
24 2 Сколько секторов в дорожке Нет
26 2 Сколько головок Нет
28 4 Сколько секторов перед началом раздела Нет
32 4 Сколько секторов в кластере II Да
36 4 Размер таблицы FAT в секторах Да
40 2 Режим обновления VI Да
42 2 Номер версии Да
44 4 Кластер с корневым каталогом Да
48 2 Сектор с FSINFO Нет
50 2 Сектор с резервной копией
загрузочного сектора
Нет
52 12 Резерв Нет
64 1 Номер диска Нет
65 1 Не используется Нет
66 1 Последовательность байт 0x29 VII Нет
67 4 Серийный номер тома Нет
71 11 Метка тома I Нет
82 8 Метка Нет
90 420 Резерв Нет
510 2 Последовательность байт 0xAA55 Нет

Таб.1 Структура загрузочного сектора FAT.

  • I В кодировке ASCII;
  • II Задается степенью 2;
  • III Использовалось для ранних версий FAT. Для FAT32 = 0;
  • IV Если количество секторов на диске больше 65535, используется поле по адресу 32;
  • V Для жестких дисков – 0xf8, для съемных – 0xf0;
  • VI Если бит 7 равен 1, активна только одна копия FAT, индекс которой определяется разрядами 0-3. В противном случае все структуры FAT являются зеркальными копиями друг друга;
  • VII Последовательность байт 0x29;

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

Структура FSINFO

Ссылка на начало структуры хранится в загрузочном секторе, размер составляет 1 сектор (обычно 512 байт). FAT использует FSINFO для алгоритма выделения свободных секторов диска.

Смещение Размер Описание Обязательное
0 4 Последовательность байт
0x41615252
Нет
4 480 Резерв Нет
484 4 Последовательность байт
0x6147272
Нет
488 4 Сколько свободных кластеров Нет
492 4 Следующий свободный кластер Нет
496 12 Резерв Нет
508 4 Последовательность байт
0xAA550000
Нет

Таб.2 Структура данных FSINFO.

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

Таблица FAT

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

В FAT32 структура состоит из записей размером 4 байта. Каждая запись соответствует кластеру на логическом диске и может принимать следующие значения:

  • 0x000 0000 – если кластер свободен;
  • 0x0fff fff7 – если кластер поврежден и не должен выделяться;
  • 0x0fff fff8 – если кластер завершает файл или каталог;
  • 0x000 0001 … 0x0fff fff6 – указатель на следующий кластер, занимаемый файлом или каталогом.

Чтение и анализ основной таблицы FAT и её копий позволяют выяснить, в каких кластерах хранится содержимое нужного файла.

NTFS, FAT32 или ExFAT для флешки, внешнего USB диска, как отформатировать без потери данных

Записи каталогов

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

Смещение Размер Описание Обязательное
0 1 Порядковый номер
или последовательность байт 0xe5 I, II
Да
1 10 Первые 5 символов имени файла I Да
11 1 Последовательность байт 0x0f Да
12 1 Резерв Нет
13 1 Контрольная сумма Да
14 12 Следующие 6 символов имени файла I Да
26 2 Резерв Нет
28 4 Следующие 2 символа имени файла I Да

Таб.3 Структура записи каталога Long File Name.

  • I Имя файла хранится в Unicode;
  • II FAT заменяет первый символ имени файла на 0xe5, если он удален.

Для хранения длинного имени файла может использоваться несколько структур LFN. Чтобы получить полное имя, нужно сложить все эти структуры. После дополнительных следует базовая запись каталога размером 32 байта.

Смещение Размер Описание Обязательное
0 1 Первый символ имени файла I, II Да
1 10 Следующие 10 символов имени файла I Да
11 1 Атрибуты III Да
12 1 Резерв Нет
13 1 Десятые доли секунды времени создания Нет
14 2 Часы, минуты, секунды времени создания Нет
16 2 Дата создания Нет
18 2 Дата последнего обращения Нет
20 2 Старшие 2 байта ссылки на первый кластер Да
22 2 Часы, минуты, секунды времени модификации Нет
24 2 Дата модификации Нет
26 2 Младшие 2 байта ссылки на первый кластер Да
28 4 Размер файла Да

Таб.4 Структура базовой записи каталога FAT.

Таб.5 Атрибуты.

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

HEX редактор

Продукты компании Hetman Software имеют встроенный HEX редактор, который позволяет быстро найти и просмотреть содержимое загрузочного сектора и его копии, записи FAT-таблицы, корневого каталога и области данных. Подробнее о том, как использовать эти таблицы и алгоритмы восстановления диска FAT, читайте у нас в блоге.

Maxim Cherniga

Автор: Maxim Cherniga, Технический писатель

С 1996 года начал интересоваться IT сферой, постепенно изучая и переводя свои интересы в профессиональное русло. В начале 2000-х был студентом компьютерной академии, где изучал администрирование, программирование и дизайн. В 2011 году получил высшее образование, защитив диплом по специальности «Художник компьютерной графики». Подробнее

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

Структура раздела 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 корневой каталог может быть расположен в любом месте области данных раздела и иметь произвольный размер.

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

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

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

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

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

На использование 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. Структура элемента каталога для длинного имени файла

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

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

Таблица 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)

Кроме перечисленных в таблицах 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

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

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

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

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

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

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

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

__u8 name[9]; // имя файла

__u8 ext[4]; // расширение файла

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

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

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

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

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

    1. Структура загрузочного сектора struct fat_boot_sector:
      • __s8 system_id[8] – системный идентификатор;
      • __u8 sector_size[2] – размер сектора в байтах;
      • __u8 cluster_size – размер кластера в секторах;
      • __u16 reserved – число резервных секторов в резервной области раздела;
      • __u8 fats – количество копий FAT;
      • __u8 dir_entries[2] – количество 32-байтных дескрипторов файлов в корневом каталоге;
      • __u8 sectors[2] – число секторов на разделе; если это поле равно 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[8],ext[3] – имя и расширение файла;
      • __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[10] – символы 1 – 5 имени;
      • __u8 attr – атрибуты файла;
      • __u8 alias_checksum – контрольная сумма короткого имени;
      • __u8 name5_10[12] – символы 6 – 11 имени;
      • __u8 name11_12[4] – символы 12 – 13 имени.

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

    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; // размер корневого каталога

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

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

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

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

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

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

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

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

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

    hard = open(FAT16_PART_NAME, O_RDONLY);

    Считываем первые 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);

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

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

    int fat16_read_file(__u8 *full_path, int num)

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

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

    static int i = 1;

    __u16 start_cluster, next_cluster;

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

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

    memset(tmp_name_buff, 0, SHORT_NAME);

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

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

    if(full_path[0] != "/") return -1;

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

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

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

    memcpy((void *)&sector_size, (void *)fbs.sector_size, 2);

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

    memcpy((void *)&sectors, (void *)fbs.sectors, 2);

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

    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).

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

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

    write(fat, dir_entry, root_size);

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

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

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

    memset(tmp_name_buff, 0, SHORT_NAME);

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

    for(n = 0 ; n < SHORT_NAME; n++, i++)

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

    if(split_name(tmp_name_buff, &sn) < 0)

    printf("not valid name ");

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

    printf("No such file! ");

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

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

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

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

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

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

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

    for(i = 0; i < num; i++)

    memset(tmp_buff, 0, byte_per_cluster);

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

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

    if(write(n, tmp_buff, byte_per_cluster) < 0)

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

    FAT (чаще всего в главе подразумевается FAT 16) представляет собой простую файловую систему, разработанную для небольших дисков и простых структур каталогов. Ее название происходит от названия метода, применяемого для организации файлов — таблица размещения файлов (File Allocation Table, FAT). Эта таблица размещается в начале тома. В целях защиты тома на нем хранятся две копии FAT. В случае повреждения первой копии FAT

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

    По принципу построения FAT похожа на оглавление книги, т. к. операционная система использует ее для поиска файла и определения кластеров, которые этот файл занимает на жестком диске. Изначально компания Microsoft разработала FAT для управления файлами на дискетах, и только затем приняла ее в качестве стандарта для управления дисками в MS-DOS. Сначала для дискет и небольших жестких дисков (менее 16 Мбайт) использовалась 12-разрядная версия FAT (так называемая FAT12). В MS-DOS v. 3.0 была введена 16-разрядная версия PAT для более крупных дисков. К настоящему моменту FAT 12 применяется на носителях очень малого объема (или на очень старых дисках). Например, все 3,5-дюймовые дискеты емкостью 1,44 Мбайт форматируются для FAT16, а все 5,25-дюймовые — для FAT12.

    Том, отформатированный под FAT12 и FAT16, размечается по кластерам. Стандартный размер кластера, устанавливаемый по умолчанию, определяется размером тома (более подробная информация о размерах кластеров приведена далее в этой главе). Таблица расположения файлов и ее резервная копия содержат следующую информацию о каждом кластере тома:

    Unused (кластер не используется).
    Cluster in use by a file (кластер используется файлом).
    Bad cluster (плохой кластер).
    Last cluster in a file (последний кластер файла).

    Корневая папка содержит записи для каждого файла и каждой папки, расположенных в корневой папке. Единственным отличием корневой папки от остальных является то, что она занимает четко определенное место на диске и имеет фиксированный размер (не более 512 записей для жесткого диска; для дискет этот размер определяется их объемом).

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

    Имя (в формате 8.3).
    Байт атрибутов (8 бит полезной информации, которая подробно описана ниже).
    Время создания (24 бит).
    Дата создания (16 бит).
    Дата последнего доступа (16 бит).
    Время последней модификации (16 бит).
    Дата последней модификации (16 бит).
    Номер начального кластера файла в таблице расположения файлов (16 бит).
    Размер файла (32 бита).

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

    Информация папок используется операционными системами, поддерживающими файловую систему FAT. Кроме того, Windows 2000 может хранить в записи папки дополнительную временную информацию (time stamps). Эти дополнительные временные атрибуты указывают, когда файл был создан и когда к нему в последний раз предоставлялся доступ. Главным образом, дополнительные атрибуты используются приложениями POSIX.

    Файлы на дисках имеют 4 атрибута, которые могут сбрасываться и устанавливаться пользователем — Archive (архивный), System (системный), Hidden (скрытый) и Read-only (только чтение).

    Примечание

    В Windows 2000 все файлы, имеющие комбинацию атрибутов скрытый и системный, считаются защищаемыми файлами операционной системы (operating system protected files). Windows 2000 защищает такие файлы, не отображая их в программе Проводник и папке Мой компьютер. Чтобы увидеть эти файлы в Проводнике, вызовите утилиту Свойства папки (Folder Options) (через панель управления или через меню Сервис (Tools) Проводника или папки Мой компьютер). В ее окне перейдите на вкладку Вид (View), выберите переключатель Показывать скрытые файлы и папки (Show hidden files and folders) и снимите флажок Скрывать защищенные системные файлы (рекомендуется) (Hide protected operating system files (Recommended)). Помимо этого, защищаемые файлы операционной системы можно просматривать из командной строки с помощью команды dir /a.

    В Windows NT, начиная с версии 3.5, файлы, созданные или переименованные на томах FAT, используют биты атрибутов для поддержки длинных имен файлов методом, не вступающим в конфликт с методами доступа к тому, используемыми операционными системами MS-DOS и OS/2. Для файла с длинным именем Windows NT/2000 генерирует короткое имя в формате 8.3. Кроме этого стандартного элемента Windows NT/2000 создает для файла одну или несколько дополнительных записей, по одной на каждые 13 символов длинного имени. Каждая из этих дополнительных записей содержит соответствующую часть длинного имени файла в формате Unicode. Windows NT/2000 устанавливает для дополнительных записей атрибуты тома, а также скрытого системного файла, предназначенного только для чтения, чтобы

    пометить их как части длинного имени файла, MS-DOS и OS/2 обычно игнорируют записи папок, для которых установлены все эти атрибуты, поэтому такие записи для них невидимы. Вместо этого MS-DOS и OS/2 получают доступ к файлу по стандартному короткому имени файла в формате 8.3.

    Примечание

    Windows NT/2000 и Windows 9х используют одинаковый алгоритм для генерации длинных и коротких имен файлов. На компьютерах с двойной загрузкой к файлам, созданным с помощью одной из этих операционных систем, можно получать доступ, работая под управлением другой.

    Windows NT, начиная с версии 3.5, поддерживает длинные имена файлов на томах FAT. Эту устанавливаемую по умолчанию опцию можно отключить, задав значение 1 для параметра реестра Win31FileSystem, входящего в состав следующего ключа реестра:

    HKEY_LOCAL_MACH IN E\System\CiirrentControlSet\Control\FileSystem

    Установка этого значения не позволит Windows NT создавать на томах FAT файлы с длинными именами, но не повлияет на уже созданные длинные имена.

    В Windows NT/2000 FAT16 работает точно так же, как и в MS-DOS, Windows 3.1х и Windows 95/98. Поддержка этой файловой системы была включена в Windows 2000, поскольку она совместима с большинством операционных систем других фирм-поставщиков программного обеспечения. Помимо этого, применение FAT16 обеспечивает возможность обновления более ранних версий операционных систем семейства Windows до Windows 2000.

    Примечание

    Нельзя использовать Windows NT/2000 совместно с программными средствами, осуществляющими разбиение диска на тома и сжатие дисков при помощи драйверов устройств, которые загружаются MS-DOS. Например, если требуется иметь доступ к разделу или логическому диску FAT, работая под управлением Windows NT/2000, не следует применять для них такие средства сжатия, как DoubleSpace (MS-DOS 6.0) или DriveSpace (MS-DOS 6.22). Для сканирования и восстановления томов FAT, используемых Windows NT/2000, рекомендуется ввести в командной строке команду chkdsk. Эта программа объединяет функциональные возможности, присущие программам MS-DOS Chkdsk и Scandisk, включая сканирование поверхности жесткого диска. Если требуется выполнить сканирование поверхности диска, дайте из командной строки команду chkdsk /r.

    32-разрядная файловая система FAT32 была введена с выпуском Windows 95 OSR2 и поддерживается в Windows 98 и Windows 2000. Она обеспечивает оптимальный доступ к жестким дискам, CD-ROM и сетевым ресурсам, повышая скорость и производительность всех операций ввода/вывода. FAT32 представляет собой усовершенствованную версию FAT, предназначенную для использования на томах, объем которых превышает 2 Гбайт.

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

    Таблица 7.1. Размеры кластеров по умолчанию для FAT 16 и FAT32

    Для обеспечения максимальной совместимости с существующими прикладными программами, сетями и драйверами устройств, FAT32 была реализована с минимумом возможных изменений в архитектуре и внутренних структурах данных. Все утилиты Microsoft, предназначенные для работы с дисками (Format, FDISK, Defrag и ScanDisk), были переработаны для обеспечения поддержки FAT32. Кроме того, Microsoft проводит большую работу по поддержке ведущих фирм-производителей драйверов устройств и утилит для работы с диском, чтобы помочь и в обеспечении поддержки FAT32 в их продуктах. В табл. 7.2 сделана попытка сравнения характеристик FAT16 и FAT32.

    Таблица 7.2. Сравнение характеристик FAT16 и FAT32

    Поддерживается большинством операционных систем, в числе которых MS-DOS, Windows 98, Windows NT, OS/2 и UNIX

    На текущий момент поддерживается только операционными системами Windows 98 (и Windows 98 Second Edition), Windows 95 OSR2 и Windows 2000

    Эффективна только на логических дисках, размер которых не превышает 256 Мбайт

    Не поддерживаются диски, размер которых менее 512 Мбайт

    Поддерживает сжатие диска с помощью таких утилит, как Drvspace

    Не поддерживает сжатие диска

    Ограничена по размеру до 65 525 кластеров. Каждый кластер имеет фиксированный размер в зависимости от размера логического диска. Ограничения по количеству кластеров, и их размеру (32 Кбайт) приводят к общему ограничению по размеру диска (не более 2 Гбайт). Помимо этого, FAT12/16 обычно имеет ограничения по количеству файлов и папок, которые могут содержаться в корневом каталоге (в зависимости от диска максимальное значение колеблется от 200 до 400)

    Максимальный размер кластера — 32 Кбайт, максимальный размер диска — 2 Тбайт

    Поскольку с увеличением размера диска размер кластера FAT16 увеличивается, хранение файлов на таких дисках становится неэффективным. Например, если файл размером 10 Кбайт хранится в кластере размером 32 Кбайт, то 22 Кбайт дискового пространства не используются

    Для дисков размером менее 8 Гбайт размер кластера — 4 Кбайт

    FAT32 обеспечивает следующие преимущества по сравнению с прежними реализациями FAT:

    Читайте также: