Программирование

Как правильно рассчитать BPB для FAT32: формулы и пример

Руководство по созданию BPB для FAT32: расчёт BPB_FATSz32, BPB_TotSec32, BPB_RootClus и связанных полей. Формулы, пример для 128 МБ и ссылки на спецификации.

Как правильно определить BIOS Parameter Block (BPB) для FAT32?

Я искал в интернете полный пример BIOS Parameter Block (BPB) для FAT32, но большинство ресурсов только объясняют, что такое BPB, без предоставления практических примеров. Хотя я успешно создал BPB для FAT12, следуя урокам на BrokenThorn.com, у меня возникают трудности при адаптации его для FAT32.

Я понимаю, что FAT12 и FAT32 имеют много общих полей BPB, но мне нужно уточнить значения, специфичные для FAT32:

  • Какое количество секторов на FAT должно быть для FAT32?
  • Как определить общее количество секторов на диске FAT32?
  • Какие поля, специфичные для FAT32, отличаются от FAT12?

Более общим образом, я хотел бы понять процесс написания правильного BPB для любой файловой системы:

  • Как вычислять значения, такие как количество секторов или секторов на FAT?
  • Где можно найти надежную документацию или инструменты для определения этих полей?
  • Какие стандартные ссылки или спецификации обычно используют разработчики ОС?

Я хочу понять процесс создания правильного BPB с нуля, а не просто копирования значений. Я пытался повторно использовать мой BPB для FAT12 с измененными значениями для FAT32, но при использовании acopy для записи файлов в образ диска, некоторая информация о файлах записывается в область FAT вместо корневого каталога.

Любые рекомендации, работающие примеры или ресурсы будут очень признательны.

BIOS Parameter Block (BPB) для FAT32 — это фундаментальный блок, который описывает структуру файловой системы на диске. Чтобы правильно рассчитать сектора на FAT (BPB_FATSz32), используйте формулу: количество секторов = ceil((количество кластеров × 4 байта) / размер сектора), с учётом двух копий FAT. Общее количество секторов (BPB_TotSec32) просто равно размеру диска в секторах, а специфичные для FAT32 поля — это BPB_FATSz32, BPB_RootClus (обычно 2) и BPB_FSInfo (1), где корневой каталог размещается как цепочка кластеров, а не фиксированный сектор.


Содержание


Что такое BPB и зачем он нужен в FAT32

BPB, или BIOS Parameter Block, — это первые 90 байт (для FAT32) загрузочного сектора, где хранятся метаданные о файловой системе. Без правильного BPB ваш диск не распознается ни ОС, ни утилитами вроде acopy. Представьте: вы пишете образ, а файлы улетают в FAT вместо каталога — классическая ошибка из-за неверных расчётов.

Почему это критично для FAT32? В отличие от FAT12, где всё компактно, FAT32 работает с огромными дисками. Тип определяется не жёстко, а по количеству кластеров: если их больше 65525, то FAT32. Официальная спецификация Microsoft подчёркивает, что BPB должен точно отражать геометрию диска, иначе цепочки файлов порвутся.

А вы пробовали dumpe2fs или hex-редактор на образе? Там сразу видно, если BPB кривой.


Общие поля BPB: от FAT12 к FAT32

Большинство полей BPB наследуются от FAT12/16 — первые 36 байт почти идентичны. Вот ключевые:

  • BPB_BytsPerSec: Размер сектора, обычно 512 байт (0x0200). Фиксировано для большинства дисков.
  • BPB_SecPerClus: Секторов в кластере — степень двойки (1, 2, 4, 8…). Для маленьких дисков 1, для больших — 8 или 16.
  • BPB_RsvdSecCnt: Зарезервированные сектора перед FAT, минимум 1, рекомендуется 32 для FAT32.
  • BPB_NumFATs: Количество копий FAT, всегда 2.
  • BPB_Media: Тип носителя (0xF8 для жёстких дисков).
  • BPB_TotSec16: Общее кол-во секторов для малых дисков (<32 МБ), но в FAT32 используйте BPB_TotSec32.

Если вы адаптируете из FAT12, просто скопируйте эти поля, но пересчитайте всё под размер диска. BrokenThorn.com даёт хорошую базу для FAT12, но там нет FAT32-нюансов.

Проблема с acopy часто в BPB_RootEntCnt — для FAT32 оно 0, иначе каталог “съедает” место в FAT.


Специфичные поля BPB для FAT32

FAT32 добавляет расширенный блок (EBPB) — 28 байт после базовых 36. Вот отличия от FAT12:

Поле Описание Значение для FAT32 Отличие от FAT12
BPB_FATSz16 Сектора на FAT (2 байта) 0 В FAT12/16 — используется
BPB_FATSz32 Сектора на FAT (4 байта) Рассчитывается Новое, ключевое
BPB_ExtFlags Флаги FAT (активная копия) 0 Новое
BPB_FSVer Версия FS 0 Новое
BPB_RootClus Первый кластер корня 2 В FAT12 — фиксированный каталог
BPB_FSInfo Сектор FSInfo 1 Новое
BPB_BkBootSec Резервный загрузчик 6 Новое

Документация ChaN подробно разбирает: в FAT32 корневой каталог — не фиксированный, а цепочка от кластера 2. BPB_RootEntCnt=0, RootDirSectors=0. Это решает вашу проблему с acopy — файлы идут в правильное место.

