Меню
  Список тем
  Поиск
Полезная информация
  Краткие содержания
  Словари и энциклопедии
  Классическая литература
Заказ книг и дисков по обучению
  Учебники, словари (labirint.ru)
  Учебная литература (Читай-город.ru)
  Учебная литература (book24.ru)
  Учебная литература (Буквоед.ru)
  Технические и естественные науки (labirint.ru)
  Технические и естественные науки (Читай-город.ru)
  Общественные и гуманитарные науки (labirint.ru)
  Общественные и гуманитарные науки (Читай-город.ru)
  Медицина (labirint.ru)
  Медицина (Читай-город.ru)
  Иностранные языки (labirint.ru)
  Иностранные языки (Читай-город.ru)
  Иностранные языки (Буквоед.ru)
  Искусство. Культура (labirint.ru)
  Искусство. Культура (Читай-город.ru)
  Экономика. Бизнес. Право (labirint.ru)
  Экономика. Бизнес. Право (Читай-город.ru)
  Экономика. Бизнес. Право (book24.ru)
  Экономика. Бизнес. Право (Буквоед.ru)
  Эзотерика и религия (labirint.ru)
  Эзотерика и религия (Читай-город.ru)
  Наука, увлечения, домоводство (book24.ru)
  Наука, увлечения, домоводство (Буквоед.ru)
  Для дома, увлечения (labirint.ru)
  Для дома, увлечения (Читай-город.ru)
  Для детей (labirint.ru)
  Для детей (Читай-город.ru)
  Для детей (book24.ru)
  Компакт-диски (labirint.ru)
  Художественная литература (labirint.ru)
  Художественная литература (Читай-город.ru)
  Художественная литература (Book24.ru)
  Художественная литература (Буквоед)
Реклама
Разное
  Отправить сообщение администрации сайта
  Соглашение на обработку персональных данных
Другие наши сайты
Приглашаем посетить
  Древнерусская литература (drevne-rus-lit.niv.ru)

   

Драйвер жесткого диска

Драйвер жесткого диска

ТЕХНИЧЕСКОЕ ЗАДАНИЕ

Разработать загружаемый драйвер жесткого диска


#Cтр.
Техническое задание 1
Содержание 2
Введение 3
Основная часть
Структура загружаемого драйвера 3
Связь драйвера с операционной системой 6
Инициализация драйвера 8
Разметка диска 9
11
Описание портов ввода-вывода 11
Система команд 12
13
15
Заключение 16
Список литературы 17
Листинг программы 18

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

Интуитивно ясно, что должна существовать какая-то программная прослойка между аппаратным и программным обеспечением, выполняющая "согласующие" и "унифицирующие" действия. Эта прослойка работает напрямую с аппаратурой, а прикладное (да и системное) программное обеспечение имеет дело только с этой интерфейсной прослойкой.

Операционная система MS-DOS, работающая на компьютерах фирмы IBM или совместимых с ними, тоже использует механизм драйверов.

Однако драйверы MS-DOS не всегда обращаются напрямую к аппаратуре. Обычно они вызывают функции BIOS, и уже BIOS выполняет все действия по вводу/выводу. Конечно, BIOS содержит программы обслуживания только стандартных устройств ввода/вывода, нестандартные устройства обслуживаются драйверами напрямую.

Использование BIOS как дополнительного интерфейса между драйверами стандартных устройств и аппаратурой резко повышает "живучесть" MS-DOS на не вполне совместимых с IBM персональных компьютерах. И это действительно так - самая распространенная на сегодняшний день операционная система MS-DOS версии 3. 30 работает на всех компьютерах, хоть сколько-нибудь совместимых с IBMPC.

Это возможно благодаря тому, что производители совместимых компьютеров учитывают в программах BIOS все аппаратные особенности, и DOS "не видит" отличий. А прикладная программа - тем более.

Почему же этот способ не используется в операционных системах UNIX или OS/2? Дело в том, что к сожалению, программы BIOS не являются реентерабельными. Это не имеет значения для однозадачной MS-DOS, а мультизадачные операционные системы вынуждены сами организовывать обслуживание аппаратуры реентерабельным способом. (Существуют еще проблемы разделения ресурсов между параллельно выполняющимися процессами, которые тоже не решаются в рамках BIOS).

Таким образом, независимость аппаратного и программного обеспечения в DOS обеспечивается, с одной стороны, BIOS для стандартных устройств, с другой стороны - драйверами.

Пользователи могут легко дополнять операционную систему своими драйверами, составленными для нестандартных устройств. Возможна также замена стандартных драйверов, замена или расширение функций BIOS.

Структура загружаемого драйвера

Иногда говорят, что драйверы - это разновидность COM-программ, но это не так. Скорее способ получения загрузочного модуля драйвера похож на способ получения программы в формате COM. Есть еще одно сходство драйверов и программ в формате COM (которое как раз и появляется из-за одинакового способа их получения) - загрузочные модули этих программ являются точным отображением исходного текста на языке ассемблера без добавления каких-либо управляющих блоков в начало файла, как это происходит в программах формата EXE

Но, оказывается, управляющий блок в самом начале модуля драйвера имеется. Это так называемый заголовок драйвера. Только в отличие от программ формата EXE, этот заголовок создается не редактором связи, а самим программистом и должен быть помещен в самое начало исходного текста программы-драйвера.

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

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

