Структура драйверу

Удосконалення зовнішніх пристроїв й інших вузлів персонального комп'ютера. Використання BIOS як додаткового інтерфейсу між драйверами стандартних пристроїв. Написання на Асемблер драйверу для роботи з жорстким диском з пошкодженою нульовою доріжкою.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык украинский
Дата добавления 21.07.2011
Размер файла 43,8 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Міністерство освіти і науки України

КУРСОВА РОБОТА

з дисципліни “Системне програмування”

на тему:

“Структура драйверу”

1. Вступ

Фірми-розробники апаратного забезпечення постійно удосконалюють зовнішні пристрої й інші вузли персонального комп'ютера. Постійно з'являються нова периферійна апаратура і нові модифікації вже існуючих пристроїв.

Однак процес створення нових пристроїв ставить питання: що робити з уже розробленим програмним забезпеченням, розрахованим на стару апаратуру. Якщо розробка програмного забезпечення була дорогою, якщо по своїх можливостях воно ще не застаріло, навряд чи доцільно переробляти все заново тільки через те, що з'явився новий жорсткий диск з більшою ємністю чи новий принтер, що забезпечує кращу якість друку.

Для подолання цих трудностей в сучасних операційних систeмах (UNIX, Windows) для кожного пристрою складається своя програма обслуговування - драйвер. Ця програма виконує всі операції зі своїм пристроєм. Сама операційна система має справу тільки з драйвером, а прикладне програмне забезпечення для виконання введення/виведення викликає відповідні модулі операційної системи. Така програмна "буферизація" усуває, з одного боку, залежність операційної системи від апаратури, з іншого боку - залежність прикладної програми від операційної системи і від апаратури.

Для кожного нового пристрою (наприклад, для нового відеоконтролера) фірма_розробник поставляє свій драйвер.

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

Використання BIOS як додаткового інтерфейсу між драйверами стандартних пристроїв і апаратурою різко підвищує "живучість" MS-DOS на не цілком сумісних з IBM персональних комп'ютерах.

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

Однак цей спосіб не використовується в операційних системах UNIX чи OS/2. Справа в тім, що програми BIOS не є рентерабельними. Це не має значення для однозадачної MS-DOS, а мультизадачні операційні системи змушені самі організовувати обслуговування апаратури реентерабельним способом. (Існують ще проблеми поділу ресурсів між процесами, що виконуються паралельно, що теж не вирішуються через BIOS).

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

Користувачі можуть легко доповнювати операційну систему своїми драйверами, складеними для нестандартних пристроїв. Можлива також заміна стандартних драйверів, чи заміна розширення функцій BIOS.

За своєю структурою драйвер - це ще один різновид програм (на додаток до програм формату COM і EXE). Формат драйверу схожий на формат COM - завантажувальні модулі цих програм є точним відображенням вихідного тексту мовою асемблера без додавання яких-небудь керуючих блоків у початок файлу, як це відбувається в програмах формату EXE.

Однак керуючий блок на самому початку модуля драйвера все ж таки існує. Це, так званий, заголовок драйвера. Тільки на відміну від програм формату EXE, цей заголовок створюється не редактором зв'язку, а самим програмістом і повинний бути поміщений у самий початок вихідного тексту програми-драйвера. При завантаженні драйвера в пам'ять заголовок драйвера теж поміщається в оперативну пам'ять

Звичайно файли драйверів мають розширення імені, відмінні від COM чи EXE. Найчастіше використовуються розширення SYS, DRV, іноді BIN. Насправді розширення імені можна задавати будь-яке, тому що при описі драйвера у файлі CONFIG.SYS вказується його повне ім'я. Формат заголовка драйвера:

Зміщення

Розмір

Назва

Призначення

+0

4

next

Вказівник на заголовок наступного драйвера. Якщо зміщення адреси наступного драйвера дорівнює 0FFFFh, це останній драйвер у ланцюжку

+4

2

attrib

Атрибути драйвера

+6

2

strateg

Зміщення програми стратегії драйвера

+8

2

interrupt

Зміщення програми обробки переривання для драйвера

+0A

8

dev_name

ім'я пристрою для символьних чи пристроїв кількість пристроїв, що обслуговуються, для блокових пристроїв.

Усі драйвери зв'язані в ланцюжок. Найперший драйвер знаходиться відразу за векторною таблицею зв'язку. Поле next заголовка драйвера вказує на наступний драйвер (на його заголовок). Це поле має формат DWORD-вказівника і складається з компоненту адреси сегмента і зміщення. Ознакою того, що даний драйвер останній у ланцюжку, служить значення 0FFFFh у компоненті зміщення полі next.

Програміст, коли він складає програму-драйвер, заносить у це поле або 0FFFFh:0FFFFh, якщо вихідний текст містить тільки один драйвер, або адреса наступного драйвера (у виді далекого вказівника на мітку заголовка наступного драйвера). Якщо вихідний текст містить кілька драйверів, то в заголовку останнього в поле next повинне знаходитися значення 0FFFFh:0FFFFh.

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

Наступне поле в заголовку драйвера - поле атрибутів драйвера atrib. Це поле описує пристрій, що обслуговується даним драйвером. Кожен біт слова відповідає за ту чи іншу особливість пристрою. Біт 15 (найстарший біт) вказує, чи цей пристрій є символьним чи блоковим.

Усі драйвери діляться на дві групи - драйвери символьних пристроїв і драйвери блокових пристроїв. Перші обслуговують пристрої посимвольного введення/виведення, такі як принтери, клавіатура, контролери послідовної передачі даних RS232C і т.д., другі орієнтовані на введення/виведення блоками - це диски.

Як правило, усі нестандартні пристрої, починаючи від цифрового вольтметра до роботів і систем автоматизації виробничих процесів, обслуговуються символьними драйверами. Хоча цей тип драйверів орієнтований на передачу даних посимвольно, для швидкодіючих пристроїв введення/виведення можна організувати буферизацію (засобами операційної системи).

Блокові драйвери можуть знадобитися для обслуговування своїх нестандартних дискових пристроїв. Наприклад, можна використовувати більш щільний запис інформації на дискетах для підвищення їхньої ємності, можна працювати з дисками з пошкодженою нульовою доріжкою тощо. Призначення окремих бітів слова атрибутів символьного драйвера:

Біт

Призначення

0

1 - драйвер обслуговує стандартний пристрій введення;

0 - цей драйвер не обслуговує стандартний пристрій введення

1

1 - драйвер обслуговує стандартний пристрій виведення;

0 - драйвер не обслуговує стандартний пристрій виведення

2

1 - це драйвер стандартного пристрою NUL;

0 - драйвер не обслуговує пристрій NUL

3

1 - драйвер обслуговує годинник

4

Зарезервовано, біт повинний дорівнювати 0

5

Зарезервовано, біт повинний дорівнювати 0

6

1 - дозволене використання драйвером функцій GENERIC IOCTL (для версій DOS, більш пізніх, чим 3.2);

0 - функції GENERIC IOCTL не підтримуються

7-10

Ці біти зарезервовані і повинні дорівнювати 0

11

1 - підтримуються функції відкриття/закриття пристрою (OPEN/CLOSE) для символьних пристроїв;

0 - функції OPEN/CLOSE для символьних пристроїв не підтримуються

12

Зарезервовано, біт повинний дорівнювати 0

13

1 - підтримується функція виведення до одержання стану зайнятості пристрою;

0 - функція виведення до стану зайнятості не підтримується

14

1 - підтримуються функції IOCTL;

