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

Таблица разделов диска

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

Последняя часть этого сектора содержит таблицу разделов - 4-элементную таблицу с 16-байтовыми элементами. Этой таблицей манипулирует программа FDISK (или эквивалентная утилита в иной операционной системе).

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

Таблица 1. Структура главной корневой записи и таблицы разделов

СмещениеДлинаСодержимое
000h446Корневая запись (MSB)
1BEh16Описатель раздела 1 (см. табл.2)
1CEh16Описатель раздела 2
1DEh16Описатель раздела 3
1EEh16Описатель раздела 4
1FEh2Подпись таблицы разделов (значение AA55h)

Таблица 2. Структура описателя раздела

СмещениеДлинаСодержимое
00h1Признак активности раздела (0 - не активен, 80h - активен)
01h1Номер поверхности диска, с которой начинается раздел
02h2Номер цилиндра и номер сектора, с которых начинается раздел
04h1Код раздела (см. табл.3)
05h1Номер поверхности диска, на которой заканчивается раздел
06h2Номер цилиндра и номер сектора, на которых заканчивается раздел
08h4Абсолютный (логический) номер начального сектора раздела
0Ch4Размер раздела (число секторов)

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

Таблица 3. Коды разделов операционных систем Microsoft

КодВид разделаРазмерТип FATОС
01hОсновной0-15 МбайтFAT12MS-DOS 2.0
04hОсновной16-32 МбайтFAT16MS-DOS 3.0
05hРасширенный0-2 Гбайт-MS-DOS 3.3
06hОсновной32 Мбайт-2 ГбайтFAT16MS-DOS 4.0
0BhОсновной512 Мбайт-2 ГбайтFAT32OSR2
0ChРасширенный512 Мбайт-2 ТбайтFAT32OSR2
0EhОсновной32 Мбайт-2 ГбайтFAT16Windows 95
0FhРасширенный0-2 Гбайт-Windows 95

За операционными системами других фирм зарезервированы следующие коды:

