Блочные устройства
Блочные устройства — это устройства, на которых DOS может организовать файловую систему. DOS не работает напрямую с дисками через BIOS, а только с драйверами блочных устройств, каждое из которых представляется системе как линейный массив секторов определенной длины (обычно 512 байт) с произвольным доступом (для BIOS, к примеру, диск — это четырехмерный массив секторов, дорожек, цилиндров и головок). Каждому загруженному устройству DOS присваивает один или несколько номеров логических дисков, которые соответствуют буквам, используемым для обращения к ним. Так, стандартный драйвер дисков получает буквы «А», «В», «С» и так далее, по числу видимых разделов на диске.
Рассмотрим атрибуты и команды, которые передаются блочным устройствам.
Атрибуты:
бит 15: 0 (признак блочного устройства)
бит 14: поддерживаются IOCTL-чтение и запись
бит 13: не требует копию первого сектора FAT, чтобы построить ВРВ
бит 12: сетевой диск
бит 11: поддерживает команды открыть/закрыть устройство и проверить, является ли устройство сменным
биты 10 – 8: 000
бит 7: поддерживается проверка поддержки IOCTL
бит 6: поддерживается обобщенный IOCTL и команды установить и определить номер логического диска
биты 5 – 2: 0000
бит 1: поддерживаются 32-битные номера секторов
бит 0: 0
Команды и структура переменной части буфера запроса для них (только то, что отличается от аналогичных структур для символьных устройств):
00h: Инициализация
+0Dh: байт — количество устройств, которые поддерживает драйвер
+12h: 4 байта — дальний адрес массива ВРВ-структур (по одной для каждого устройства)
ВРВ — это 25-байтная структура (53 для FAT32), которая описывает блочное устройство. Ее можно найти по смещению 0Bh от начала нулевого сектора на любом диске:
+0: 2 байта — число байт в секторе (обычно 512)
+2: байт — число секторов в кластере ( DOS выделяет пространство на диске для файлов не секторами, а обычно более крупными единицами — кластерами. Даже самый маленький файл занимает один кластер)
+3: 2 байта — число секторов до начала FAT (обычно один — загрузочный)
+5: байт — число копий FAT (обычно 2) (FAT — это список кластеров, в которых расположен каждый файл, DOS делает вторую копию, чтобы можно было восстановить диск, если произошел сбой как раз при модификации FAT)
+6: 2 байта — максимальное число файлов в корневой директории
+8: 2 байта — число секторов на устройстве (если их больше 65 536 — здесь записан 0)
+0Ah: байт — описатель носителя (F8h — для жестких дисков, F0h — для дискет на 1,2 Мб и 1,44 Мб, а также других устройств)
+0Bh: 2 байта — число секторов в одной копии FAT (0, если больше 65 535)
+0Dh: 2 байта — число секторов на дорожке (для доступа средствами BIOS)
+0Fh: 2 байта — число головок (для доступа средствами BIOS)
+11h: 4 байта — число скрытых секторов
+15h: 4 байта — 32-битное число секторов на диске
(следующие поля действительны только для дисков, использующих FAT32)
+16h: 4 байта — 32-битное число секторов в FAT
+1Dh: байт — флаги
бит 7: не обновлять резервные копии FAT
биты 3 – 0: номер активной FAT, если бит 7 = 1
+1Fh: 2 байта — версия файловой системы (0000h для Windows 95 OSR2)
+21h: 4 байта — номер кластера корневой директории
+25h: 2 байта — номер сектора с информацией о файловой системе (FFFFh, если он отсутствует)
+27h: 2 байта — номер сектора запасной копии загрузочного сектора (FFFFh, если отсутствует)
+29h: 12 байт — зарезервировано
Для всех остальных команд в поле буфера запроса со смещением +1 размещается номер логического устройства из числа обслуживаемых драйвером, к которому относится команда:
01h: Проверка носителя
+0Dh: байт
на входе — описатель носителя
на выходе
0FFh — если диск был сменен
01h — если диск не был сменен
00h — если это нельзя определить
+0Fh: 4 байта — адрес ASCIZ-строки с меткой диска (если установлен бит 11 в атрибуте)
02h: Построить ВРВ
+0Dh: описатель носителя
+0Eh: 4 байта
на входе — дальний адрес копии первого сектора FAT
на выходе — дальний адрес ВРВ
03h: IOCTL-чтение (если установлен бит 14 атрибута)
04h: Чтение из устройства
+0Dh: байт — описатель носителя
+12h: 2 байта
на входе — число секторов, которые надо прочитать
на выходе — число прочитанных секторов
+16h: 2 байта — первый сектор (если больше 65 535 — здесь FFFFh)
+18h: 4 байта — на выходе — адрес метки диска, если произошла ошибка 0Fh
+1Ch: 4 байта — первый сектор
08h: Запись в устройство. Структура буфера аналогична 04h с точностью до замены чтения на запись
09h: Запись в устройство с проверкой. Аналогично 08h
0Ch: IOCTL-запись (если установлен бит 14 атрибута)
0Dh: Открыть устройство (если установлен бит 11 атрибута)
0Eh: Закрыть устройство (если установлен бит 11 атрибута)
0Fh: Проверка наличия сменного диска (если установлен бит 11 атрибута). Драйвер должен установить бит 9 слова состояния, если диск сменный, и сбросить, если нет.
13h: Обобщенный IOCTL (если установлен бит 6 атрибута)
+0Dh: байт — категория устройства:
08h: дисковое устройство
48h: дисковое устройство с FAT32
+0Eh: код подфункции:
40h: установить параметры
60h: прочитать параметры
41h: записать дорожку
42h: отформатировать и проверить дорожку
62h: проверить дорожку
46h: установить номер тома
66h: считать номер тома
47h: установить флаг доступа
67h: прочитать флаг доступа
68h: определить тип носителя (DOS 5.0+)
4Ah: заблокировать логический диск (Windows 95)
6Ah: разблокировать логический диск (Windows 95)
4Bh: заблокировать физический диск (Windows 95)
6Bh: разблокировать физический диск (Windows 95)
6Ch: определить флаг блокировки (Windows 95)
6Dh: перечислить открытые файлы (Windows 95)
6Eh: найти файл подкачки (Windows 95)
6Fh: получить соотношение логических и физических дисков (Windows 95)
70h: получить текущее состояние блокировки (Windows 95)
71h: получить адрес первого кластера (Windows 95)
+13h: адрес структуры (аналогично INT 21h AX = 440Dh)
17h: Определить логический диск (если установлен бит 6 атрибута)
+01h: байт
на входе — номер устройства
на выходе — его номер диска (1 – А, 2 – В)
18h: Установить логический диск (если установлен бит 6 атрибута)
+01h: байт — номер устройства. (Команды 17h и 18h позволяют DOS обращаться к одному и тому же дисководу как к устройству А: и как к устройству В:)
19h: Поддержка функций IOCTL (если установлены биты 6 и 7 атрибута)
Для написания своего драйвера блочного устройства можно пользоваться схемой, аналогичной символьному драйверу из предыдущей главы. Единственное важное отличие — процедура инициализации должна будет подготовить и заполнить ВРВ, а также сообщить DOS число устройств, для которых действует этот драйвер.
Содержание раздела