0 - функції IOCTL не підтримуються

15

1 - символьний пристрій;

Для драйверів блокових пристроїв формат слова атрибутів інший:

Біт

Призначення

0

Зарезервовано, біт повинний бути дорівнює 0

1

1 - драйвер підтримує 32-бітову адресацію сектора (для версій DOS, починаючи з 4.00 і більш пізніх); якщо встановлений цей біт, поле номера сектора всіх запитів є подвійним словом, що додається в кінець заголовка запиту;

0 - використовується 16-бітова адресація сектора

2-5

Ці біти зарезервовані і повинні бути рівні 0

6

1 - підтримуються логічні пристрої та загальний IOCTL

0 - логічні пристрої та загальний IOCTL не підтримуються;

7-10

Ці біти зарезервовані і повинні бути рівні 0

11

1 - драйвер підтримує функцію перевірки заміни носія даних у пристрої (наприклад, заміни дискети); використовується для DOS версій 3.00 і більш пізніх;

0 - функція перевірки заміни носія даних не підтримується

12

Зарезервовано, біт повинний бути дорівнює 0

13

1 - драйвер не використовує стандартний IBM-пристрій, і необхідно видати запит на побудову блоку параметрів BIOSBIOS BPB;

0 - використовується IBM-пристрій

14

1 - підтримуються функції читання/запису IOCTL;

0 - функції читання/запису IOCTL не підтримуються

15

0 - блоковий пристрій

Після слова атрибутів драйвера знаходяться два дуже важливих поля: зміщення програми стратегії драйвера strateg і зміщення програми обробки переривання interrupt. Ці дві програми використовуються DOS для організації звертання до драйвера.

Для звертання до драйвера DOS формує у своїй області даних запит, що складається з заголовка стандартного формату і перемінної частини запиту, довжина і формат якої залежать від типу запиту. Після цього DOS зчитує з заголовка драйвера значення зміщення програми стратегії і передає їй керування, записавши в регістри ES:BX адреса заголовка запиту. Задача програми стратегії - запам'ятати цю адресу усередині тіла драйвера для подальшого використання чи організувати чергу запитів обслуговування.

Відразу після виклику програми стратегії DOS викликає програму переривання, визначивши її адресу з поля interrupt заголовка драйвера. Програма переривання зчитує тільки що записаний програмою стратегії адреса заголовка запиту і виконує ту функцію, номер якого записаний у запиті. Номер функції знаходиться в заголовку запиту. Результати виконання функції програма переривання записує в спеціально відведені поля заголовка запиту, і на цьому процедура звертання DOS до драйвера завершується.

Останнє поле заголовка драйвера dev_name має різну інтерпретацію для символьних і блокових пристроїв. Для символьних пристроїв у цьому полі повинне розташовуватися вирівняне по лівому краї і доповнене до восьми символів пробілами ім'я пристрою. Це ім'я буде використовуватися для звертання до драйвера. Для блокових пристроїв перший байт поля dev_name містить кількість пристроїв, що обслуговуються даним драйвером, інших сім байтів не використовуються. Окрім зазначених процедур в програмі-драйвері можуть знаходитися також області даних, що використовуються драйвером, і підпрограми, що викликаються програмами стратегії і переривання. Іноді стандартні драйвери перепризначують на себе деякі вектори переривань, і тоді вони містять у собі обробники цих переривань. В області пам'яті, відведеною операційною системою драйверу, може розташовуватися стек драйвера, якщо розмір системного стека недостатня. На довжину драйвера накладається таке ж обмеження, як і на довжину COM-програм - 64 кілобайти, тобто один сегмент.

Процес завантаження драйверів наступний. Системний файл DOS IO.SYS містить деякі драйвери пристроїв, що складають базову систему введення/виведення. Ці драйвери з'являються в пам'яті при завантаженні операційної системи і зв'язані в ланцюжок через поля next у своїх заголовках. Такі драйвери є резидентними драйверами операційної системи. Резидентні драйвери можуть бути замінені драйверами користувача, крім того, користувач може додати в список драйверів нові. У списку драйверів драйвери користувача знаходяться перед резидентними. Першим у цьому списку завжди йде драйвер з ім'ям пристрою NUL. Це нуль-пристрій, що використовується для тестових цілей. Драйвер псевдопристрою NUL не може бути перепризначений, він завжди розташований безпосередньо за векторною таблицею зв'язку DOS. Далі йдуть драйвери, описані у файлі CONFIG.SYS Коли операційна система завантажує драйвер, вона створює заголовок запиту і поміщає в нього команду ініціалізації. Потім викликається програма стратегії драйвера, який передається адреса підготовленого заголовка запиту. Після цього викликається програма переривання драйвера. Ця програма переглядає заголовок запиту, визначає, що прийшла команда ініціалізації, і починає її обробляти. Ініціалізуюча частина виконується тільки один раз при завантаженні драйвера. Можуть виконуватися такі дії, як зчитування параметрів ініціалізації з файлу CONFIG.SYS, видача ініціалізуючих команд на пристрій, що обслуговується, введення/виведення, ініціалізація внутрішніх областей даних і т.д. Перед завершенням своєї роботи ініціалізуюча частина драйвера записує в заголовок запиту розмір резидентної частини драйвера. Сама ініціалізуюча частина більше не буде потрібна, тому ця частина драйвера не залишається при ініціалізації резидентною у пам'яті.

Таким чином, кількість пам'яті, що відводиться драйверу при завантаженні, визначається, в залежності від інформації, котру драйвер передає операційній системі при ініціалізації, та не залежить від довжини файлу драйвера. Після завантаження драйвер стає частиною операційної системи. Усі звертання до драйвера DOS виконує з використанням заголовка драйвера. Запит операційної системи до драйвера складається із заголовка, що має фіксований формат і довжину 13 байт, і перемінної частини, розмір і формат якої залежить від виконуваної функції. Формат заголовка запиту:

Зміщення

Розмір

Назва

Призначення

+1

1

Unit

Номер пристрою (вказує, з яким саме пристроєм, що обслуговується драйвером, буде працювати операційна система)

+2

1

Cmd

Код команди, що потрібно виконати (може мати значення від 0 до 18h)

+3

2

Status

Слово стану пристрою, заповнюється драйвером перед поверненням керування операційній системі

+5

8

Reserved

Зарезервовано

Після виклику програми стратегії DOS передає керування програмі переривання (без параметрів). Задача програми переривання - виконати команду, код якої знаходиться в поле cmd заголовка запиту. Якщо драйвер блокового пристрою обслуговує кілька логічних пристроїв, то в поле unit знаходиться номер пристрою, для якого необхідно виконати команду.

У залежності від виконуваної команди запит може містити іншу інформацію, необхідну для виконання команди. Дані (чи адреси даних), отримані драйвером від фізичного пристрою введення/виведення, містяться в область перемінної частини запиту. Крім того, драйвер повинний установити слово статусу пристрою 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 і більш пізніх версій).

Як уже було сказано, номер функції, котру повинен виконати драйвер, передається операційною системою через поле cmd заголовку запиту. Нижче описані основні функції, що використовуються для роботи з драйверами блокових пристроїв. Для наведених далі функцій у вигляді таблиці подано дані, що описують поля заголовку для тієї чи іншої функції. Опис основних функцій для роботи з драйверами. Функція 00h: Ініціалізація драйвера. Ця функція виконується тільки один раз при завантаженні драйвера і підключенні його до операційної системи. Функція ініціалізації повинна підтримуватися будь-яким драйвером, тому що вона повідомляє операційній системі дані, що необхідні DOS для правильного підключення і використання драйвера. Формат запиту для команди ініціалізації:

Зміщення

Розмір

Назва

Призначення

+0

13

Header

Заголовок запиту.

+0Dh

1

n_units

Кількість пристроїв, що обслуговуються драйвером. Це поле заповнюється тільки блоковим драйвером.

+0Eh

4

end_addr

Кінцева FAR-адреса резидентної частини коду драйвера. У це поле драйвер записує адреса байта пам'яті, що випливає за тією частиною коду драйвера, що повинна стати резидентною.

+12h

4

parm

FAR-адреса рядка параметрів ініціалізації драйвера з файлу CONFIG.SYS. Цей рядок містить усе, що знаходиться в рядку файлу після команди 'DEVICE=', вона закінчується символами перекладу рядка і повернення каретки 0Ah, 0Dh. При поверненні драйвер блокового пристрою повинний записати в це поле адреса масиву вказівників на блоки параметрів BIOS Parameter Block (BPB), по одному вказівнику на кожен пристрій, що обслуговується драйвером.

+16h

1

drive

Номер пристрою. Для версії DOS 3.0 і більш пізніх версій у це поле при завантаженні драйвера операційна система заносить номер, призначений пристрою, що обслуговується драйвером. Наприклад, для пристрою А: це 0, для B: - 1 і т.д.

При ініціалізації драйвер символьного пристрою зберігає у своїй внутрішній області дані параметри ініціалізації, використовуючи адресу parm. Якщо параметри містять числові величини, програма ініціалізації може зробити їхнє перекодування і зберегти значення в двійковому форматі.

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

Крім цього, драйвер повинний заповнити поле end_addr адресою кінця резидентної частини драйвера. Тому що програма ініціалізації виконується тільки один раз, звичайно її розташовують наприкінці драйвера і для економії пам'яті не залишають резидентною.

Драйвери блокових пристроїв додатково повинні повернути DOS кількість пристроїв, що обслуговуються, (у поле n_units) і вказівник на масив вказівників на блоки BPB (у поле parm).

Кількість пристроїв використовується DOS для визначення логічних імен пристроїв. Наприклад, якщо драйвер обслуговує три логічних пристрої, і на момент його завантаження в системі маються пристрої A:, B: і C:, то пристрої, що обслуговуються драйвером, одержать імена D:, E: і F:. Кількість пристроїв необхідно вказувати також і в заголовку драйвера, у першому байті поля імені пристрою dev_name. Для кожного логічного пристрою драйвер повинний містити так називаний блок параметрів BIOS (BIOS Parameter Block) BPB. Блок BPB міститься в завантажувальному секторі диска і містить інформацію, необхідну BIOS для роботи з диском. Формат блоку BPB:

Зміщення

Розмір

Назва

Призначення

+0

2

sect_siz

Кількість байтів в одному секторі диска.

+2

1

clustsiz

Кількість секторів в одному кластері.

+3

2

res_sect

Кількість зарезервованих секторів.

+5

1

fat_cnt

Кількість таблиць FAT.

+6

2

root_siz

Максимальна кількість дескрипторів файлів, що містяться в кореневому каталозі диска.

+8

2

tot_sect

Загальна кількість секторів на носії даних (у розділі DOS).

+0Ah

1

media

Опис носія даних.

+0Bh

2

fat_size

Кількість секторів, в одній копії FAT.

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

Якщо з'ясувалося, що по тим чи іншим причинам встановлення драйвера неможливе то процедура ініціалізації повинна виконати такі дії. Драйвер символьного пристрою повинен вказати як кінцеву адресу резидентної частини програми адресу початку драйвера, тобто адресу заголовка драйвера. Розмір резидентної частини при цьому буде дорівнювати нулю. Блокові драйвери додатково повинні записати нуль у поле кількості логічних пристроїв, що обслуговуються, n_units. В обох випадках включення драйвера до складу операційної системи не відбудеться. Функція 01h: Перевірка заміни носія даних. Цю команду DOS видає драйверу, коли вона хоче перевірити, чи відбулася заміна носія даних, наприклад, заміна дискети. Формат запиту для команди перевірки заміни носія:

Зміщення

Розмір

Назва

Призначення

+0

13

header

Заголовок запиту.

+0Dh

1

media

У цьому полі драйверу передається опис носія даних, з яким DOS працювала раніш.

+0Eh

1

reply

У це поле драйвер повинний помістити відповідь про факт заміни середовища:

1 - диск не був замінений;

0 - невідомо;

0FFh - диск був замінений.

+0Fh

4

vol_id

Вказівник на попередню мітку тому (якщо встановлений біт 11 слова атрибута пристрою і диск був замінений)

Якщо драйвер підтримує функцію перевірки заміни середовища носія даних (біт 11 слова атрибута встановлений у 1) і виявилося, що відбулася заміна диска, драйвер повинний повернути в поле vol_id вказівник на область пам'яті, що містить попередню мітку тому у форматі ASCIIZ. Якщо мітка тому не використовується драйвером, а біт 11 слова атрибутів установлений, необхідно повернути вказівник на рядок "NO_NAME", завершений двійковим нулем. Опис середовища media класифікує використовуване середовище носія даних, але робить це неоднозначно. Характерні для цього байта параметри дисків:

Значення

Тип носія

0FFh

2 сторони, 8 секторів на доріжку;

0FEh

1 сторона, 8 секторів на доріжку;

0FDh

2 сторони, 8 секторів на доріжку;

0FCh

1 сторона, 9 секторів на доріжку;

0F9h

2 сторони, 15 секторів на доріжку;

0F8h

Жорсткий диск;

Функція 02h: Побудувати блок BPB. Ця команда має сенс тільки для блокових пристроїв і викликається після попередньої команди, якщо відбулася зміна носія даних. Драйвер повинний повернути адресу нового блоку BPB. Формат запиту для цієї команди:

Зміщення

Розмір

Назва

Призначення

+0

13

header

Заголовок запиту.

+0Dh

1

media

У цьому полі драйверу передається байт-опис середовища носія даних, з яким DOS працювала раніш.

+0Eh

4

buf_adr

Адреса буфера обміну. Уміст цього буфера при виклику драйвера залежить від установки біта 13 слова атрибутів пристрою (IBM-формат). Якщо цей біт дорівнює 0 (пристрій формату IBM), буфер містить перший сектор першої копії FAT. В іншому випадку вказівник встановлений на буфер вільного сектора.

+12h

4

bpb_adr

Вказівник на новий BPB. Це поле записується драйвером.

Операційна система MS-DOS версії 3.0 і більш пізніх версій включає підтримку апаратних засобів перевірки зміни носія даних. Якщо драйвер знайшов, що зміна носія даних відбулася неправильно, у невідповідний момент часу, він може повернути помилку з кодом 15 (недозволена заміна диска).

Функції 04h - Читання, 08h - Запис, 09h - Запис з перевіркою. Усі ці команди використовуються для читання/запису інформації з пристрою чи в пристрій відповідно. Вони мають практично однаковий формат запиту. В операціях читання чи запису беруть участь сектори для блокових пристроїв і байти для символьних пристроїв. Область запиту містить вказівник на буфер обміну, куди потрібно помістити прочитані чи звідки треба взяти записані дані.

Крім того, драйвер повинний повернути кількість дійсно прочитаних чи записаних байтів/секторів. Формат запиту для цих команд:

Зміщення

Розмір

Назва

Призначення

+0

13

header

Заголовок запиту.