Замечания:

  1. Номера цилиндра и сектора занимают 10 и 6 бит соответственно:
    1514131211109876543210
    ccccccccccssssss

    Они упорядочены так, что, когда вы загружаете CX 16-битовым значением, оно готово для вызова прерывания INT 13h для чтения нужной порции диска. Таким образом, после чтения Главной записи загрузки в область памяти sect_buf, код
    CMP byte ptr sect_buf[01BEh], 80h

    проверит, активен ли первый раздел, а код

    MOV CX, sect_buf[01C0h]

    загрузит CX для вызова INT 13h для чтения корневого сектора раздела № 1.

  2. Значение "относительного сектора" по смещению 08h в каждом разделе эквивалентно головке, сектору и цилиндру начального адреса раздела. Относительный сектор 0 совпадает с цилиндром 0, головкой 0, сектором 1. Относительный номер сектора прирастает сначала по каждому сектору на головке, затем по каждой головке и наконец по каждому цилиндру.

    Применима формула:

    отн_сек = (#Цил * сек_на_цил * головок) + (#Гол * сек_на_цил) + (#Сек -1)

    Разделы начинаются с четного номера цилиндра, за исключением первого раздела, который может начинаться с цилиндра 0, головки 0, сектора 2 (поскольку сектор 1 занят Главной записью загрузки).

    Когда корневая запись раздела получает управление, DS:SI указывает на соответствующий элемент таблицы разделов.

Структура корневого сектора

Таблица 4. Формат корневого сектора дискеты или раздела жесткого диска

Смещ. Длина Содержимое
00h3
JMP
xx xx
NEAR-переход на код загрузки
03h8
'I'
'B'
'M'
  
'4'
'.'
'0'
OEM-имя компании и версия системы
0Bh2SectSizчисло байтов в секторе (всегда 512)начало BPB
0Dh1ClustSizчисло секторов в кластере
0Eh2ResSecsчисло резервных секторов (секторов перед FAT #1)
10h1FatCntчисло таблиц FAT
11h2RootSizчисло 32-байтовых элементов корневого каталога (для FAT32 - 0)
13h2TotSecsобщее число секторов на носителе (раздел DOS)
15h1Mediaтип носителя информации (то же, что 1-й байт FAT)
16h2FatSizeчисло секторов в одной FATконец BPB
18h2TrkSecsчисло секторов на дорожке
1Ah2HeadCnt число головок
1Ch4HidnSecчисло скрытых секторов (исп. в схемах разделения)
20h4TotSecsвсего секторов, если размер >32 Мб
24h1128физич.номер диска
25h1  резерв
26h129h признак расшир.структуры
27h4 ID тома(серийный номер)
2BhBh метка (NO NAME)
36h8 ID файловой системы (FAT12)
3Ehначало кода и данных загрузки

Замечания:

  1. Типы носителей информации:
    • F0h - гибкий диск, 2 стороны, 18 секторов на дорожке;
    • F8h - жесткий диск;
    • F9h - гибкий диск, 2 стороны, 15 секторов на дорожке;
    • FCh - гибкий диск, 1 стороны, 9 секторов на дорожке;
    • FDh - гибкий диск, 2 стороны, 9 секторов на дорожке;
    • FEh - гибкий диск, 1 сторона, 8 секторов на дорожке;
    • FFh - гибкий диск, 2 стороны, 8 секторов на дорожке.

  2. Используйте абсолютное чтение INT 25h (DX=0) для чтения этого сектора. ИЛИ:
    • гибкие диски: корневой сектор = BIOS INT 13h головка 0, дорожка 0, сектор 1;
    • жесткие: читайте Таблицу_разделов для получения BIOS головки/дорожки/сектора.

  3. BPB (BIOS Parameter Block) - подмножество данных, содержащихся в корневом_секторе. Запрос к драйверу 'Построить BPB' требует, чтобы драйвер заполнил блок, отмеченный выше. Длина BPB = 13 байт

Таблица параметров дискеты

Эта 10-байтовая структура известна также как "Disk Base Table". Она находится по адресу вектора прерывания INT 1Eh (4-байтовый адрес в 0:0078). Эта таблица задает некоторые важные переменные для устройств дискет. Ее инициализирует ROM-BIOS, а DOS модифицирует, чтобы улучшить производительность дискет.

Таблица 5. Формат таблицы параметров дискеты

СмещениеДлинаСодержимое
00h1Первый байт спецификации:
биты 0-3 - время загрузки головок;
биты 4-7 - длительность шага головок
01h1Второй байт спецификации:
бит 0 - флаг режима ПДП;
биты 1-7 - время загрузки головок
02h1Задержка перед отключением мотора (в "тиках" ситемных часов)
03h1Размер сектора (байт): 0 - 128, 1 - 256, 2 - 512, 3 - 1024
04h1Число секторов на дорожке
05h1Длина межсекторного промежутка для операций чтения/записи
06h1Длина области данных
07h1Длина межсекторного промежутка для операции форматирования
08h1Символ-заполнитель для форматирования (обычно 0F6h, т.е. 'Ў')
09h1Время установки головок (в миллисекундах)
0Ah1Время запуска мотора (в 1/8 с)

Таблица параметров жесткого диска

Эта 16-байтовая структура находится по адресу вектора прерывания INT 41h (4-байтовый адрес в 0:0104). Параметры для второго жесткого диска (если он есть) находятся по адресу вектора INT 46h. Эти таблицы задают некоторые важные переменные для операций с твердыми дисками.

Таблица 6. Формат таблицы жесткого диска

СмещениеДлинаСодержимое
00h2Число цилиндров
02h1Число головок
03h2Не используется (всегда 0)
05h2Номер начального цилиндра предкомпенсации
07h1Максимальная длина блока коррекции ошибок ECC
08h1Байт контроля:
биты 0-2 - не используются (всегда 0);
бит 3 - установлен, если число головок больше 8;
бит 4 - не используется (всегда 0);
бит 5 - установлен, если изготовитель разместил карту дефектов на цилиндре с номером "максимальный рабочий цилиндр + 1";
бит 6 - запрет повторного контроля ECC;
бит 7 - запрет контроля ECC
09h1Не используется (всегда 0)
0Ah1Не используется (всегда 0)
0Bh1Не используется (всегда 0)
0Ch2Номер цилиндра зоны парковки
0Eh1Число секторов на дорожке
0Fh1Резерв

Таблица распределения файлов (FAT)

Размер файла может изменяться со временем. Если допустить хранение файла только в смежных секторах, то при увеличении размера файла ОС должна полностью переписать его в другую подходящего объема (свободную) область диска. Чтобы упростить и ускорить выполнение операции добавления новых данных в файл, в современных ОС применяются таблицы распределения файлов (File Allocation Table, сокращенно FAT), которые позволяют хранить файл в виде нескольких несмежных участков.

При использовании FAT область данных логического диска разделена на участки одинакового размера - кластеры. Кластер может состоять из одного или нескольких последовательно расположенных на диске секторов. Число секторов в кластере должно быть кратным 2N и может принимать значения от 1 до 64 (размер кластера зависит от типа используемой FAT и объема логического диска).

Каждому кластеру поставлен в соответствие собственный элемент таблицы FAT. Первые два элемента FAT являются резервными - если на диске имеется K кластеров данных, то число элементов FAT будет равно K+2. Тип FAT определяется значением K:

  1. если K<4085 - используется FAT12;
  2. если 4084>K<65525 - используется FAT16;
  3. если 65524>K - используется FAT32.

Название типов FAT происходят от размера элемента. Так элемент FAT12 имеет размер 12 бит, FAT16 - 16 бит, FAT32 - 32 бита. Следует учитывать, что в FAT32 четыре старших двоичных разряда зарезервированы и игнорируются в процессе работы ОС (то есть значащими являются только семь младших шестнадцатеричных разрядов элемента).

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

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

Эта диаграмма иллюстрирует основные концепции FAT. Из нее видно, что:

  1. MYFILE.TXT занимает 10 кластеров. Первый кластер - это кластер 08, последний кластер - 1Bh. Цепочка кластеров - 08h, 09h, 0Ah, 0Bh, 15h, 16h, 17h, 19h, 1Ah, 1Bh. Каждый элемент указывает на следующий элемент цепочки, а последний элемент содержит специальный код (см. табл. 7).
  2. Кластер 18h помечен как дефектный и не входит в цепочку распределения.
  3. Кластеры 06h, 07h, 0Ch-14h и 1Ch-1Fh пусты и доступны для распределения.
  4. Еще одна цепочка начинается с кластера 02h и кончается кластером 05h. Чтобы узнать имя файла, нужно отыскать элемент оглавления с начальным номером кластера 02h.

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

ЗначениеFAT12FAT16FAT32
Свободный кластер000
Зарезервированный кластерFF0h-FF6hFFF0h-FFF6hFFFFFF0h-FFFFFF6h
Дефектный кластерFF7hFFF7hFFFFFF7h
Конец цепочки распределенияFF8h-FFFhFFF8h-FFFFhFFFFFF8h-FFFFFFFh
Номер кластера следующего элемента в цепочке002h-FEFh0002h-FFEFh0000002h-FFFFFEFh

FAT обычно начинается с логического сектора 1 в разделе DOS (т.е. ее можно прочитать по INT 25h с DX=1). В общем случае сначала надо прочитать корневой_сектор (DX=0) и взять смещение 0Eh. Там указано, сколько корневых и резервных секторов стоят перед FAT. Используйте затем это число (обычно 1) как содержимое DX, чтобы прочитать FAT через INT 25h.

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

Замечание:

Чтобы прочитать любой элемент FAT (следуя по цепочке), сначала прочитайте в память всю FAT и получите из оглавления начальный номер кластера. Затем, в случае FAT12:

  1. Умножьте номер кластера на 3.
  2. Разделите результат на 2 (длина элемента - 1.5 (3/2) байт).
  3. Прочитайте из FAT 16-разрядное слово, используя в качестве адреса результат предыдущей операции.
  4. Если номер элемента четный, выполните операцию AND над считанным словом и маской 0FFFh. Если номер элемента нечетный, сдвиньте значение вправо на 4 бита. В результате получите искомое значение элемента FAT.

Теперь рассмотрим порядок действий при записи элемента в FAT12.

  1. Умножьте номер кластера на 3.
  2. Разделите результат на 2 (длина элемента - 1.5 (3/2) байт).
  3. Прочитайте из FAT 16-разрядное слово, используя в качестве адреса результат предыдущей операции.
  4. Если номер элемента четный, выполните операцию AND над считанным словом и маской 0F000h, а затем операцию OR над полученным результатом и значением записываемого элемента. Если номер элемента нечетный, выполните операцию AND над считанным словом и маской 0F000h, а затем сдвиньте значение влево на 4 бита и выполните операцию OR с результатом предыдущей операции.
  5. Запишите полученное 16-разрядное слово обратно в FAT.

Замечание:

В программах, написанных на ассемблере, для выполнения умножения на 3 вместо команды MUL часто применяется алгоритм "сдвиг и сложение": исхродное число копируется, над копией числа выполняется сдвиг влево на один разряд (умножение на 2), а затем оба числа складываются (x + 2x = 3x). Вместо команды DIV используется сдвиг вправо на один разряд.

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

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

  1. корневой и резервные секторы;
  2. FAT #1;
  3. FAT #2;
  4. корневой каталог (не существует в FAT32);
  5. область данных.

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

Чтобы получить номер начального сектора кластера из номера кластера ClustNum (считанный из соответствующего поля в элементе каталога или в цепи FAT ), вы можете использовать недокументированную функцию ОС 32h или прочитать корневой сектор и применить следующие формулы:

корневых_секторов = (RootSiz * 32) / 512
начало_данных = ResSecs + (FatSize * FatCnt) + корневых_секторов
нач_сектор = начало_данных + ((ClustNum - 2) * ClustSiz),

где значения переменных: RootSiz, ResSecs, FatSize, FatCnt, ClustSiz извлекаются из корневого сектора или из BPB (см. табл.4).

Установите DX=нач_сектор перед операцией чтения INT 25h или записи INT 26h.

Каталоги файлов

Каталог файлов представляет собой массив 32-байтных элементов - описателей файлов. С точки зрения операционной системы все каталоги (кроме корневого каталога в системах FAT12 и FAT16) выглядят как файлы и могут содержать произвольное количество записей.

Корневой каталог (Root Directory) - это главный каталог диска, с которого начинается дерево подкаталогов. Для корневого каталога в FAT12 и FAT16 в системной области логического диска выделено специальное место фиксированного размера (16 Кбайт), рассчитанное на хранение 512 элементов. В системе FAT32 корневой каталог является файлом произвольного размера.

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

СмещениеДлинаСодержимое
00h11Короткое имя файла
0Bh1Атрибуты файла
0Сh1*Зарезервировано под Windows NT (должно содержать 0)
0Dh1*Поле, уточняющее время создания файла (в десятках миллисекунд).
Значение поля может находиться в пределах от 0 до 199
0Eh2*Время создания файла
10h2*Дата создания файла
12h2*Дата последного обращения к файлу для записи или считывания данных
14h2*Старшее слово номера первого кластера файла
16h2Время выполнения последней операции записи в файл
18h2Дата выполнения последней операции записи в файл
1Ah2Младшее слово номера первого кластера файла
1Ch4Размер файла в байтах (32-разрядное число)

Знак "*" означает, что поле обрабатывается только в файловой системе FAT32. В системах FAT12 и FAT16 поле считается зарезервированным и содержит значение 0.

Короткое имя файла состоит из двух полей: 8-байтного поля, содержащего собственно имя файла, и 3-байтного поля, содержащего расширение. Если введенное пользователем имя файла короче восьми символов, то оно дополняется пробелами (код пробела - 20h), если введенное расширение короче трех символов, то оно также дополняется пробелами.

Некоторые функции DOS требуют в качестве параметра байт атрибутов файла. Разряды байта атрибутов устанавливаются в 1 в том случае, если у файла имеется соответствующее свойство:

  • бит 0 - только для чтения;
  • бит 1 - скрытый;
  • бит 2 - системный;
  • бит 3 - идентификатор тома;
  • бит 4 - каталог;
  • бит 5 - архивирован;
  • биты 6 и 7 - резерв (установлены в 0).

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

ЧасМинутаСекунда/2
1511 105 40

"Секунда/2" означает двухсекундный отсчет (допустимо значение от 0 до 29).

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

ГодМесяцДень
159 85 40

При создании файлов отсчет дат ведется от начала эпохи MS-DOS, т.е. от 01.01.1980. Биты 9-15 содержат номер года минус 1980 (допустимо значение от 0 до 127).

Длинные имена файлов

Начиная с Windows 95 файлу можно присвоить (в дополнение к короткому имени) так называемое длинное имя. Для хранения длинного имени используются пустые элементы каталога, смежные с основным элементом - описателем файла. Наличие единиц в разрядах 0-3 байта атрибутов является признаком того, что свободный элемент каталога используется для хранения участка длинного имени файла (для описателей файлов и каталогов такое сочетание невозможно). Короткое и длинное имена файла являются уникальными, т.е. не должны встречаться дважды в одном каталоге.

Длинное имя записывается не ASCII-символами, а в формате Unicode, где каждому национальному алфавиту соответствует набор кодов. Расплатой за универсальность Unicode является снижение плотности хранения информации - каждый символ занимает два байта (16-разрядное слово). В пустые элементы каталога длинное имя записывается в разрезанном на кусочки виде (см. табл.9).

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

СмещениеДлинаСодержимое
00h1Номер фрагмента
01h10Первый участок фрагмента имени
0Bh1Атрибуты файла
0Ch1Байт флагов
0Dh1Контрольная сумма короткого имени
0Eh12Второй участок фрагмента имени
1Ah2Номер первого кластера (должен быть равен 0)
1Ch4Третий участок фрагмента имени

Длинное имя записывается в каталог первым, причем фрагменты размещены в обратном порядке, начиная с последнего:

(Начало каталога)
 
 
Последний фрагмент длинного имени
***
Второй фрагмент длинного имени
Первый фрагмент длинного имени
Стандартный описатель файла
***
 
(Конец каталога)

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

Блок информации диска формируется НЕДОКУМЕНТИРОВАННОЙ функцией DOS 32h.

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

Таблица 10. Схема блока информации диска

СмещениеДлинаСодержимое
00h1Номер диска (0=A, 1=B и т.д.)
01h1Номер субустройства из заголовка устройства (один драйвер может управлять несколькими дисками)
02h2Размер сектора в байтах
04h1Число секторов на кластер -1 (максим. сектор в кластере)
05h1Сдвиг кластера в сектор (кластер = 2№ секторов) (секторов на кластер в степенях двойки: 2 для 4, 3 для 8)
06h2Число резервных секторов (корневые, начало корневого огл.) (N первого сектора FAT)
08h1Число таблиц FAT
09h2Макс. число элементов в корневом оглавлении
0Bh2Номер сектора для кластера №2 (1-й кластер данных)
0Dh2Всего кластеров +2 (наивысший номер кластера)
0Fh1Число секторов, занимаемое одной FAT
10h2Номер сектора начала корневого оглавления
12h4Адрес заголовка_устройства
16h1Байт дескриптора_носителя
17h1Флаг доступа: 0, если был доступ к устройству
18h4Адрес следующего блока информации диска
(0FFFFh, если блок - последний)

Битовые флаги режима открытия:

  1. 0-2: Права доступа процесса в сети
    000 - чтение; 001 - запись; 010 - чтение и запись.
  2. 4-6: Режим разделения:
    000 - режим совместимости
    001 = монопольный захват файла
    010 = отвергать запись
    011 = отвергать чтение
    100 = ничего не отвергать
  3. 7: Наследование:
    1 - файл приватный для этого процесса 0 - наследуется порожденными процессами

Если байт атрибутов файла индицирует только чтение, он перекрывает эти флаги.

Биты прав доступа в сети и режима разделения имеют эффект только в том случае, когда установлена программа SHARE.

Оглавление


© Колесников Дмитрий Геннадьевич Rambler's Top100 Учебник по СайтоСтроению