Больной вопрос о файловой системе... Решено использовать файловую систему
MS-DOS - fat12. На первых порах нам ее хватит. Поддержка длинных имён
(vfat) будет развита потом.
Прежде, чем говорить о каталогах, давайте рассмотрим структуру
диска файловой системы FAT12:
|
Структурная единица
|
Описание
|
|
Boot Sector
|
- загрузочный сектор
|
|
|
таблица 12-битных значений, значений кластеров
|
|
FAT (копия)
|
|
Корневой каталог
|
набор структур DirEntrtyRec
|
|
Данные
|
Остальные данные: каталоги, файлы. На эти данные
ссылаются единицы корневого каталога
|
Итак, когда мы создаем на диске каталог, под этот каталог выделяется
1 кластер. По мере заполнения кластера каталог наращивается. Корневой
каталог не растет, он строго ограничен в размере. Кластер - это группа
(или один) секторов.
При работе с диском, с файловой системой нужно осуществлять
некоторые подсчеты. Наиболее важные формулы отображены здесь. Чтение диска
осуществляется в таком порядке: сначала считываются все сектора данного
цилиндра первой головкой дисковода, затем второй, после чего происходит
перемещение на следующий цилиндр. Позиция головки задается значениями
CHS(цилиндр, головка, сектор). Но при работе с кластерами оперируют абсолютными
значениями сектора, т.е. задается только номер сектора от 0.
Абсолютный номеp сектоpа вычисляется по фоpмуле:
AbsSectNo =
(CylNo * SectPerTrack * Heads) + (HeadNo * SectPerTrack) + (SectNo - 1)
Обpатное:
CylNo = AbsSectNo / (SectPerTrack * Heads)
HeadNo = остаток / SectorPerTrack
SectNo = остаток + 1
ABS=absolute sector
CLUSTER=cluster number
C,H,S = cylinder, head, sector
CM, SH, AC = дополнительные переменные
AbsDataSector = абсолютный сектор начала области данных (для FAT12,
FAT16)
----
ABS=AbsDataSector+((CLUSTER-2)*bClustSects)
SH=(sec_per_track*heads_count)
С=ABS/SH
CM=C*SH
AC=(ABS-CM)
H=AC/sec_per_track
S=AC-(H*sec_per_track)+1
Отсюда имеем:
|
C=ABS/SH
H=reminder/sec_per_track
S=reminder+1
|
Где reminder - остаток от деления.
Загружается вся таблица в память.
PTR=указатель на таблицу
CLUSTER=требуемый кластер
VAL=значение
VAL=(CLUSTER*3)/2 + PTR
Если VAL чётное, то VAL=VAL&0x0FFF, если нечетное, то
VAL=VAL>>4
Вот формулы для нахождения нужных областей диска:
ReservedRegion = VolumeStart
FATRegion = ReservedRegion + ReservedSectors
RootDirectoryRegion = FATRegion + (NumberOfFATs * SectorsPerFAT)
DataRegion = RootDirectoryRegion + ((RootEntiesCount * 32) / BytesPerSector)
ReservedRegion_Size = ReservedSectors
FATRegion_Size = NumberOfFATs * SectorsPerFAT
RootDirectoryRegion_Size = (RootEntiesCount * 32) / BytesPerSector
(Не забудьте округлить!)
DataRegion_Size = (TotalNumberOfSectors - (ReservedRegion_Size
+ FATRegion_Size + RootDirectoryRegion_Size)) / SectorsPerCluster
First sector of cluster N = DataRegion + ((N - 2)
* SectorsPerCluster)
Здесь:
ReservedRegion - это сектор, с которого начинается зарезервированная
область
FATRegion - это область, где начинаются все таблицы размещения файлов
RootDirectoryRegion - облать корневого каталога
DataRegion - область данных (описанная в FAT)
Загр. сектор имеет особый формат. Сначала следует заголовок, потом программа,
а затем последовательность байт: 55h, AAh.
|
Смещение
|
Размер
|
Название
|
Описание
|
|
+0
|
3
|
abJmpCode
|
Инструкция Jmp на начало кода
|
|
+3
|
8
|
abOem
|
'MSDOS6.0' или др.
|
|
+0Bh
|
2
|
wSectSize
|
размер сектора в байтах
|
|
+0Dh
|
1
|
bClustSects
|
Количество секторов на единицу распределения (кластер),
т.е. размер кластера в секторах
|
|
+0E
|
2
|
wResSects
|
Загрузочный и зарезервированные сектора (кол-во)
|
|
+10h
|
1
|
bFatCnt
|
Количество таблиц размещения файлов
|
|
+11h
|
2
|
wRootEntries
|
Максимальное число 32-байтовых записей DirEntryRec
в корневом каталоге
|
|
+13h
|
2
|
wTotSects
|
Общее число секторов на носителе.
Значение 0000h означает, что раздел
объёмом выше, чем 32МБ. Тогда значение надо считывать с lBigTotSects.
|
|
+15h
|
1
|
bMedia
|
Media Descriptor.
F8h - жёсткий диск, остальные знаения (F0, F9, FA,
FB, FC, FD, FE, FF) означают формат гибкого диска.
|
|
+16h
|
2
|
wFatSects
|
Число секторов на одну таблицу размещения файлов
(FAT)
|
|
+18h
|
2
|
wSectsPerTrk
|
Число секторов на один трек (цилиндр)
|
|
+1Ah
|
2
|
wHeads
|
Число записывающих/считывающих головок
|
|
+1Сh
|
4
|
lHidSects
|
Скрытые сектора
|
|
+20h
|
4
|
lBigTotSects
|
32-bit число секторов на разделе большем, чем 32МБ
|
|
+24h
|
1
|
bDrvNo
|
80h - первый жесткий диск (используется внутри MS-DOS)
|
|
+25h
|
1
|
res1
|
Зарезервировано
|
|
+26h
|
1
|
bExtBootSig
|
Дополнительная подпись, всегда равна 29h
|
|
+27h
|
4
|
lSerNo
|
Volume Serial Number
|
|
+2Bh
|
11
|
abVolLabel
|
Метка тома, 11 символов, дополненых пробелами, если
необходимо
|
|
+36h
|
8
|
abFileSysID
|
'F','A','T','1','2',32,32,32
|
Вся структура занимает 62 байта.
Файл или каталог обозначается структурой(записью)DirEntryRec:
|
Смещение
|
Размер
|
Название
|
Описание
|
|
+0
|
8
|
abName
|
Имя файла, выровненное влево, остаток заполнен пробелами (20h)
Самый первый символ имени имеет особое значение:
|
Значение
|
Описание
|
|
0
|
Запись еще не использовалась
|
|
5
|
Первый символ 0E5h
|
|
2Eh
|
Это ссылка на каталог (.=сам,
..=родитель)
|
|
E5h
|
Запись удалена
|
|
|
+8
|
3
|
abExt
|
Расширение, выровненное влево, остаток заполнен
пробелами
|
|
+0Bh
|
1
|
bAttr
|
Атрибуты (FileAttrRec)
|
|
+0Ch
|
10
|
res
|
Зарезервировано
|
|
+16h
|
2
|
rTime
|
Время создания/изменения (FileTimeRec)
|
|
+18h
|
2
|
rDate
|
Дата создания/изменения (FileDateRec)
|
|
+1Ah
|
2
|
wClstrNo
|
Номер кластера начала файла в FAT
|
|
+1Ch
|
4
|
lSize
|
Длинна файла до 4ГБ
|
Размер структуры - 32 байта.
|
Бит
|
Значение
|
|
0
|
Read-only (Файл не может быть удалён или изменён)
|
|
1
|
Hidden (Невидимый)
|
|
2
|
System (Системный)
|
|
3
|
Volume label entry (?)
|
|
4
|
subDirectory entry - подкаталог
|
|
5
|
Archive (1=file has not been backed up) Устанавливается
дла архивации файла (?)
|
|
6
|
зарезерв.
|
|
7
|
зарезерв.
|
|
Биты
|
Маска
|
Значение
|
|
0-4
|
001Fh
|
Секунды/2 (0-29)
|
|
5-10
|
07E0h
|
Минуты (0-59)
|
|
11-15
|
F800h
|
Часы (0-23)
|
|
Биты
|
Маска
|
Значение
|
|
0-6
|
007Fh
|
Год от 1980 (0-127)
|
|
7-10
|
0780h
|
Месяц (1-12)
|
|
11-15
|
2800h
|
День (1-31)
|
|