+0Dh

1

media

У цьому полі драйверу передається опис середовища носія даних.

+0Eh

4

buf_adr

Адреса буфера для передачі даних.

+12h

2

count

Кількість переданих байтів для символьних чи пристроїв секторів для блокових пристроїв.

+14h

2

sector

Номер початкового сектора, якщо драйвер використовує 16-бітову адресацію чи секторів -1 для 32-бітової адресації. Це поле не використовується символьними драйверами.

+16h

4

vol_id

Вказівник на мітку тому у форматі ASCIIZ. Повертається блоковим драйвером, якщо він виставляє помилку 15 (неправильна зміна диска). Це поле повинне містити посилання на мітку необхідного диска.

+1Ah

4

sect32

Номер початкового сектора, якщо вміст поля sector дорівнює -1. Першим йде старше слово номера сектора. Якщо виявлена помилка з номером 15, у це поле записується вказівник на мітку тому.

Після виконання операцій чи читання записи драйвер обов'язково повинний записати в поле count кількість дійсна переданих байтів для символьних чи пристроїв секторів для блокових. У випадку помилки також потрібно записати правильне значення в поле count.

Функції 0Dh - Відкрити пристрій, 0Eh - Закрити пристрій. Для того щоб драйвер міг використовувати ці команди, біт 11 у слові атрибутів пристрою в заголовку драйвера повинний бути встановлений у 1.

Драйвери символьних пристроїв по цій команді можуть посилати ініціалізуючі послідовності символів на пристрої (наприклад, на принтер можуть посилатися команди установки типу шрифту, формату папера і т.д.) чи встановлювати пристрій у вихідний стан. Можна також виявляти спроби одержання багаторазового доступу до пристрою. У цьому випадку друга команда відкриття повинна повернути помилку (якщо багаторазовий доступ до пристрою заборонений).

Драйвер блокового пристрою за допомогою цих команд може робити підрахунок відкритих файлів. Якщо вміст лічильника відкритих файлів для даного пристрою дорівнює 0, то відкритих файлів на цьому пристрої немає. Якщо драйвер тепер скине всі буфери на диск, користувач зможе замінити диск на іншій. Однак якщо програми відкривають файли без їхнього закриття, то можуть виникнути помилки при використанні цього методу.

Запит для цих команд складається тільки з заголовка.

Функція 0Fh - Перевірка можливості зміни диска

Ця команда використовується тільки для тих драйверів, у слові атрибутів яких біт 11 встановлений у 1. Драйвер повинний повідомити DOS, чи можлива заміна носія даних. Наприклад, заміна жорсткого диска звичайно неможлива, хоча існують накопичувачі зі змінними жорсткими дисками.

Драйвер повертає інформацію про можливість заміни носія в біті 9 слова стану пристрою. Значення цього біта, рівне 0, драйвер установлює, якщо можлива заміна носія даних, у противному випадку встановлюється значення, рівне 1.

Запит складається тільки з заголовка.

Функція 13h - Функції керування введенням/виведенням (IOCTL)

Команда з кодом 19 призначена для виконання декількох функцій і підтримується тільки тими драйверами, у яких у слові атрибутів пристрою встановлений у 1 біт підтримки IOCTL (біт 6). Ця команда підтримується DOS версії 3.2 і більш пізніх версій. Команда використовується для виконання ряду операцій з дисками, доступних звичайно лише на рівні BIOS, наприклад, форматування, читання/запис секторів по їхньому абсолютному номері і т.д. DOS має спеціальну функцію номер 44h переривання 21h. Ця функція має безліч підфункций і призначена для підтримки IOCTL. Формат запиту для даної команди:

Зміщення

Розмір

Назва

Призначення

+0

13

header

Заголовок запиту.

+0Dh

1

funct

Це поле містить код функції команди загального IOCTL.

+0Eh

1

subfunc

Код підфункції для функції funct.

+0Fh

2

si_reg

Значення регістра SI при виклику функції 44h переривання 21h. Ця функція DOS призначена для керування введенням/ви- веденням.

+11h

2

di_reg

Значення, передане при виклику функції 44h переривання 21h через регістр DI.

+13h

4

buf

Вказівник на буфер даних, що містить керуючу інформацію для чи пристрою призначений для прийому інформації від пристрою.

Функції 17h - Одержати активний логічний пристрій, 18h - Встановити активний логічний пристрій.

Ці команди обробляються тільки тими драйверами, в яких у слові атрибутів встановлений біт 6 - підтримка логічних пристроїв. Команди використовуються в DOS версії 3.2 і в більш пізніх версіях.

Команди забезпечують метод опитування номера поточного активного логічного пристрою на фізичному диску чи встановлення активного логічного пристрою. Формат запиту:

Зміщення

Розмір

Назва

Призначення

+0

13

Header

Заголовок запиту.

+0Dh

1

Unit

Код логічного пристрою, що повинне стати активним при використанні команди 18h, чи код активного пристрою, що поміщається драйвером по команді 17h.

+0Eh

1

Cmd

Код команди.

+0Fh

4

Status

Слово стану.

+13h

4

Reserved

Зарезервовано.

По команді 17h (одержати активний логічний пристрій) драйвер повинний помістити ідентифікатор пристрою в поле unit, для пристрою А: міститься 1, для В: - 2 і т.д. Якщо драйвер керує єдиним пристроєм, він повинний записати в поле unit нуль

При написанні даної курсової роботи було використано літературу по програмуванню на мові Асемблер [1], технічну документацію опису роботи з драйверами [2], [3], електронну документацію опису переривань MS-DOS [4] та вихідні коди ОС MS-DOS 3.30 [5].

Після ознайомлення з наведеними літературними джерелами було виділено такі особливості програмної реалізації продукту:

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

перехоплення переривання прямої роботи з жорстким диском INT 13;

звертання до диску через INT 13 Extension.

2. Постановка задачі

комп'ютер асемблер драйвер

Задача курсової роботи полягає у написанні на мові Асемблер драйверу для роботи з жорстким диском, що містить пошкоджену нульову доріжку.

Дана програма відноситься до класу системних та створюється для забезпечення можливості роботи з нестандартним апаратним забезпеченням із ОС MS-DOS.

Постановка задачі для драйвера жорсткого диску, що містить пошкоджену нульову доріжку:

Оголошення типів та констант, необхідних при роботі з жорстким диском.

Перехоплення переривання прямої роботи з жорстким диском INT 13;

Забезпечення звертання до диску через INT 13 Microsoft/IBM Extension;

Забезпечення можливості звертання до диску прикладних програм через функції MS-DOS.

3. Алгоритм розв'язку задачі

Пошкоджена нульова доріжка робить неможливим зчитування з нього таблиці розділів, а отже роботу з диском. Для усунення цієї проблеми драйвер перехоплює звертання через переривання до нульової доріжки та перенаправляє їх до останньої доріжки жорсткого диску. Таким чином, створивши нову таблицю розділів, можна проводити нормальну роботу із жорстким диском. Оскільки на момент запуску ядра MS-DOS драйвер ще не завантажений, логічні диски на пошкодженому жорсткому дискові не аналізуються та автоматично не створюються. Тому драйвер в процесі ініціалізації створює логічні диски самостійно.

4. Програмна реалізація алгоритму

Драйвер для роботи з жорстким диском з пошкодженою нульовою доріжкою.

1. Загальна характеристика програми.

- Файл програми має ім'я hddriver.asm (856 рядків, 18 Кб).

- Файл драйверу має ім'я hddriver.sys (2546 байт)

