Структура драйверу
Удосконалення зовнішніх пристроїв й інших вузлів персонального комп'ютера. Використання 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 - підтримуються логічні пристрої та загальний IOCTL0 - логічні пристрої та загальний 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