Не стоит пытаться запускать драйвер как программу в формате COM, так как управление будет передано в область памяти, содержащую заголовок драйвера, а там нет правильных машинных команд. Поэтому обычно файлы драйверов имеют расширения имени, отличные от COM или EXE. Чаще всего используются расширения SYS, DRV, иногда BIN. На самом деле расширение имени можно задавать любое, так как при описании драйвера в файле CONFIG. SYS указывается его полное имя.

Для драйвера никогда не создается префикс программного сегмента PSP. В начале исходного текста программы-драйвера не ставится директива ORG 100H, как это делается для COM-программы, так как не надо резервировать место для PSP.

Что же представляет из себя загрузочный модуль драйвера?

(0) 4 next указатель на заголовок следующего драйвера. Если смещение адреса следующего драйвера равно FFFF, это последний драйвер в цепочке
(+4) 2 attrib атрибуты драйвера
strateg
interrupt смещение программы обработки прерывания для драйвера
dev_name

поле имеет формат DWORD-указателя и состоит из компоненты адреса сегмента и смещения. Признаком того, что данный драйвер последний в цепочке, служит значение 0FFFFh в компоненте смещения поля next.

Программист, когда он составляет программу-драйвер, заносит в это поле либо 0FFFFh:0FFFFh, если исходный текст содержит только один драйвер, либо адрес следующего драйвера (в виде дальней ссылки на метку заголовка следующего драйвера). Если исходный текст содержит несколько драйверов, то в заголовке последнего в поле next должно находиться значение 0FFFFh:0FFFFh.

а не в файле драйвера!)

Обычно исходный текст программы содержит один драйвер, и поле next задается следующим образом:

Это поле описывает устройство, обслуживаемое данным драйвером. Каждый бит слова отвечает за ту или иную особенность устройства. Прежде чем мы детально рассмотрим назначение всех битов этого слова, заметим, что бит 15 (самый старший бит) указывает, является ли это устройство символьным или блочным.

Для драйверов блочных устройств формат слова атрибутов:

Бит
0 Зарезервировано, бит должен быть равен 0
1

в конец заголовка запроса, старое поле номера сектора должно содержать -1);

2-5 Эти биты зарезервированы и должны быть равны 0
6

1 - поддерживаются логические устройства (используется блочными драйверами для управления "виртуальными" флоппи-дисками, создаваемые драйвером DRIVER. SYS в DOS версии 3. 2 и более поздних версиях);

0 - логические устройства для блочных драйверов не поддерживаются;

7-10 Эти биты зарезервированы и должны быть равны 0
11

1 - единица в этом бите означает, что драйвер поддерживает функцию проверки замены носителя данных в устройстве (например, замены дискеты); используется для DOS версий 3. 00 и более поздних;

0 - для блочных устройств функция проверки замены носителя данных не поддерживается

12 Зарезервировано, бит должен быть равен 0
13

1 - драйвер не использует стандартное IBM-устройство, и необходимо выдать запрос на построение блока параметров BIOSBIOSBPB;

0 - используется IBM-устройство

14

0 - функции IOCTL не поддерживаются

15

1 - символьное устройство;

0 - блочное устройство

После слова атрибутов драйвера находятся два очень важных поля: смещение программы стратегии драйвера strateg и смещение программы обработки прерывания interrupt.

Эти две программы используются DOS для организации обращения к драйверу. Для обращения к драйверу DOS формирует в своей области данных запрос, состоящий из заголовка стандартного формата и переменной части запроса, длина и формат которой зависят от типа запроса. После этого DOS считывает из заголовка драйвера значение смещения программы стратегии и передает ей управление, записав в регистры ES:BX адрес заголовка запроса.

Задача программы стратегии - запомнить этот адрес внутри тела драйвера для дальнейшего использования или организовать очередь запросов обслуживания.

Сразу после вызова программы стратегии DOS вызывает программу обработки прерываний, определив ее адрес из поля interrupt заголовка драйвера.

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

Результаты выполнения функции программа прерывания записывает в специально отведенные поля заголовка запроса, и на этом процедура обращения DOS к драйверу завершается.

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

interrupt DW interruptproc

Последнее поле заголовка драйвера devname имеет различную интерпретацию для символьных и блочных устройств.

Для символьных устройств в этом поле должно располагаться выровненное по левому краю и дополненное до восьми символов пробелами имя устройства. Это имя будет использоваться для обращения к драйверу. Если Вы собираетесь заменить драйвер стандартного символьного устройства DOS на свой, Вы должны записать имя устройства заглавными буквами:

devnameDB 'AUX '

Для блочных устройств первый байт поля devname содержит количество устройств, обслуживаемых данным драйвером, остальные семь байтов не используются:

devname DB 1

DB 7 dup(?)

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

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

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

Связь драйвера с операционной системой

Рассмотрим теперь более подробно механизм взаимодействия драйвера и операционной системы.

После загрузки драйвер становится как бы частью операционной системы. Все обращения к драйверу DOS выполняет с использованием заголовка драйвера. Для примера приведем вид заголовка символьного драйвера, выполняющего только простейшие функции:

Это символьный драйвер (старший бит поля attrib равен 1), исходный текст содержит только один драйвер (поле next содержит значение 0FFFFFFFFh), имя устройства, которое нужно будет использовать при обращении к драйверу - TESTDRV. Имя устройства не должно совпадать с именем файла, содержащего символьный драйвер, иначе Вы не сможете обратиться к файлу, например, для его переименования - DOS будет работать не с файлом, а с устройством.

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

reqoff DW ?reqseg DW ?

Тогда программа стратегии должна записать содержимое регистра ES в поле reqseg, а регистра BX - в поле reqoff:

strategproc: mov cs:reqoff,bx mov cs:reqseg,es ret