- Мова програмування - Асемблер.

2. Призначення програми.

Призначена для забезпечення можливості роботи з жорстким диском з пошкодженою нульовою доріжкою

3. Основні ідентифікатори програми.

cs_seg -сегмент коду програми;

request-far вказівник на поточний запит драйвера;

load_str-far вказівник на стрічку завантаження драйвера;

old_int13-far вказівник на попередній обробние переривання 13h;

int13_info-версія INT 13 MS/IBM Extension;

drive_param-параметри жорсткого диску з котрим працює програма;

rw_packet-структура для читання/запису даних через INT 13 MS/IBM Extension;

drive_letter-літера першого логічного диску;

fault_drive-фізичний номер жорсткого диску;

write_verified-визначення наявності перевірки при записі даних;

disk_table-таблиця параметрів логічних дисків;

bpb_ptr-вказівник на таблицю BPB;

bpb_table-таблиця BPB.

4. Структура програми.

Основні процедури:

strat_proc-процедура стратегії драйвера;

intr_proc-процедура переривання драйвера;

media_chk-перевірка заміни носія даних;

dev_read-зчитати дані з диску;

dev_write-записати дані на диск;

dev_write_verify -записати дані на диск з перевіркою;

dev_open-відкрити пристрій;

dev_close-закрити пристрій;

removable_chk -перевірка можливості заміни носія даних;

ioctl_common -процедура загального опрацювання IOCTL;

ioctl_format_track -форматування дорожки;

ioctl_get_bpb-повернення BPB;

build_bpb-створення BPB;

read_1_sector-зчитати 1 фізичний сектор;

read_sectors-зчитати фізичні сектори;

write_1_sector-записати 1 фізичний сектор;

write_sectors-записати фізичні сектори;

verify_1_sector -перевірити 1 фізичний сектор;

verify_sectors - перевірити фізичні сектори;

get_disk_param -дістати параметри жорсткого диску;

chk_int13ext-перевірити наявність INT 13 MS/IBM Extension;

int13_handler-обробник переривання INT 13h;

init- процедура ініціалізації;

find_fault_drive -знаходження несправного жорсткого диску;

parse_cmd_line -опрацювання командного рядка;

fill_bpb-підготовка BPB;

process_mbr-опрацювання таблиці розділів;

install_int13_handler - встановлення обробника переривання INT 13h.

5. Середовище реалізації: MS DOS.

6. Середовище виконання: Turbo Assembler 5.0

7. Середовище відлагодження: NuMega Soft-Ice 2.62 for DOS

5. Інструкція користувачеві програми

Для запуску програми користувачеві слід добавити в файл CONFIG.SYS стрічку:

device=<шлях_до_програми>\hddriver.sys [/D:<номер_диску>]

Де <шлях_до_програми> - повний шлях до програми драйвера,

/D:<номер_диску> - необов'язковий параметр, що явно задає номер несправного жорсткого диску (<номер_диску> може дорівнювати від 0 до 3). При відсутності даного параметру програма визначить цей диск автоматично.

У даній курсовій роботі розроблено драйвер для роботи з жорстким диском, що містить пошкоджену нульову доріжку. Подальшим розвитком даного проекту є вдосконалення функцій драйвера (зчитування таблиці розділів з файлу, автоматичне відновлення завантажувального сектора тощо) та перенесення драйвера в мультизадачні операційні системи (Linux, Windows).

Література

1. Зубков С.В. Assembler для DOS, Windows и UNIX. - 2-е изд., испр. и доп. - М.: ДМК, 2000. - 608 с.: ил.

2. TechHelp! 6.0.

3. Внутренная организация MS-DOS: http://www.vcl.ru

4. Ralf Brown's Home Page: http://www.pobox.com/~ralf

5. MS-DOS 3.30 Source Code: http://www.microsoft.com

Додаток 1. Текст програми на мові Assembler

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; HDDRIVER.ASM;

; AUTHOR: IDOLON;

; (10-6-2002);

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; SE NON E VERO, E BEN TROVATO;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.modeltiny.386.code

tagRW_PACKETstruc bSizedb10h bRsvrddb0 wBlockCountdw? dwBuffdd? qwBlockNumdq?tagRW_PACKETendstagDRIVE_PARAMstruc wSizedw1Ah

wFlagsdw?

dwCylsdd?

dwHeadsdd?

dwSectsdd?

qwSectorsCountdq?

wSectorSizedw?

tagDRIVE_PARAMends

tagINT13_INFOstruc

bVersiondb?

bRsvrddb?

wFlags dw?

tagINT13_INFOends

tagLOG_DISKstruc

dwStartSectordw?

dwSectorsdw?

tagLOG_DISKends

tagBPBstruc

wSectSizedw0

bClustSectsdb0

wResSectsdw0

bFatCntdb0

wRootEntriesdw0

wTotSectsdw0

bMediadb0

wFatSectsdw0

wSectsPerTrkdw0

wHeadsdw0

dwHidSectsdd0

dwBigTotSectsdd0

bAligndb0

tagBPBends

MBR_SIGNEQU0AA55h

PART_1EQU1BEh

PART_2EQU1CEh

PART_3EQU1DEh

PART_4EQU1EEh

PART_SIGNEQU1FEh

FS_CODEEQU4h

PART_STARTEQU8h

PART_SIZEEQU0Ch

FS_FAT16EQU04h

FS_FAT16BEQU06h

FS_FAT16X EQU0Eh

FS_EXTENDEDEQU05h

FS_EXTENDEDXEQU 0Fh

UNIT_NOEQU1h

UNITS_SUPPORTED EQU0Dh

SECT_COUNTEQU12h

SECT_NUMEQU14h

BIG_SECT_NUMEQU1Ah

TRANSFER_ADDREQU0Eh

MAX_UNITS_SUPPORTED EQU 24

org0h

start:

;; ------------------------- Заголовок драйвера ----------------------------- ;;

next_drvdd0FFFFFFFFh

drv_attrdw0000100001000010b

strat_addrdwoffset strat_proc

intr_addrdwoffset intr_proc

device_countdb1

device_namedb"HDFAULT"

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

cs_segdw?

requestdd?

load_strdd?

old_int13dd?

int13_infotagINT13_INFO <>

drive_paramtagDRIVE_PARAM <>

rw_packettagRW_PACKET <>

drive_letterdb?

fault_drivedb?

write_verifieddb0

disk_tabletagLOG_DISK 24 dup (<>)

bpb_ptrdw offset bpb_table,?

bpb_tabletagBPB 24 dup (<>)

command_table:

dwoffsetinit; 0

dwoffsetmedia_chk; 1

dwoffsetbuild_bpb; 2

dwoffsetunsupported; 3

dwoffsetdev_read; 4

dw3 dup (offset unsupported); 5,6,7

dwoffsetdev_write; 8

dwoffsetdev_write_verify; 9

dw2 dup (offset unsupported); 0a,0b

dwoffsetunsupported; 0c

dwoffsetdev_open; 0d

dwoffsetdev_close; 0e

dwoffsetremovable_chk; 0f

dw3 dup (offset unsupported); 10,11,12

dwoffsetioctl_common; 13

dw6 dup (offset unsupported); 14,15,16,17,18,19

int13_jumptable:

dwoffset read_sectors ; 2

dwoffset write_sectors; 3

dwoffset verify_sectors; 4

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

;

; Процедура стратегії драйвера

;strat_procprocfarmovword ptr cs:request,bxmovword ptr cs:request+2,esretstrat_procendp;

