Описание файловой системы FAT16

matrix

 

Пару слов, перед описание файловой системы FAT16…

 

 

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

Возможно вы думаете: «что файловая система это сложная и непонятная штука, ведь с ней работают операционные системы, а там все просто быть не может…»

Частично вы правы, но весь изюм находиться в драйвере файловой системе, т.е. в программе, которая предоставляет API для остальных прикладных программ. Она  как раз и выполняет такие действия как:

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

Сам принцип организации файловой системы прост.

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

(про то, как написать драйвер, есть отдельный пост)
 

Почему FAT16? 

Я считаю её наиболее удобной для обучения, её легко осмыслить. А зная идею, уже не сложно изучать другие файловые системы — FAT32, NTFS, и т.п.

 

Зачем мне нужно знать как устроена файловая система?

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

 

 

Описание файловой системы FAT16

 

Для удобного ориентирования по посту, я приведу список вопросов, на которые вы найдете ответы:

 

Файловая система FAT16 делит все адресное пространство носителя на две области:

  • системную область
  • область данных

 

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

 

structure_FAT16

 

Все данные, которые мы храним на своем носителе, т.е. все файлы и каталоги — хранятся в области данных. Системная же область, хранит параметры данного носителя и характеристики файлов и директорий – имя файла, имя директориии, атрибуты файла и т.п.

 

Начнем с простого, пару слов про область данных и как там хранятся данные

 

Про область данных …

 

Чтобы не адресовать каждый байт (хотя некоторые носители информации позволяют работать и побайтно) в файловой системе используют другую минимальную адресуемую единицу – сектор. Размер сектора 512 байт. Помимо сектора файловая система FAT16 использует еще такое понятие как кластер. Кластер это один или несколько расположенных подряд секторов.

Этим параметром (число секторов на кластере) часто манипулируют при форматирование носителей информации. Т.к. от него зависит скорость работы и «степень упаковка данных». FAT16 как и все файловые системы использует такое понятие как файл. Файл это область данных имеющая имя и некоторые атрибуты. Физически в области данных это один или несколько занятых кластеров, причем файл занимает целое число кластеров. Даже, если он занимает чуть больше чем два кластера для файловой системы занятых под файл будет считаться три кластера. Поэтому, чем меньше размер кластера, тем больше «степень упаковки данных» и экономичнее используется область данных. С другой стороны, считывать файл из больших кусков памяти т.е. кластеров быстрее, чем из мелких. Поэтому, выбор размера кластера это дело компромисса.

Файловая система FAT16 накладывает ограничения на размер кластера, не более 128 секторов (т.е. не более 64 кб) и на количество кластеров не более 65525 штук. Если использовать все по максимум, т.е. максимальные размер секторов и максимальное количество кластером, то выходит что FAT16 не может адресовать больше чем 4.2 гигабайта информации.

 

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

 

 

Про системную область …

 

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

 

structure_fat16_2

 

 

Разберем каждую часть подробнее

 

 

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

 

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

 

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

boot_sector_param

 

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

 

Если посмотреть HEX код, какого-нибудь носителя информации отформатированного в формате FAT16, то мы увидим значение полей. В качестве примера я приведу HEX код образа в формате FAT16 созданного в WinImage. Для удобства ориентирования по коду, я пометил цветами какой фрагмент HEX кода к какому параметру относиться.

 

HEX_Example_1

 

P.S. Значение для каждой ячейки считаются справа налево, например если написано 00 02h, то на самом деле это 02 00h, т.е. 512 в десятичной системе исчисления.

 

boot_sector_param_2

P.S. Загрузочный сектор всегда заканчивается 55AAh.

 

Важно обратить внимание на параметр «ReservedSectors» — количество зарезервированных секторов, по смещению 0Eh. В самом начале, я говорил, что загрузочный сектор обычно имеет размер 512 байт, но может быть и больше. Определяется его размер параметром «ReservedSectors», в нашем случае ReservedSectors = 01h, значит загрузочный сектор занимает 1-ин сектор или 512 байт.

 

 

2. FAT

 

После загрузочного сектора с размером 512* ReservedSectors байт, идет таблица FAT1, её размер определяется двухбайтовым полем — SectorPerFat (16h) загрузочного сектора. В примере выше значение данного поля равняется 0001h или 1, т.е. один сектор или 512 байт.

Что такое FAT?

Первым делом это аббревиатура – File Allocation Table, означающая «таблица расположение файлов». Это таблица с одним столбцом и 512/2 количеством строк (если размер таблицы FAT – 512 байт или SectorPerFat равен 0001h, как в нашем случае). Каждая строка таблицы FAT занимает 2 байта памяти, поэтому количество строк для нашего случая это 512/2.

Таблица служит в роли карты по кластерам, каждая её строка характеризует какой либо кластер, первая строка – первый кластер, вторая – второй и так для всех кластеров, что есть в области данных. Перед таблицей стоит дескриптор таблицы F8FFh (то же значение, что и в 15h загрузочного сектора) и заполнитель FFFFh. Далее идут строки таблицы, значения которых могут быть следующие:

  • 0000h — свободный кластер;
  • 0002h-FFEFh — номер следующего элемента в цепочке;
  • FFF0h-FFF6h — зарезервированный;
  • FFF7h — дефектный;
  • FFF8h-FFFFh — последний в цепочке;

 

