У цьому розділі коротко розглядаються основні апаратно програмні аспекти, ка сающіеся організації та функціонування підсистем вводу виводу в комп’ютерних сис темах з різною конфігурацією системних шин, включаючи шину PCI платформи x86, яка найбільш часто застосовується в персональних комп’ютерах. Такий аналіз допоможе глибше зрозуміти принципи функціонування різних периферійних пристроїв у різних систе мах і полегшить завдання програмування таких пристроїв. Під терміном «підсистема вводу виводу» зазвичай розуміють як апаратні пристрої комп’ютера, так і програмний ін терфейс, що дозволяє взаємодіяти з ними.

Операції введення виведення для більшості комп’ютерних систем відрізняються від операцій з пам’яттю, як на рівні інструкцій процесора, так і в плані схемотехнической реалізації ції самих пристроїв. Схему введення виведення інформації можна уявити собі так, як по казано на рис. 2.1.

Рис. 2.7

Тимчасова діаграма роботи циклу запису на шині PCI

Тут я не буду аналізувати призначення сигнальних ліній PCI шини – їх призначення описано в численній літературі і специфікаціях на стандарт. По ходу я поясню сенс сигналів, присутніх на шині. Найперше, що слід відзначити при аналізі роботи шини PCI – синхронізацію будь-яких операцій по фронту імпульсів тактовою частоти CLK. Інформація на шині буде дійсна при перепаді сигналу CLK з високого уров ня в низький, причому це стосується команд, адрес, даних і сигналів стану.

Новий цикл шини починається з установки сигналу FRAME # в низький рівень, який свідчить про виконання операції на шині. Високий рівень на цій лінії забороняє обмін даними. Після установки сигналу FRAME # в низький рівень на лінії адреси

AD [0:31] виставляється адреса пристрою, якому необхідно передати дані. Одночасним обелівську на лінії команд C / BE # виставляється код команди, яка буде виконуватися (в даний ном випадку, код дорівнює 0011, що відповідає запису).

На лінію DEVSEL # виставляється сигнал вибору пристрою (активний рівень низький). Нарешті, контролер шини виставляє на лінію сигнал IRDY # готовності даних для запису пристрою. Поки цільове пристрій (target) не виставить сигнал готовності до прийому даних на лінію TRDY #, ніякого запису даних в пристрій не відбудеться, і логіка шини буде чекати, поки сигнал на лінії TRDY # не стане активним (низький рівень).