;Процедура переривання драйвера

;

intr_procprocfarpushfpushapushdspushespushcspopds

assumeds:_TEXT

lessi,dword ptr request

xorbx,bx

movbl,byteptr es:[si+2]

cmpbl,19h

jainvalid_command

shlbx,1

callword ptr command_table[bx]

err_check:

testal,al

jeok_exit

orax,8000h

ok_exit:

orax,0100h

movword ptr es:[si+3],ax

popes

popds

popa

popf

ret

invalid_command:

movax,3h

jmpshort err_check

intr_procendp

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

unsupportedprocnear

xorax,ax

ret

unsupportedendp

media_chkprocnear

mov byte ptr es:[si+0Eh], 1

xor ax, ax

ret

media_chkendp

dev_readprocnear

pushes

xoreax,eax

movax,es:[si+SECT_NUM]; 16-бітний # сектора

cmpax,0FFFFh; якщо 0FFFFh то # 32-бітний ->

jnzprocess_reading

moveax,es:[si+BIG_SECT_NUM] ; # сектора (thanx to Ralf Brown)

process_reading:

xorebx,ebx

movbl,es:[si+UNIT_NO]

shlbx,3; bx = bx*sizeof(tagLOG_DISK)

movebx,[ebx+disk_table]

addeax,ebx

movcx,es:[si+SECT_COUNT]; к-сть секторів

lesbx,es:[si+TRANSFER_ADDR] ; Адрес буферу

movdl,fault_drive; диск

callread_sectors

popes

jncdev_read_ok

moves:[si+SECT_NUM],cx

movax,0Bh; General read error

ret

dev_read_ok:

xorax,ax

ret

dev_readendp

dev_writeprocnear

pushes

xoreax,eax

movax,es:[si+SECT_NUM] ; 16-бітний # сектора

cmpax,0FFFFh ; якщо 0FFFFh то # 32-бітний ->

jnzprocess_writing

moveax,es:[si+BIG_SECT_NUM] ; # сектора (thanx to Ralf Brown)

process_writing:

xorebx,ebx

movbl,es:[si+UNIT_NO]

shlbx,3 ; bx = bx*sizeof(tagLOG_DISK)

movebx,[ebx+disk_table]

addeax,ebx

movcx,es:[si+SECT_COUNT] ; к-сть секторів

lesbx,es:[si+TRANSFER_ADDR] ; Адрес буферу

movdl,fault_drive

callwrite_sectors

popes

jncdev_write_ok

moves:[si+SECT_NUM],cx

movax,0Ah; General write error

ret

dev_write_ok:

xorax,ax

ret

dev_writeendp

dev_write_verify procnear

movwrite_verified,1

calldev_write

movwrite_verified,0

ret

dev_write_verify endp

dev_openprocnear

xorax,ax

ret

dev_openendp

dev_closeprocnear

xorax,ax

ret

dev_closeendp

removable_chk proc near

mov ax, 200h ; Диск - незмінний пристрій

ret

removable_chk endp

ioctl_commonprocnear

cmpbyte ptr es:[si+0Dh],08h; DISK category

jnzioctl_unknown

xorax,ax

moval,es:[si+0Eh]; minor code

cmpax,42h

jzioctl_format_track

cmpax,60h

jzioctl_get_bpb

ioctl_unknown:

movax,3

ret

ioctl_commonendp

ioctl_format_track proc near

pushes

pushbx

lesbx,es:[si+13h]

popbx

popes

xorax,ax

ret

ioctl_format_track endp

ioctl_get_bpbproc near

pushes

pushsi

xorbx,bx

movbl,es:[si+UNIT_NO]

lesdi,es:[si+13h]

movbyte ptr es:[di],5

movbyte ptr es:[di+1],5

movword ptr es:[di+2],1

movax,word ptr drive_param.dwCyls

moves:[di+4],ax

leadi,[di+7]

moval,SIZE tagBPB

movcx,12

mulbl

movbx,ax

leasi,[bx+bpb_table]

rep movsw

movsb

popsi

popes

xorax,ax

ret

ioctl_get_bpbendp

build_bpbprocnear

xorbx,bx

movbl,es:[si+UNIT_NO]

moval,SIZE tagBPB

mulbl

movbx,ax

leabx,[bx+bpb_table]

mov word ptr es:[si+12h],bx

mov word ptr es:[si+14h],ds

xor ax,ax

ret

build_bpbendp

;; =-----------------------------------------------------= ;;

chs_2_lbaprocnear ; in ax=доріжка, dx=головка, cx=сектор

xorebx,ebx

movbx,dx

andeax,0FFFFh

xoredi,edi

movdi,word ptr drive_param.dwHeads

muledi

jctoo_large_sect_num

addeax,ebx

jctoo_large_sect_num

movdi,word ptr drive_param.dwSects

muledi

jctoo_large_sect_num

deccx

movbx,cx

addeax,ebx

too_large_sect_num:

ret

chs_2_lbaendp ; out eax = LBA # сектора, CF=1 помилка

read_1_sectorprocnear ; in ds:bx=&буфер, eax=# сектора, dl=диск

movcx,1

read_1_sectorendp ; out cf=1 - error, cf=0 - all clear

read_sectorsprocnear ; in es:bx=&буфер, eax=# сектора, dl=диск

; cx=к-сть секторів, dl=номер диску

pushsi

movrw_packet.wBlockCount,cx

movdword ptr rw_packet.qwBlockNum,eax

movdword ptr rw_packet.qwBlockNum+4,0

movword ptr rw_packet.dwBuff,bx

movword ptr rw_packet.dwBuff+2,es

movah,42h ; Int13X - EXTENDED READ

movsi,offset rw_packet

cmpcs:int13_executed,0

jnzread_sec_exit

int13h

movcx,rw_packet.wBlockCount

popsi

ret

read_sec_exit:

addsp,2

ret ; must save/restore SI by yourself!

read_sectorsendp ; out cf=1 - помилка, cf=0 - ok

write_1_sectorprocnear ; in es:bx=&буфер, eax=# сектора, dl=диск

movcx,1

write_1_sectorendp ; out cf=1 - помилка, cf=0 - ok

write_sectorsprocnear ; in es:bx=&буфер, eax=# сектора,

; cx=к-сть секторів, dl=номер диску

pushsi

movrw_packet.wBlockCount,cx

movdword ptr rw_packet.qwBlockNum,eax

movdword ptr rw_packet.qwBlockNum+4,0

movword ptr rw_packet.dwBuff,bx

movword ptr rw_packet.dwBuff+2,es

movah,43h ; Int13X - EXTENDED WRITE

movsi,offset rw_packet

moval,write_verified

cmpcs:int13_executed,0

jnzwrite_sec_exit

int13h

movcx,rw_packet.wBlockCount

popsi

ret

write_sec_exit:

addsp,2

ret

write_sectorsendp ; out cf=1 - помилка, cf=0 - ok

verify_1_sectorprocnear ; in es:bx=&буфер, eax=# сектора, dl=диск

movcx,1

verify_1_sectorendp ; out cf=1 - помилка, cf=0 - ok

verify_sectorsprocnear ; in es:bx=&буфер, eax=# сектора,

; cx=к-сть секторів, dl=номер диску

pushsi

movrw_packet.wBlockCount,cx

movdword ptr rw_packet.qwBlockNum,eax

movdword ptr rw_packet.qwBlockNum+4,0

movword ptr rw_packet.dwBuff,bx

movword ptr rw_packet.dwBuff+2,es

movah,44h ; Int13X - VERIFY SECTORS