Драйвер состоит из одного сегмента кодов, поэтому для адресации данных используется сегментный регистр CS.

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

Приведем формат заголовка запроса:

(0) 1 size
(+1) 1 unit Номер устройства (используется для блочных устройств, указывает, с каким именно устройством, обслуживаемым драйвером, будет работать операционная система)
(+2) 1 cmd Код команды, которую требуется выполнить (может иметь значение от 0 до 18h)
(+3) 2 status Слово состояния устройства, заполняется драйвером перед возвратом управления операционной системе
(+5) 8 reserved

После вызова программы стратегии DOS передает управление программе прерывания (без параметров). Задача программы прерывания - выполнить команду, код которой находится в поле cmd заголовка запроса. Если драйвер блочного устройства обслуживает несколько логических устройств, то в поле unit находится номер устройства, для которого необходимо выполнить команду.

Как результаты выполнения команды возвращаются DOS?

status в заголовке запроса в соответствии с результатами выполнения команды.

Бит Назначение
0-7 Код ошибки устройства (если команда выполнена с ошибкой и драйвер установил признак ошибки (бит 15) в единицу, в это поле он должен записать код ошибки).
8 Команда выполнена. Этот бит всегда устанавливается драйвером перед тем, как он возвращает управление операционной системе.
9 передачи такой информации, как "буфер клавиатуры не пуст", "среда носителя данных заменяемая" (в команде проверки возможности замены среды носителя данных).
10-14 Зарезервировано.
15 Признак ошибки. Устанавливается драйвером, когда он не может обработать запрос или произошла физическая либо логическая ошибка при обработке правильного запроса. Биты 0-7 при этом должны содержать код ошибки.

Приведем таблицу возможных кодов ошибок:

Код Описание
0 Нарушение защиты от записи. Была предпринята попытка записи информации на защищенное от записи устройство.
1 Неизвестное устройство.
2
3 Неизвестная команда. Затребованная команда не поддерживается драйвером.
4 Ошибка CRC. При выполнении команды обнаружена ошибка циклического кода проверки.
5
6 Ошибка при поиске дорожки (дорожка не найдена).
7 Неизвестный носитель данных.
8
9 Нет бумаги в принтере.
0Ah
0Bh Ошибка чтения.
0Ch Общая ошибка.
0Dh Зарезервировано.
0Eh Зарезервировано.
0Fh Неразрешенная замена диска (только для DOS версии 3. 0 и более поздних версий).

  • при необходимости программа считывает дополнительную информацию из области запроса;
  • затребованная команда выполняется (если она поддерживается драйвером);
  • если драйвер считывает какие-либо данные от обслуживаемого физического устройства для передачи их DOS, то сами данные или их адреса программа прерывания записывает в область запроса;
  • программа прерывания устанавливает слово состояния устройства в соответствии с результатами выполнения команды (если драйвер не поддерживает затребованную команду, в слове состояния устройства устанавливаются биты 15 и в биты 0-7 записывается код ошибки 3 - неизвестная команда);
  • восстанавливается содержимое регистров процессора, и управление возвращается операционной системе с помощью команды возврата из дальней процедуры.

Инициализация драйвера

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

Функция инициализации должна поддерживаться любым драйвером, так как она сообщает операционной системе сведения, необходимые DOS для правильного подключения и использования драйвера.

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

header Заголовок запроса.
(+13) 1 n_units Количество устройств, обслуживаемых драйвером. Это поле заполняется только блочным драйвером.
(+14) 4
(+18) 4 parm каретки 0Ah, 0Dh. При возврате драйвер блочного устройства должен записать в это поле адрес массива указателей на блоки параметров BIOSBIOS (BPB), по одному указателю на каждое устройство, обслуживаемое драйвером.
drive Номер устройства. Для версии DOS 3. 0 и более поздних версий в это поле при загрузке драйвера операционная система заносит номер, назначенный устройству, обслуживаемому драйвером. Например, для устройства А: это 0, для B: - 1 и т. д.

При инициализации драйвер символьного устройства сохраняет в своей внутренней области данных параметры инициализации, используя адрес parm. Если параметры содержат числовые величины, программа инициализации может произвести их перекодировку и сохранить значения в двоичном формате.

Затем драйвер может выполнить инициализацию обслуживаемого физического устройства ввода/вывода, инициализацию своих внутренних переменных, вывести на экран какие-либо сообщения либо даже запросить у оператора дополнительные данные - функция инициализации может пользоваться для организации диалога с оператором и других действий функциями прерывания 21h с номерами от 01h до 0Ch, 25h, 30h, 35h и функциями BIOS.

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

Драйверы блочных устройств дополнительно должны возвратить DOS количество обслуживаемых устройств (в поле nunits) и указатель на массив указателей на блоки BPB (в поле parm).

Количество устройств используется DOS для определения логических имен устройств. Например, если Ваш драйвер обслуживает три логических устройства, и на момент его загрузки в системе имеются устройства A:, B: и C:, то устройства, обслуживаемые Вашим драйвером, получат имена D:, E: и F:. Количество устройств необходимо указывать также и в заголовке драйвера, в первом байте поля имени устройства devname.

Для каждого логического устройства драйвер должен содержать так называемый блок параметров BIOS (BIOS Parameter Block) BPB.

Блок BPB содержится в загрузочном секторе диска и содержит информацию, необходимую BIOS для работы с диском. Приведем формат BPB:

(0) 2 sect_siz Количество байтов в одном секторе диска.
(+2) 1 Количество секторов в одном кластере.
(+3) 2 res_sect Количество зарезервированных секторов.
fat_cnt Количество таблиц FAT.
(+6) 2 Максимальное количество дескрипторов файлов, содержащихся в корневом каталоге диска.
(+8) 2 Общее количество секторов на носителе данных (в разделе DOS).
(+10) 1 media Байт-описатель среды носителя данных.
fat_size Количество секторов, занимаемых одной копией FAT.

Приведем фрагмент исходного текста драйвера, возвращающего при инициализации указатель на массив BPB:

lea dx,bpbptr

mov es:[bx+18],dx

mov es:[bx+20],cs

. . . . . . . . . .

В этом примере предполагается, что ES:BX содержит адрес заголовка запроса.

Разметка диска Данные на жесткий диск записываются в секторах. Сектора располагаются на дорожках. Нумерация дорожек начинается с внешней стороны пластины (там расположена нулевая дорожка). Количество пластин (дисков) и головок, так же как и максимальное число дорожек, могут колебаться в довольно широких пределах и зависят от типа конкретного накопителя. Дорожка обычно содержит от 8 до 26 секторов и для данного конкретного накопителя число секторов на дорожке постоянно. Начало дорожки определяется сигналом "индекс", который генерируется накопителем при каждом обороте диска. Далее следует первый сектор дорожки. Второй сектор будет отстоять от первого на число секторов, равное значению фактора чередования минус 1, третий еще на столько же и т. д. Таким образом при факторе чередования равном 3, сектора на 17-секторной дорожке будут располагаться следующим образом: ЪДДВДДВДДВДДВДДВДДВДДВДДВДДВДДВДДВДДВДДВДДВДДВДДВДДї i 1i 7i13i2 i8 i14i3 i9 i15i4 i10i16i 5i11i17i 6i12i ГДДБДДБДДБВДБДДБДДБВДБДДБДДБДДБДДБДДБДДБДДБДДБДДБДДґ i i фактор i i i iчер-ния i i i<--индексi<------>i индекс --> i Формат сектора приведен в таблице. ЪДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДї iОбозначениеi Назначение iДлина i i i i(байт)i ГДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДґ i АМ i Адресный маркер i 4 i i ИНТ1 i Интервал i 9-12 i ГДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДґ i i Поле идентификации: i i i СИНХ1 i Синхробайт i 1 i i ИНТ2 i Интервал i 2 i i СРВ i Байт для сравнения i 1 i i ЦСБ i Старший байт номера цилиндра i 1 i i ЦМБ i Младший байт номера цилиндра i 1 i i ГЛВ i Номер головки i 1 i i СЕКТ i Номер сектора i 1 i i ФЛАГ i Флаговый байт i 1 i i НУЛЬ i Нулевой байт i 1 i i КС1 i Контрольная сумма поля идентификации i 4 i ГДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДґ i ИНТ3 i Интервал i 16 i ГДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДґ i i Область данных: i i i СИНХ2 i Синхробайт i 1 i i ИНТ4 i Интервал i 2 i i ДАННЫЕ i Поле данных i 512 i i КС2 i Контрольная сумма поля данных i 4 i ГДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДґ i ИНТ5 i Интервал i 43 i АДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДЩ Начало сектора обозначается при помощи уникальной комбинации, называемой адресным маркером. Пять интервалов, обозначенных в таблице ИНТ1 - ИНТ5, заполняются нулями, причем длина ИНТ2 и ИНТ4 постоянна и равна 2 байтам, в то время как ИНТ1, ИНТ3 и ИНТ5 могут иметь разную длину, немного отличающуюся от значений, приведенных в таблице. Эти три интервала предназначены для подготовки накопителя к считыванию (записи) следующей за ним области, а различие в длине объясняется тем, что адресный маркер, поле идентификации и данные могут записываться в разное время поверх ранее имевшейся информации, что не обеспечивает точного совпадения физической длины записанной области и ранее имевшейся на этом месте области. Отличия в длине могут составлять несколько бит, чем объясняется наличие после после интервалов синхробайта, позволяющего определить истинную начальную границу области и правильно сгруппировать все последующие биты по байтам. Байт СРВ имеет постоянное значение для всех секторов и используется для проверки правильности считывания поля идентификации. Флаговый байт содержит служебную информацию, в частности отмечает дефектность сектора, если он не пригоден для записи. Контрольные суммы служат для проверки правильности считывания информации из поля идентификации и области данных и вычисляются специальным генератором кодов коррекции ошибок (Error Correction Code, ECC) с производящим полиномом 32-й степени.Контроллер жестких дисков для АТ-подобных ПЭВМ IBM PC AT отличается от всех предыдущих моделей IBM PC и совместимых ПЭВМ в следующем: - стандартный BIOS обеспечивает возможность работы как с накопителями на гибких, так и с накопителями на жестких дисках; - контроллеры жестких и гибких дисков расположены на одной плате; - адреса портов ввода-вывода, предназначенных для управления жестким диском, и назначение портов полностью отличаются от ХТ-подобных ПЭВМ. Возможно подключение к одному ПЭВМ двух жестких дисков. Каждый диск имеет свой набор портов (1F0h-1F7h для первого и 170h-177h для второго). Ниже будут описаны порты только первого диска. Назначение портов второго диска аналогично первому. Порт 1F0h Предназначен для обмена данными с внутренним ОЗУ контроллера, являющимся промежуточным звеном между оперативной памятью ПЭВМ и накопителем. Порт 1F1h. При чтении через этот порт можно получить информацию о последней возникшей ошибке: 7 6 5 4 3 2 1 0 ЪДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДї i i i 0 i i 0 i i i i Бит: АДВДБДВДБДДДБДВДБДДДБДВДБДВДБДВДЩ ДДДД i i i i i АД>0: 1=адресный маркер данных не i i i i i найден i i i i АДДДДД>1: 1=ошибка на нулевой дорожке i i i АДДДДДДДДД>2: 1=выполнение команды прекра- i i i щено программно, команда i i i не завершилась i i АДДДДДДДДДДДДДДДДД>4: 1=идентификатор сектора не i i найден i АДДДДДДДДДДДДДДДДДДДДДДДДД>6: 1=неисправимая ошибка в дан- i ных, ошибка контрольной i суммы АДДДДДДДДДДДДДДДДДДДДДДДДДДДДД>7: 1=дефектный сектор Порт 1F2h. Чтение/запись числа секторов для последующей операции. Порт 1F3h. Чтение/запись параметра "номер сектора" для последующей операции. Порт 1F4h. Чтение/запись старших битов номера цилиндра для последующей операции (биты 0 - 1 - это биты 8 - 9 в 10-битовом номере цилиндра). Порт 1F5h. Чтение/запись младших восьми битов номера цилиндра для последующей операции. Порт 1F6h. Чтение/запись номера устройства и головки для последующей операции. Порт 1F7h (запись). Вывод команды по управлению накопителем. Порт 1F7h (чтение). Чтение состояния накопителя и результатов предыдущей команды: 7 6 5 4 3 2 1 0 ЪДДДВДДДВДДДВДДДВДДДВДДДВДДДВДДДї i i i i i i i i i Бит: АДВДБДВДБДВДБДВДБДВДБДВДБДВДБДВДЩ ДДДД i i i i i i i АД>0: 1=предыдущая команда завер- i i i i i i i шилась с ошибкой i i i i i i АДДДДД>1: 1=сигнал "индекс" i i i i i АДДДДДДДДД>2: 1=данные при выполнении пос- i i i i i ледней операции были скор- i i i i i ректированы при помощи i i i i i алгоритма ECC i i i i АДДДДДДДДДДДДД>3: 1=идет процесс обмена данными i i i АДДДДДДДДДДДДДДДДД>4: 1=поиск завершен i i АДДДДДДДДДДДДДДДДДДДДД>5: 1=ошибка записи i АДДДДДДДДДДДДДДДДДДДДДДДДД>6: 1=устройство готово для чте- i ния, записи или поиска АДДДДДДДДДДДДДДДДДДДДДДДДДДДДД>7: 1=устройство занято выполне- нием команды ( остальные биты не несут смысловой нагрузки)Система команд Код команды заносится в порт 1F7h после того, как подготовлены все параметры в портах 1F2h - 1F6h. Выполнение команды начинается сразу после занесения в порт 1F7h кода команды. Команда состоит из одного байта. Старшие 4 бита содержат код требуемой операции, младшие содержат параметры. Перечень команд с возможными значениями параметров приведен в таблице. ЪДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї i Код i Назначение i Параметры i iоперацииi i i ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ i 1 i Рекалибровать (сброс i Период импульсов сигнала i i i головок на цилиндр 0) i "шаг" i ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ i 2 i Чтение секторов i Биты, определяющие необходи-i ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДґ мость повторных обращений i i 3 i Запись секторов i к диску и повторных попыток i ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДґ считывания при ошибках i i 4 i Проверка секторов i контрольной суммы i ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ i 5 i Форматирование дорожкиi Параметр = 0 i ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ i 7 i Поиск цилиндра i Период импульсов сигнала i i i i "шаг" i ГДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ i 9 i Диагностика i Параметр = 0 i i ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ i i Установка параметров i Параметр = 1 i i i накопителя (максималь-i i i i ное число головок и i i i i секторов) i i АДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Для получения информации о жёстких дисках, а также их самодиагностики необходимо программировать IDE контроллер. Для того, чтобы приведённый исходный текст модуля был более или менее понятен, необходимо разъяснить некоторые принципы программирования IDE контроллера. Базовый порт ввода/вывода для первого IDE контроллера - 1F0h. Ещё я использовал порт контроля (3F6h) для сброса состояния контроллера. Для сброса контроллера служит функция hdreset(). Так как контроллер генерирует запрос на прерывание IRQ14, то есть необходимость в функции, ожидающей прерывание от контроллера. Такой функцией служит hdwait(), она останавливает работу системы до тех пор, пока не произойдёт прерывание от контроллера жёстких дисков или не истечёт время ожидания. Программа правильно обрабатывает все используемые в программе IRQ.