Приведу пример HEX кода с пояснением.

Синей рамкой я обозначил таблицу FAT1, красной таблицу FAT2 (копия таблицы FAT1). Закрашенный зеленый квадратик это дескриптор таблицы F8FFh и заполнитель FFFFh. Не закрашенные квадратики, это строки таблицы. Я не стал обозначать все строки зеленой рамкой, обвел только не нулевые.

 

HEX_Example_2

Как применяется и зачем нужна FAT, я объясню чуть позже.

 

 

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

 

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

 

Размер корневого каталога зависит от параметра RootEntries (11h) загрузочного сектора. В нем указывается максимальное число 32-ух байтных элементов в корневом каталоге. Выходит размер каталога это RootEntries * 32, для нашего случая это 512 * 32 = 16384 байт.

 

Каждый элемент имеет следующую структуру:

 

root_dir_param

 

Приведу пример HEX кода с пояснением.

 

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

 

HEX_Example_3

 

 

Здесь два не пустых 32-ух байтных элемента, значит, в корневом каталоге храниться два «чего-то», это могут быть как файлы так и другие каталоги. В данном случае для простоты примера в корне храниться два файла «1.txt» и «test.txt».

Рассмотрим поближе этих два 32-ух байтных элемента, для удобства я отметил цветами фрагмент HEX кода и соответствующий параметр 32-ух байтного элемента в таблице.

 

root_dir_param_2

 

P.S. Если первый байт имени файла заменить на «E5», то проводник Windows будет считать его как удаленный. Такой файл возможно восстановить, заменив первый символ E5 в имени на прежнее значение. Не уверен до конца, но думаю, что так работает корзина в Windows. Помещая в корзину, операционная система сохраняет, где-то имя файла и заменяет первый байт в имени на E5, а при восстановление присваивает файлу прежнее имя.

 

P.S. Имена файлов в системе FAT16 хранятся в формате 8.3. Т.е. 8-байтов выделено для имени и 3-и байта выделено для расширения. Имена кодируются в формате ASCII, один символ это один байт. Поэтому имя не может иметь длину больше чем 8-емь символов, а расширения больше 3-ех. Если имя короче 8-и символов, то недостающие байты заполняются 20h (знак пробела в ASCII коде).

 

P.S. Напомню, что значение для каждой ячейки считается справа налево, например если написано 00 02h, то на самом деле это 02 00h, т.е. 512 в десятичной системе исчисления.

 

root_dir_param_3

 

Самый важный для нас параметр находится по адресу 1Аh — «младшее слово первого кластера файлов». В нем храниться номер кластера, в котором находиться содержимое файл, а это значит мы можем работать с информацией данного файла, т.е. считывать, редактировать его и т.п.

Например «1.txt» храниться в кластере номер 0x0003 или 3 в десятичной системе исчисления. А это значит, что если мы перейдем к кластеру №3 в области данных (напомню, область данных это просто подряд идущие кластеры) мы попадем к содержимому данного файла.

 

У вас может возникнуть «практический» вопрос, а как найти этот третий кластер? По какому адресу он находиться?

 

 

Как найти адрес кластера зная его номер?

 

Для этого, вам нужно знать какой объем у вас занимает системная область и какого размера кластеры (т.е. сколько секторов (или 512 байт) содержит в себе кластер).

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

 

structure_fat16_3

 

Пример для моего случая

Загрузочный сектор имеет объем 512*ReservedSectors байт, в моем случае 512 байт. Далее, таблица FAT у меня занимает один сектор, т.е. 512 байт (т.к. SectroPerFat равен 1). Таблицы две (т.к. NumberOfFATs равен 2), значит две таблицы в сумме 512*2=1024 байт. Размер корневого каталога 512-ть 32-ух значных элементов, т.е. 512*32=16384 байт. Считаем:

512 (загрузочный сектор) + 1024 (две таблицы FAT) + 16384 (корневой каталог) = 17920 байт или 4600 в шестнадцатеричной системе исчисления.

 

В итоге, в нашем случае область данных начинается с 0x4600, посмотрим:

 

HEX_Example_4

 

 

Мы видим содержимое, какого то файла, но не нашего. Данные интересующего наc файла (1.txt) хранятся в кластере №3.

 

Теперь нужно узнать размер кластера, в этом нам поможет параметр загрузочного сектора – SectorPerCluster (0xD, размер параметра 1 байт). В нашем случае размер кластера 4-е сектора, т.е. 512*4=2048 байт или 800 в шестнадцатеричной системе исчисления. Важно заметить, что кластеры нумеруются с двойки, а не с единицы (!).

 

Подсчитываем, с какого адреса начинается кластер №3:

0x4600 (системная область) + 0x800 (второй кластер) = 0x4E00

 

Подсчитываем, по какому адресу кончается кластер №3:

0x4E00 (начало кластера №3) + 0x800 (512*4 или размер одного кластера в HEX) = 0x5600

 