movsi,offset rw_packet

moval,write_verified

cmpcs:int13_executed,0

jnzverify_sec_exit

int13h

movcx,rw_packet.wBlockCount

popsi

ret

verify_sec_exit:

addsp,2

ret

verify_sectorsendp ; out cf=1 - помилка, cf=0 - все гаразд

get_disk_param proc near ; in dl=номер_диску (фізичний ID)

pushsi

movah,48h

movsi,offset drive_param

int13h

popsi

ret ; out заповнений drive_param

get_disk_paramendp

chk_int13ext procnear ; in dl=номер_диску (фізичний ID)

pushsi

movah,41h

movbx,55AAh

int13h

jcchk_int13_exit

movint13_info.bVersion,ah

movint13_info.wFlags,cx

cmpbx,0AA55h

stc

jnzchk_int13_exit

clc

chk_int13_exit:

popsi

ret

chk_int13ext endp

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

int13_handler procfar

assume ds:nothing

movcs:int13_executed,1

cmpdl,cs:fault_drive

jnzexec_old_int13

cmpah,42h

jbsimple_int13

cmpah,44h

jbextended_int13

simple_int13:

cmpah,02h

jbexec_old_int13

cmpah,04h

jaexec_old_int13

testcx,0FFC0h

jnzexec_old_int13

testdh,dh

jnzexec_old_int13

; отже ми працюємо з 0-доріжкою

subah,2

pushsi

movsi,ax

shrsi,7

pushds

movds,cs:cs_seg

assumeds:_TEXT

pushcx

pushdi

pushax

movedi,dword ptr drive_param.qwSectorsCount

moveax,drive_param.dwSects

subedi,eax

andecx,1Fh

dececx

addedi,ecx

popax

xorcx,cx

movcl,al

moveax,edi

callword ptr int13_jumptable[si]

pushf

calldword ptr old_int13

moval,byte ptr rw_packet.wBlockCount

popdi

popcx

popds

popsi

pushbp

pushax

pushf

popax

movbp,sp

mov[bp+8],ax

popax

popbp

movcs:int13_executed,0

iret

extended_int13:

assume ds:nothing

pushecx

pusheax

moveax,ds:[si+08h]; LBA номер сектора

movecx,cs:drive_param.dwSects

dececx

cmpeax,ecx

popeax

jaexec_old_int13x

pusheax

moveax,dword ptr cs:drive_param.qwSectorsCount

incecx

subeax,ecx

addds:[si+08h],eax

popeax

exec_old_int13x:

popecx

exec_old_int13:

pushf

calldword ptr cs:old_int13

pushbp

pushax

pushf

popax

movbp,sp

mov[bp+8],ax

popax

popbp

movcs:int13_executed,0

iret

int13_executed db0

int13_handler endp

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

;; Процедура ініціалізації ;;

;; --------------------------------------------------- ;;assumeds:_TEXTinitprocnearmovcs_seg,csmovah,9movdx,offset install_msgint21hmovword ptr es:[si+0Eh],offset initmovword ptr es:[si+10h],cs

moval,es:[si+16h]

addal,'A'

movdrive_letter,al

pushes

pushsi

lessi,es:[si+12h]

movword ptr load_str,si

movword ptr load_str+2,es

callparse_cmd_line

popsi

popes

testax,ax

jzoption_D_set

callfind_fault_drive

movdx,offset nofault_drive_msg

jcabort_install

option_D_set:

movdl,fault_drive

callchk_int13ext

movdx,offset no_int13ext_msg

jcabort_install

movdl,fault_drive

callget_disk_param

movdx,offset getparam_err_msg

jcabort_install

movbyte ptr es:[si+UNITS_SUPPORTED],0

movword ptr es:[si+12h],offset bpb_ptr

movword ptr es:[si+14h],cs

movword ptr bpb_ptr+2,cs

callinstall_int13_handler

callfill_bpb

cmpbyte ptr es:[si+UNITS_SUPPORTED],0

jnzinit_exit

inc byte ptr es:[si+UNITS_SUPPORTED]

movbx,offset bpb_table; параметри за замовчуванням

mov[bx+tagBPB.dwBigTotSects],0; необхідні для інсталяції

mov[bx+tagBPB.wSectSize],200h

mov[bx+tagBPB.bClustSects],1; cluster size

mov[bx+tagBPB.wResSects],1; 1 reserved sector

mov[bx+tagBPB.bFatCnt],2; 2 copies of FAT

mov[bx+tagBPB.wRootEntries],512; root size = 512 entries

mov[bx+tagBPB.wTotSects],0

mov[bx+tagBPB.bMedia],0F8h; fixed disk

mov[bx+tagBPB.wFatSects],0

mov[bx+tagBPB.wSectsPerTrk],0

mov[bx+tagBPB.wHeads],0

mov[bx+tagBPB.dwHidSects],0

init_exit:

xorax,ax

ret

abort_install:

movah,9

int21h

movdx,offset aborted_msg

int21h

movax,0Bh

movword ptr es:[si+0Eh],offset start

ret

initendp

find_fault_drive procnear

pushes

pushds

popes

movdx,80h

read_track0:

movah,15h

pushdx

int13h

popdx

jcnext_drive

testah,ah

jznext_drive

movbx,offset mbr_buff

movcx,1

movax,0201h

int13h

jcget_fault_drive

next_drive:

incdx

cmpdx,84h

jnzread_track0

stc

get_fault_drive:

popes

movfault_drive,dl

ret

find_fault_drive endp

parse_cmd_lineprocnear; in es:si - командна стрічка

xorcx,cx

cld

next_char:

seges

lodsb

deccx

cmpal,0Ah

jzget_length

cmpal,0Dh

jzget_length

jmpshort next_char

get_length:

negcx

subsi,cx

moval,'/'

movdi,si

repnz scasb

jnzparse_cmd_exit

cmpbyte ptr es:[di],'D'

jzoption_d

cmpbyte ptr es:[di],'d'

jnzparse_cmd_exit

option_d:

incdi

cmpbyte ptr es:[di],' '

jzoption_d

cmpbyte ptr es:[di],':'

jzoption_d

moval,es:[di]

cmpal,'0'

jbparse_cmd_exit

cmpal,'3'

japarse_cmd_exit

addal,50h

movfault_drive,al

xorax,ax

parse_cmd_exit:

ret

parse_cmd_lineendp ; out ax=0 - без опції, ax=1 - опція /D вказана

fill_bpbprocnear; заповнити BPB для всіх логічних дисків