Командование контроллером осуществляется через порт 1F7h, в него записывается код соответствующей команды и после её выполнения в нём хранится результат выполнения. Обмен данными осуществляется через порт 1F0h, порт 1F1h служит для выдачи ошибок, все остальные порты (1F2h-1F6h) для задания параметров работы. Так, например, перед вызовом команды получения информации в 5й бит порта 1F6h заносится номер диска, подключённого к первому контроллеру.

буфере диска, который считывается через порт 1F0h. Теперь, приведённыйниже, текстстанетболеепонятным.

____ ______________________________________________________________________

1f0H Data register. Read/write data from/to controller sector buffer

1f1H Write: Write Precompensation register. Turn on write precompensation.

+7-6-5-4-3-2-1-0+

¦ ¦ ¦0¦ ¦0¦ ¦ ¦ ¦

+---------------+ bit

¦ ¦ ¦ ¦ ¦ +-0: Data Address Mark not found

¦ ¦ ¦ ¦ +---1: Track 0 Error

¦ ¦ ¦ +-----2: Command was aborted

¦ ¦ +---------4: Sector ID not found

+---------------7: Bad block

1f2H Sector count. Read/Write count of sectors for operation

1f3H Sector number. Read/Write current/starting logical sector number

1f4H Cylinder high (bits 0-1 are bits 8-9 of 10-bit cylinder number)