З тимчасової діаграми видно, що при 3 м тактовом імпульсі CLK запис даних все ще неможлива, оскільки немає готовності пристрою до прийому даних (про це свідок ствует високий рівень на лінії TRDY #). Нарешті, пристрій сигналізує про готовність прийняти дані, які і записуються в пристрій по фронту 4 го синхроімпульса CLK. Цикл запису закінчується при установці сигналу FRAME # в високий рівень.

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

Що ж стосується програмної частини, то доступ до портів введення висновку здійснюється за допомогою операцій читання записи з використанням стандартних інструкцій процесо ра (для процесорів, сумісних з Intel, це команди in / out і їх модифікації). Якщо ж пристрій працює з регістрами, відображеними на пам’ять, то доступ до них здійснює ся з використанням інструкцій mov. Дані, з якими оперує порт, можуть мати раз заходів 1 байт, 2 байта (слово) і 4 байта (подвійне слово).

Проаналізуємо, як виконати читання регістра стану паралельного порту. Для цієї мети можна використовувати інструкцію in, наприклад:

mov  DX, 0x379 in  AL, DX

Перша команда поміщає в регістр DX адреса порту, а друга читає дані розміром в 1 байт в регістр AL процесора.

З усього простору адрес вводу виводу (0-0xFFFF) частину адрес резервується сі

стемой і не повинна використовуватися в програмах користувачів – це адреси з 0xF8 по 0xFF.

Всі пристрої персонального комп’ютера взаємодіють з процесором посред ством шини PCI або PCI Express. При цьому взаємодія різних інтерфейсів здійснюва ляется за допомогою спеціальних контролерів, перетворюють сигнали на спеціалізований них шинах в сигнали шин PCI або PCI Express. Наприклад, для взаємодії пристрою USB з системою необхідно перетворити сигнали на шині USB в сигнали шини PCI, для чого в комп’ютерній системі є хост контролер USB (як правило, він інтегрується в ма терінськой плату, хоча може бути виконаний і як окремий пристрій).

Другий приклад. Для перетворення сигналів інтерфейсу RS 232, використовуваного при обміні даних через послідовний порт, в сигнали PCI на материнській платі є контролер UART (асинхронного приймача-). Спеціалізовані контролери ис користуються і для будь-яких інших інтерфейсів (паралельного порту, Bluetooth, Wi Fi і т. д.).

У більш ранніх операційних системах Windows 98/Me програми користувача могли безпосередньо звертатися до портів введення висновку за допомогою інструкцій процесора in і out, про які я згадував раніше. Для операційних систем Windows 2000/XP/2003, в яких код користувальницької програми не має доступу до адресного простору системи (до якого належать і порти введення виведення), виконання операцій з пристроями вво та виведення можливо тільки за допомогою драйверів пристроїв, а прямий доступ до портів в деяких випадках неможливий навіть з драйвера.

При роботі процесора в захищеному режимі захист доступу до портів введення висновку

забезпечується двома механізмами:

установкою рівня привілеїв введення виведення в поле IOPL (I / O Provilege level) (біти

13 грудня в регістрі прапорів процесора EFLAGS);

картою, містить біти доступу в сегменті стану завдання TSS (Task State

Segment).

Поле IOPL в регістрі прапорів дозволяє управляти доступом до простору адрес по засобом обмеження використання певних інструкцій процесора. Цей хутра низм захисту дозволяє встановлювати необхідний для операційної системи рівень привілеїв для виконання операцій введення висновку. У загальному випадку, доступ до адресного простору введення виведення обмежений рівнями 0 і 1. У цьому випадку операції введення виводи та можуть виконувати драйвери ядра і драйверів пристроїв, в той час як додатки з мен шим рівнем привілеїв операції введення виведення виконати не зможуть. Для менш привілей гірованних програм доступні механізми введення виведення за допомогою викликів функцій інтерфейсу WinAPI.

Наступні інструкції будуть виконані тільки в тому випадку, якщо рівень привілеїв виконується програми (CPL, Current Privilege Level) менше або дорівнює встановленому в IOPL: in, ins, out, outs, cli, sti.

Будь-яка спроба виконати ці інструкції в програмі, рівень привілеїв якої недостатній, викликає виключення загального захисту (General Protection Exceptin). Оскільки кожна виконується завдання отримує власну копію регістра прапорів, то для неї встановлюється свій IOPL.

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

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

Інструкції in (введення даних з порту) і out (висновок даних в порт) передають дані між

портом і регістрами EAX (32 розрядна операція), AX (16 розрядна операція) або AL (опе рація з одним байтом). Адреса порту може бути заданий безпосередньо в команді або по засобом регістра DX.

Наприклад,

in    AL, 0x378 mov  DX, 0x379 out  DX, AL

Строкові інструкції ins і outs пересилають дані між пам’яттю і портом вводу виводу. При цьому адреса порту заноситься в регістр DX, а адреса області пам’яті визначається однією з пар регістрів DS: ESI (При введенні) або ES: EDI (при виводі даних).

При використанні префіксів повторення (наприклад, rep) інструкції ins і outs виконан няют поблочно передачу даних. В цьому випадку регістр ESI або EDI инкрементируется або декрементируется (залежно від значення прапора DF), щоб вказувати на наступний байт, слово або подвійне слово.

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

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

У розглянутому щойно прикладі читання порту введення з адресою 0x379 можливе тільки з програми, що виконується в режимі ядра. Наприклад, програмний код пользо вательскій програми в Windows працює тільки в режимі користувача та взаємодію ет з операційною системою за допомогою інтерфейсу прикладного програмування WinAPI, що реалізований у вигляді підсистеми Win32.

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

Джерело: Магда Ю. С. Комп’ютер в домашній лабораторії. – М.: ДМК Пресс, 2008. – 200 с.: Іл.