Ещё нюанс: BPB_DrvNum (0x80), BPB_BootSig (0x29), BPB_VolID (серийный номер).


Расчёт секторов на FAT (BPB_FATSz32)

Это сердце проблемы. Каждый кластер в FAT32 занимает 4 байта (32-битный указатель).

Формула из Microsoft spec:

  1. DataSec = TotSec - RsvdSecCnt - (NumFATs × FATSz32) (но FATSz циклически)

Упрощённо по ChaN:

\text{BPB_FATSz32} = \left\lceil \frac{\text{ClusterCount} \times 4}{\text{BPB_BytsPerSec}} \right\rceil

Сначала оцените ClusterCount:

DataSectors = TotSec - RsvdSecCnt - (NumFATs × FATSz32) (итеративно)

Практика: для диска 128 МБ (262144 сектора по 512 B):

  • SecPerClus=4 → кластер 2 КБ
  • Rsvd=32, NumFATs=2
  • Предположим FATSz32=532 → DataSec = 262144 - 32 - (2×532) = 260996
  • ClusterCount = 260996 / 4 = 65249 (>65525? Подкорректируйте)

Точный алгоритм Microsoft:

TmpVal1 = TotSec32 - RsvdSecCnt

TmpVal2 = (256 × SecPerClus) + NumFATs

FATSz32 = ceil(TmpVal1 / TmpVal2)

Для FAT32 делим TmpVal2 на 2. Итеративно подгоните.

OSDev Wiki советует начинать с 1 сектора FAT на 384 кластера.

Не копируйте слепо — всегда проверяйте hex-дампом.


Определение общего количества секторов (BPB_TotSec32)

Проще некуда: BPB_TotSec32 = размер диска в байтах / BPB_BytsPerSec.

Для образа 32 МБ (33554432 байт, сектор 512) = 65536 секторов (0x10000).

Но! Это весь диск, включая неиспользуемые сектора в конце. FAT использует только до FirstDataSector + DataSectors.

FirstDataSector = RsvdSecCnt + (NumFATs × FATSz32)

Корень начинается с кластера BPB_RootClus (2), в FirstDataSector + (2-2)×SecPerClus.

Если TotSec32 маловато для FAT32 (<~268 МБ), система может fallback на FAT16. Для вашего 32 МБ-образа увеличьте до 128 МБ — тогда кластеров хватит.

Проверяйте: mke2fs или fatlabel покажут реальные значения.


Полный пример BPB для FAT32 на 128 МБ

Возьмём диск 128 МБ (268435456 байт), сектор 512 B, SecPerClus=4.

Из Microsoft PDF, пример:

Офсет Тип Поле Значение (hex)
03h WORD BPB_BytsPerSec 200h (512)
0Bh BYTE BPB_SecPerClus 04h
0Eh WORD BPB_RsvdSecCnt 0020h (32)
10h BYTE BPB_NumFATs 02h
11h WORD BPB_RootEntCnt 0000h
13h DWORD BPB_TotSec32 042A92h (~268 МБ)
24h DWORD BPB_FATSz32 00214h (532 сектора)
2Ch WORD BPB_ExtFlags 0000h
2Eh WORD BPB_FSVer 0000h
30h DWORD BPB_RootClus 00000002h
34h WORD BPB_FSInfo 0001h
36h WORD BPB_BkBootSec 0006h
... (остальное стандарт)

ClusterCount ≈ 65249. Запишите в образ dd или hexedit, mkfs.fat -F32 образ.img, протестируйте acopy.

Работает? Файлы в /, не в FAT.


Общий процесс создания BPB с нуля

Шаги, чтобы не мучаться:

  1. Выберите геометрию: BytsPerSec=512, SecPerClus=потому что размер диска (1 для <1MB кластера).
  2. TotSec32 = disk_size / 512.
  3. Итеративно: предположите FATSz32= TotSec32 / 200, вычислите DataSec, ClusterCount=DataSec/SecPerClus.
  4. Если ClusterCount >65525 — ок для FAT32, уточните FATSz32=ceil(ClusterCount*4/512).
  5. Заполните поля, обнулите FATSz16=0, RootEntCnt=0.
  6. FSInfo в секторе 1: свободные кластеры, следующий свободный.
  7. Тестируйте: hexdump -C образ.img | head, mount или acopy.

Инструменты: mkfs.fat (Linux), fat32format (Win). Доки: ChaN, Microsoft, OSDev.

Разработчики ОС юзают эти + UEFI spec. Нет магии — математика + итерации.


Источники

  1. FAT - OSDev Wiki
  2. FAT Filesystem by ChaN
  3. Microsoft FAT Specification (PDF)
  4. BIOS parameter block - Wikipedia
  5. Design of the FAT file system - Wikipedia
  6. Overview of FAT32

Заключение

Правильный BPB для FAT32 строится на точных расчётах секторов на FAT и общего количества секторов, с фокусом на итеративный подход для ClusterCount. Изучите примеры из Microsoft и ChaN — они спасут от ошибок вроде смещения файлов в FAT. Начните с малого образа, тестируйте acopy, и вы освоите процесс для любой FS. Удачи с образом!

Авторы
Проверено модерацией
Модерация
Как правильно рассчитать BPB для FAT32: формулы и пример