Получение блока параметров BIOS

случае драйвера устройства, поддерживающего только один тип носителя (например драйвер RAM-диска), содержимое

частью блока начальной загрузки, как

показано на рис. 6-7. В этом случае драйвер должен найти и прочитать этот блок, выбрать оттуда блок параметров BIOS и возвратить адрес последнего. Практически во всех случаях блок начальной загрузки располагается в самом первом логическом секторе диска (т. е. сектора, имеющего номер 0). Преобразование номера логического сектора в координаты физического сектора зависит от характеристик устройства и должно быть описано в документации по этому устройству. Драйвер должен проверить структуру этого сектора, чтобы убедиться, что он действительно содержит блок начальной загрузки.

Если первый логический сектор не содержит корректного блока начальной загрузки, например, как в дисках, отформатированных в MS-DOS версий до 2. 0,то драйвер должен считать первый сектор таблицы размещения файлов (FAT). К счастью, MS-DOS версий до 2. 0 поддерживали только несколько форматов, каждый из которых определялся в первом секторе FAT второго логического сектора диска. Самый первый байт первого сектора FAT содержит байт описателя носителя, который можно использовать для определения соответствующего содержимого BPB, возвращаемого к MS-DOS. Версии MS-DOS до 2. 0 используют описатели 0FEH и 0FFH.

СМЕЩЕНИЕ СОДЕРЖАНИЕ РАЗМЕР

(hex)

┌───────────────────────────────────────╖

│ Команда перехода на код загрузчика ║ 3 байта

├───────────────────────────────────────╢

+03 │ Имя и версия изготовителя ║ 8 байт

╓─ ├───────────────────────────────────────╢

║ +0B │ Размер сектора в байтах ║ Слово

║ ├───────────────────────────────────────╢

║ +0D │ Количество секторов в кластере ║ Байт

║ ├───────────────────────────────────────╢

║ +0E │ Количество зарезервированных секторов ║ Слово

БЛОК ║ ├───────────────────────────────────────╢

║ +10 │ Количество таблиц FAT ║ Байт

ПАРАМЕТРОВ ─╢ ├───────────────────────────────────────╢

║ +11 │ Количество элементов директория ║ Слово

BIOS ║ ├───────────────────────────────────────╢

║ +13 │ Количество логических секторов ║ Слово

║ ├───────────────────────────────────────╢

║ +15 │ Описатель носителя ║ Байт

║ ├───────────────────────────────────────╢

║ +16 │ Количество секторов в одной FAT ║ Слово

╙─ ├───────────────────────────────────────╢

+18 │ Количество секторов на дорожке ║ Слово

├───────────────────────────────────────╢

│ Количество головок чтения/записи ║ Слово

├───────────────────────────────────────╢

+1C │ Количество скрытых секторов ║ Слово

╘═══════════════════════════════════════╝

Рисунок 6-7. Содержимое первых 30 байт блока начальной загрузки

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

тома данного диска. Найти его можно, обратившись к корневому директорию.

Вкратце, последовательность обработки команды BUILDBPB следующая :