В результате кластер №3 лежит в диапазоне адресов 0x4E000x5600.

 

Посмотрим HEX код

HEX_Example_5

 

Синий рамкой я обозначил содержимое файла 1.txt. Все, что выше рамки — содержимое другого файла. Пустые области сектора заполняются 0x00.

 

 

Так зачем нужна таблица FAT?

 

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

Если строка имеет значение 0xFF8-0xFFFF, то это значит, что это последний кластер для данного файла, т.е. файл занимает всего один кластер.

Если строка имеет значение 0x0002-0xFFEF, то это означает, что файл растянулся на еще один кластер. Цифра означает номер следующего кластера, в котором храниться продолжение файла. Мы должны продолжить считывать файл по данному номеру кластера.

После считывания нового кластера, нужно посмотреть значение строки по данному номеру в FAT. Если значение строки равно 0x FF8-0xFFFF, то это значит, что данный кластер последний в файле. Если 0x0002-0xFFEF, то это номер для следующего кластера, считываем дальше и повторяем действие. Считывание файла это цикл с условием.

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

 

 

Что такое директория?

 

Директория для файловой системы FAT16 (да и для многих других) это особый файл с нулевым размером хранящий список своего содержимого.

 

Допустим, мы добавили в наш образ FAT16 директорию «TEST_DIR» c файлом «in_dir.txt». Тогда в корневом каталоге появиться новый 32-ух байтный элемент, он описывает директорию также как и файл, но с небольшими отличиями.

 

Я отметил красным параметры характерные для директорий, это 0x10 – метка каталога и 0x00000000 — размер файла.

 

HEX_Example_6

 

Как видно в синем квадрате, директория у нас лежит в кластере №5, посмотрим что там.

 

HEX_Example_7

 

 

Содержимого «файла» TEST_DIR по сути, это тот же корневой каталог, т.е. набор 32-ух байтных элементов. Я обозначил каждый элемент зеленой рамкой.

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

 

 

HEX_Example_8

 

 

Первый лежит в кластере №5, т.е. это тот же самый каталог, а второй на кластер номер №0. Под этим номером понимается «корневой каталог», т.е. это выход в корневой каталог.

 

Описание файла «in_dir.txt» стандартное, как и для корневого каталога (см. корневой каталог). Для нас главное, это номер кластера в котором находиться содержимое данного файла (обозначил красным квадратом).

 

HEX_Example_9

 

 

Смотрим кластер №6 и видим содержимое файла «in_dir.txt». Красной линей я обозначил начало кластера.

 

HEX_Example_10




Буду признателен если вы поделитесь данным постом

Комментарии
  1. Рафаил пишет:

    Сперва надо выразить признательность за такую относительно доходчивую статью. Не каждый ещё так сможет рассказывать.
    Спасибо!

    Но откуда эти цифры:
    не более 128 секторов на кластер
    и не более 65’525 кластеров в разделе?
    Кто это сказал? И где это указывается?

    Количество секторов на кластер — это 2-хбайтовое число,
    т.е. возможен максимум: 2^16=65’536-1(нулевое значение)=65’535 секторов.

  2. admin пишет:

    Спасибо за приятные слова, значит, все что я делаю не зря)

    Данный пост, я писал 2-а года назад, честно говоря я уже не смогу найти источник. Рафаил, вы ошиблись, количество секторов на кластер это однобайтовое число (см. таблицу в посте).
    Технически максимум должен быть 255, но здесь 128, я точно не помню, но это ограничение я встречал повсюду.

    Например от майкрасофта https://support.microsoft.com/ru-ru/kb/310561, там пишут что максимальный размер кластера 64кб (по расчетам это 128 секторов).
    Или посмотрите документ «Microsoft Extensible Firmware Initiative FAT32 File System Specification», в нем как раз описывается структура файловых систем FAT12,FAT16,FAT32, посмотрите страницу 9 и 21. На 9-ой странице как раз написано что максимальное значение для SecPerCluster это 128.

    Я не знаю чем это вызвано.

  3. Станислав пишет:

    Спасибо за отличную статью. Вроде бы у всех одинаково написано, а у вас Понятно!

  4. admin пишет:

    Добрый день Станислав!

    Мне это приятно слышать, вкладываю душу в посты)
    Я всегда рад вас видеть, если будут проблемы обязательно обращайтесь =)

  5. Алексей пишет:

    Замечательная статья.Автор настоящий Учитель-Мастер-Сэмпай. Так держать и огромное спасибо! Сам перелопатил море информации в инете, нигде более внятного доходчивого и понятного объяснения не встречал. Да ещё и с примерами! Я в восторге!… *пошёл записываться к вам в ученики*…

  6. admin пишет:

    Спасибо Алексей за теплые слова! Буду стараться дальше)
    Я поставил себе цель, что нужно делать записи таким образом, которые будут понятные мне позже, при условии что я забуду мелочи.

  7. Thanks пишет:

    Крутая статья. Пасиб!!

  8. admin пишет:

    Спасибо вам за посещение =)



Ваш комментарий


Ответ в цифрах

 
© s-engineer.ru, 2012-2017 | Все права защищены