xoreax,eax; почати з MBR (сектор #0)

next_mbr:

pusheax

movdl,fault_drive

movbx,offset mbr_buff

pushes

moves,cs:cs_seg

callread_1_sector

popes

popedx

jcfill_bpb_exit

cmpword ptr [bx+PART_SIGN],MBR_SIGN

jnzfill_bpb_exit

movax,smbr_processed

callprocess_mbr

cmpsmbr_processed,0

jnztest_next

movsmbr_processed,1

test_next:

testeax,eax

jnznext_mbr

ret

fill_bpb_exit:

movax,1

ret

smbr_processeddw0

fill_bpbendp

process_mbrprocnear; in: 'mbr_buff' містить MBR сектор,

leadi,[bx+PART_1]; ds:bx -> mbr_buff, edx=LBA # сектора MBR

callchk_partition; ax = 0 якщо MBR, or ax = 1 якщо SMBR

jaeprocess_exit

testax,ax

jnzis_smbr

leadi,[bx+PART_2]

callchk_partition

jaeprocess_exit

leadi,[bx+PART_3]

callchk_partition

jaeprocess_exit

leadi,[bx+PART_4]

callchk_partition

jaeprocess_exit

is_smbr:

callfind_extended

ret

process_exit:

xoreax,eax

ret

process_mbrendp ; out: eax = # секторп наступного SMBR, або 0

chk_partitionprocnear; in: ds:di -> &partition_record

pushax; edx=LBA # сектора MBR

pushbx

moval,[di+FS_CODE]

cmpal,FS_FAT16

jzprepare_bpb

cmpal,FS_FAT16B

jzprepare_bpb

cmpal,FS_FAT16X

jnzchk_exit

prepare_bpb:

moveax,[di+PART_START]

addeax,edx

pusheax

movecx,[di+PART_SIZE]

xorbx,bx

movbl,es:[si+UNITS_SUPPORTED]

shlbx,3; bx = bx*sizeof(tagLOG_DISK)

mov[bx+disk_table],eax

mov[bx+disk_table+4],ecx

shrbx,3

moval,SIZE tagBPB

mulbl

movbx,ax

leabx,[bx+bpb_table]; ds:bx -> BPB нового логічного диску

pushbx

mov[bx+tagBPB.dwBigTotSects],ecx

mov[bx+tagBPB.wSectSize],200h; 512-byte sector

movedx,ecx; розмір в секторах

shredx,2; edx = edx/4

movax,4; розмір кластера

movebx,128*1024*2

check_clustersize:

cmpecx,ebx

jbwrite_clustersize

shlax,1; ax = ax*2 - розмір кластера

shlebx,1

shredx,1; edx = edx/2 - розмір в секторах

jmpshort check_clustersize

write_clustersize:

popbx

mov[bx+tagBPB.bClustSects],al; розмір кластера

mov[bx+tagBPB.wResSects],1; 1 зарезервований сектор

mov[bx+tagBPB.bFatCnt],2; 2 копії FAT

mov[bx+tagBPB.wRootEntries],512; root size = 512 записів

mov[bx+tagBPB.wTotSects],0

mov[bx+tagBPB.bMedia],0F8h; жорсткий диск

shredx,8; edx = edx/256

incdx

jnz write_fatsize

decdx

write_fatsize:

mov[bx+tagBPB.wFatSects],dx

movax,word ptr drive_param.dwSects

mov[bx+tagBPB.wSectsPerTrk],ax

movax,word ptr drive_param.dwHeads

mov[bx+tagBPB.wHeads],ax

popeax

mov[bx+tagBPB.dwHidSects],eax

incbyte ptr es:[si+UNITS_SUPPORTED]

cmpbyte ptr es:[si+UNITS_SUPPORTED],MAX_UNITS_SUPPORTED

chk_exit:

popbx

popax

ret

chk_partitionendp

find_extendedprocnear ; in: ds:bx -> mbr_buff

leadi,[bx+PART_1]

next_extended_chk:

moval,[di+FS_CODE]

cmpal,FS_EXTENDED

jzextended_found

cmpal,FS_EXTENDEDX

jzextended_found

adddi,10h

cmpdi,PART_SIGN

jbnext_extended_chk

xoreax,eax; out: eax=0 - no more extended partitions

ret

extended_found:

moveax,[di+PART_START]

ret

find_extendedendp; out: eax=LBA # сектора наступного SMBR

install_int13_handler proc near

pushes

pushsi

movax,3513h

int21h

movword ptr old_int13,bx

movword ptr old_int13+2,es

movax,2513h

movdx,offset int13_handler

int21h

popsi

popes

ret

install_int13_handler endp

install_msgdb0Dh,0Ah,'HDDriver ver 0.91',0Dh,0Ah,'$'

nofault_drive_msg db"There is no HDD with damaged 0-track. Hint: use D<drive_num> option",0Dh,0Ah,"$"

no_int13ext_msg db"No BIOS INT 13 extension support",0Dh,0Ah,"$"

getparam_err_msg db"Error occured while getting disk geometry values",0Dh,0Ah,"$"

aborted_msgdb"Installation aborted",0Dh,0Ah,"$"

mbr_buff db512 dup (?)

endstart

Размещено на Allbest.ru


Подобные документы

  • Основні блоки персонального комп'ютера та їх значення. Варіанти організації внутрішньомашиного інтерфейсу. Функціональна схема мікропроцесору. Види запам'ятовуючих пристроїв. Послідовність роботи блоків комп'ютера. Основні зовнішні та внутрішні пристрої.

    курсовая работа [346,8 K], добавлен 05.01.2014

  • Системний блок як корпус, який містить основні компоненти персонального комп’ютера. Коротка характеристика головних зовнішніх та внутрішніх пристроїв персонального комп’ютера. Послідовність операцій при обтиску та обробленні роз'єму "витої пари".

    лабораторная работа [1,7 M], добавлен 02.06.2011

  • Властивості та класифікація оперативної пам'яті комп'ютера. Пам'ять типу ROM, DRAM, DDR2 та DDR3, кеш-пам'ять SRАМ. Архітектурна будова пам'яті. Швидкість обміну інформацією з жорстким диском та флеш-пам'яттю. Технічні характеристики оперативної пам'яті.

    реферат [147,1 K], добавлен 13.04.2014

  • Загальна структура комп'ютера, архітектура процесора типу Intel 8086. Принцип роботи пам'яті, її види (постійна та оперативна). Основи програмування на мові асемблер та її синтаксис. Особливості використання позначок, кодів команд, операндів і директив.

    лабораторная работа [36,0 K], добавлен 27.02.2013

  • Мова асемблер для кожного типу комп'ютера своя. Асемблер орієнтований саме на специфіку комп'ютера або на специфіку процесора. Мікропроцесори, що належать до різних сімейств, мають свої системи команд. Система команд МП ІA 32 - режими адресації.

    лекция [36,2 K], добавлен 13.04.2008

  • "Критичні" комплектуючі комп'ютера. Процесор та оперативна пам'ять. Швидкість роботи комп'ютера. Порівняння швидкодії комплектуючих з роботою еталонних моделей. Стратегія і варіанти модернізації. Функціональні особливості побудови материнської плати.

    курсовая работа [4,6 M], добавлен 24.06.2013

  • Призначення драйверів та порядок роботи з драйверами в MS-DOS. Розробка драйверів консолі. Структура драйвера та призначення компонентів. Розробка структури алгоритму, програми налагодження драйвера. Опис змінних програми та роботи модулів програми.

    курсовая работа [1,0 M], добавлен 22.06.2012

  • Набір програм, призначених для управління комп'ютером, зберігання і обробки інформації, для організації роботи всіх підключених до комп'ютера пристроїв. Загальні відомості про операційну систему. Історичний аспект розвитку ОС Windows та його можливості.

    реферат [2,3 M], добавлен 30.03.2009

  • Види списків, особливості їх створення, застосування та можливості удосконалення роботи користувача персонального комп’ютера. Керування та аналіз груп споріднених даних у середовищі програми MS Excel 2010. Опрацювання спискiв за допомогою форми даних.

    дипломная работа [2,7 M], добавлен 18.06.2014

  • Аналіз роботи обчислювальних пристроїв, побудованих за RISC-архітектурою. Центральний процесор і внутрішня пам'ять мікроконтролерів AVR компанії Atmel. Принцип побудови AVR-контролера ATtiny2313: складові частини; програмування пам'ятi мовою Асемблер.

    курсовая работа [1,1 M], добавлен 27.07.2015

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.