1. Драйвер должен прочитать блок начальной загрузки (обычно на-

ходящийся в первом логическом секторе диска - сектор #0) и

проверить его на наличие блока параметров BIOS. Если BPB об-

наружен, то переход к шагу 3, иначе переход к шагу 2.

драйвер должен сконструировать соответствующий BPB.

3. Если устройство поддерживает замену носителя (установлен бит

11 слова атрибутов), драйвер должен получить из корневого

директория идентификатор тома и сохранить его.

ный для считывания туда сектора с диска.

Мы опустили из рассмотрения параметры, которые передаются драйверу при обращении к нему с командой BUILDBPB. Игнорируйте их. Один из этих параметров - это описанный ранее описатель носителя, который в данной ситуации не имеет никакого значения, так как данная команда возвращает MS-DOS новое его значение. Второй параметр - это адрес буфера, который либо не содержит ничего су- щественного (если бит 13, NONIBM атрибут, равен 1), либо содержит копию первого сектора FAT (если бит 13 сброшен). В последнем слу- чае, т. е. если там содержится FAT, этот буфер никоим образом не должен быть модифицирован, а так как драйвер обязан иметь свой буфер, куда будет считываться блок начальной загрузки, то на бу- фер, передаваемый при вызове команды BUILDBPB можно не обращать внимания.

Напоследок представляется важным отметить, что в отличие от BPB описатель носителя не обеспечивает однозначного определения формата диска. Однако, MS-DOS версии 3. 0 и выше не будут обновлять свои внутренние структуры, ассоциированные с данным дисководом, до тех пор, пока байт описателя носителя не станет отличным

от предыдущего MDB. Даже несмотря на то, что MS-DOS версии 3. 0 и выше не обращают внимание на действительное значение MDB, драйвер должен вернуть новый MDB при смене формата дискеты.

Подключение драйвера

Он устанавливается путем включения имени гото­вой программы в файл конфигурации системы.

DEVICE=[d:][path]filename[. ext][ parameters]

где (заключенные в квадратные скобки элементы не являются обязательными):

d: - идентификатор дисковода,

path - путь к драйверу,

filename - имя файла, содержащего драйвер,

ext - расширение имени файла,

parameters - параметры для драйвера.

Для установки драйвера следует поместите в файл CONFIG. SYS строку DEVICE = myHDD. sys. (myHDD. sys- это имя программы)

Заключение

Создав драйвер (который работает в операционной системе MSDOS) для жёсткого диска, я разобрался как взаимодействуют персональный компьютер и периферийное устройство. Также я научился как заменять драйвер стандартного устройства, используя системный конфигурационный файл CONFYG. SYS, разобрался в стандартных процедурах и функциях, которые используются при написании драйвера, и получил навыки написания драйверов устройств.

Список литературы

“Справочник программиста ПК типа IBMPC, AT, XT, AT” Москва: 1991г.

“Методика создания и отладки драйвера периферийного

устройства для ОС MSDOS” Софтпанорама: 1990г.

; Вызов : Скопиpуйте в коpневой каталог, добавьте в файл ;

; систему ;

; 1F0 DataRegister (Базовый контроллер ввода-вывода для первого IDE)

; 1F2 Sector count

; 1F3 Sector number

; 1F4 Cylinder low

; 1F6 SDHregister (Номер устройства и головки)

; 1F7 Status register (command register)

;

; 3F6 Alt. Status reg (Dig Output register)

; 3F7 Drive addr reg.

;

;

;COMMAND CODE 1F2(SC) 1F3(SN) 1F4-5(CY) 1F6(SDH)

;Recalibrate 10 n n n d

;Read Sec(s) 20 y y y y

;Write Sec(s) 30 y y y y

;Verify Sec(s) 40 y y y y

;Seek 70 n n y y

;Diagnostic 90 n n n d

code segment

assume cs:code, ds:code, es:code, ss:code

;-- КОНСТАНТЫ --------------------------------------------------------------

cmdfld equ 2 ; поле команды в запросе

status equ 3 ; поле состояния в запросе

numdev equ 13 ; число поддеpживаемых устpойств

changed equ 14 ; носитель сменялся ?

endadr equ 14 ; конечный адpес дpайвеpа в запросе

numrqst equ 18 ; номеp в запросе

bpbadr equ 18 ; адpес BPB на носителе

badr equ 14 ; адpес буфеpа в запросе

sectorequ 20 ; номеpсектоpа

;-- Заголовок дpайвеpа устpойства ------------------------------------------

dw -1, -1 ; связь со следующим дpайвеpом

dw 0100100000000000b ; атpибут дpайвеpа

dw offset strat ; указатель на подпpогpамму

; стpатегии

; пpеpывания

db 1 ; устpойство поддеpживается

db 7 dup (0) ; эти байты обpазуют имя

;-- Таблица пеpеходов к отдельным функциям ---------------------------------

fkttab dw offset init ; функция 0: инициализация

dw offset read ; функция 3: пpямое чтение

dw offset read ; функция 4: чтение

dw offset dummy ; функция 5: читать, остаться в буфеpе

dw offset dummy ; функция 7: очистить буфеp ввода

dw offset dummy ; функция 10: состояние вывода

dw offset write ; функция 12: пpямая запись

dw offset dummy ; функция 13: откpыть (3. 0 и выше)

dw offset dummy ; функция 14: закpыть

dw offset write ; функция 16: выводить, пока не будет занято

request dw (?), (?) ; эдесь проц. стратегии сохр. адpес буфера запроса

bpbptrdwoffsetbpb

mbrdb 0bhdup(0)

bpb db 200h-0bh dup(0) ;сюда считаем bpb

head db ?

sect db ?

n dd ?

n63 dd 63

n255 dd 255

fsec dd ?

;-- ПОДПРОГРАММЫ И ФУНКЦИИ ДРАЙВЕРА ----------------------------------------

; DOSзаписывает в es:bx адрес заголовка запроса, и мы должны вытащить его оттуда

strat proc far ; подпpогpамма стpатегии

mov cs:request, bx ; начальный адpес запроса

mov cs:request+2, es ; в пеpеменной REQUEST

ret ; возвpат в вызывающую подпpогpамму

strat endp

;---------------------------------------------------------------------------

intr proc far ; подпpогpамма пpеpывания

push ax ; занести pегистpы в стек

push cx

push dx

push di

push si

push bp

push ds

pushf ; занестивстек pегистp флагов

push cs ; установить pегистp сегмента данных

pop ds ; здесь код идентичен данным

; в ES:DI

mov bl, es:[di+cmdfld] ; получить код команды

cmp bl, numcmd ; допустим ли код команды ?

jlebcok ; ДА --> bcok

mov ax, 8003h ; код для "неизвестной команды"

; ------ если код команды коppектен, то выполнить команду ---------

bcok: shl bl, 1 ; вычислить указатель в таблице пеpеходов

xor bh, bh ; очистить BH

call [fkttab+bx] ; вызов функции

; в ES:DI

; ------ выполнение функции завеpшено -----------------------------

pop ds ; здесь код идентичен данным

les di, dword ptr request ; занести адpес блока данных

or ax, 0100h ; установить бит окончания

mov es:[di+status], ax ; запомнить все в поле состояния

popf ; восстановить pегистp флагов

pop es ; восстановить дpугие pегистpы

pop ds

pop bp

pop si

pop dx

pop cx

popbx

popax

ret ; возвpат в вызывающую подпpогpамму

intr endp

init proc near ; подпpогpамма инициализации

mov dx, 3f6h

xor al, al

out dx, al ;Turn off IRQ 14

call waithd ; sit back and relax…

mov dx, 1f6h ;SDH register

mov al, 0a0h ;Drive descriptor

out dx, al

mov dx, 1f2h ;Sector count

mov al, 1

out dx, al

mov dx, 1f3h ;Sector number

mov al, 1

out dx, al

mov dx, 1f4h ;low cyl

out dx, al

mov dx, 1f5h ;high cyl

out dx, al ;New generation choose zero cyl.

st head

mov al, 1

out dx, al

mov dx, 1f7h ;Status(Command) register

mov al, 20h ;Read Sector

out dx, al

gword: mov dx, 1f7h ; Wait for data

in al, dx

testal, 8 ; 8th bit=1 - устр-во занято вып-м команды

jz gword

mov cx, 256

mov si, offset mbr

mov dx, 1f0h ;Get data

mov [si], ax

loop gloop

call waithd ; sit back and relax…

mov dx, 3f6h ;Turn on IRQ14 and exit

mov al, 2

mov al, es:[di+devdes] ; получитьобозначениеустpойства

add al, 'A' ; пpеобpазовать в буквы

mov imger, al ; сохpанить в сообщении об установке

mov dx, offset initm ; адpес сообщения об установке

mov ah, 9 ; вывод стpоки

int 21h

mov byte ptr es:[di+numdev], 1 ; поддеpживается 1 устpойство

mov word ptr es:[di+bpbadr], offset bpbptr ; адpесуказателя

mov es:[di+bpbadr+2], ds ; на BPB

mov bpbptr+2, ds ; сегментный адpес BPB в указателе на BPB

xor ax, ax ; все отлично

ret ; возвpат в вызывающую пpогpамму

init endp

; -----------------------------------------------------------------

xor ax, ax ; очистить бит занятости

ret ; возвpат в вызывающую подпpогpамму

dummyendp

; -----------------------------------------------------------------

medtest proc near

xor ax, ax ; очистить бит занятости

ret ; возвpат в вызывающую подпpогpамму

; -----------------------------------------------------------------

getbpb proc near ; пеpедать DOS адpес BPB

mov word ptr es:[di+bpbadr], offset bpb

mov word ptr es:[di+bpbadr+2], ds

xor ax, ax ; очистить бит занятости

ret ; возвpат в вызывающую подпpогpамму

getbpbendp

; -----------------------------------------------------------------

norem proc near ; носитель диска является несменяемым

mov ax, 20 ; установить бит занятости

ret ; возвpат в вызывающую подпpогpамму

; -----------------------------------------------------------------

write proc near

movbp, 30h ; пеpесылка из DOSв диск

jmp short move ; копиpовать данные

writeendp

readprocnear

mov bp, 20h ; пеpесылка из диска в DOS

moveprocnear

fild dword ptr es:[di+sector] ; номеp пеpвогосектоpа

fld1

faddp st(1), st(0) ;sect+1

les di, es:[di+badr] ; адpесбуфеpазанестив ES:DI

move1: ;вычисляемфиз. сектор

fild fsec ;load the number of the first sector to st(0)

Fprem ;st(0) mod st(1)

fxch

fcomp

fistp n ;save number of the phisycal sector

mov al, byte ptr n

mov sect, al

fild fsec ;вычисляемголовку

fisub n

fidiv n63

fist temp

fild n255

fxch

fprem

fxch

fcomp

fistp n ;save number of head

mov head, al

fild temp ; вычисляемцилиндр

fisub n

fidiv n255

fistp n

mov ax, word ptr n

dec ax

mov cyl, ax

hok: mov dx, 3f6h ; Turn off IRQ14

out dx, al

call waithd ; sit back and relax…

mov dx, 1f6h ;SDH Register

mov al, 0a0h

out dx, al

mov al, 1

out dx, al

mov dx, 1f3h ;Sector number

mov al, sect;1

out dx, al

mov dx, 1f4h ;Cyl. low

mov al, byte ptr cyl;0

out dx, al

mov dx, 1f5h ;Cyl. high

mov al, byte ptr cyl+1;0

out dx, al

mov al, head ;1

out dx, al

mov dx, 1f7h ;Status(command) register

out dx, al

mword: mov dx, 1f7h ;wait for data

testal, 8 ; 8th bit=1 - устр-во занято вып-м команды

jz mword

mov cx, 256

mov dx, 1f0h

mloop: cmp bp, 20h ;Read or Write?

jne wr

in ax, dx

jmp short nx

out dx, ax

nx: add di, 2

loop mloop

call waithd ;ждем-с

mov dx, 3f6h ;Turn on IRQ14

mov al, 2

out dx, al

dec bx

cmpbx, 0 ; количество пpочитанных сектоpов = 0 ?

je movee ;if equal, goto end

fild fsec

fld1

fistp fsec

jmp move1

movee: xor ax, ax ; всеотлично

mov di, si

;------------Wait till not busy---------------

waithd: mov dx, 1f7h

in al, dx

test al, 128 ;128=01000000b, it means that device is ready for R/W

jnz waithd

ret

diskdrv equ $

initm db "Your disk installed and ready to use"

imger db "?"

": $", 13, 10, 10

; -----------------------------------------------------------------

code ends

end

Министерство Образования и Культуры Кыргызской Республики

Кыргызский Технический Университет им. И. Раззакова.

Кафедра Информатики и Вычислительной Техники

Курсовой Проект

на тему: Разработка драйвера жесткого диска

Выполнил: ст. гр. ЭВМ-1-99

Ыйсаев У. Б.

Приняла: доц. Токмергенова А. З.

Бишкек 2003.