Класи пристроїв і модулів

Спосіб бачення пристроїв в Linux розділяється на три фундаментальні типи. Кожен модуль зазвичай реалізований як один з цих типів і таким чином класифікується як символьний модуль. блоковий модуль. або мережевий модуль. Такий поділ модулів на різні типи або класи не є жорстким; програміст може при бажанні створювати великі модулі, що містять різні драйвери в одному шматку коду. Хороші програмісти, проте, зазвичай створюють різні модулі для кожної нової функціональності, тому що декомпозиція є ключем до масштабованості і розширюваності.

Цими трьома класами є:

Символьне пристрій - це таке пристроїв, до якого можна звертатися як до потоку байтів (так само як до файлу); драйвер символьного пристрою відповідає за реалізацію такої поведінки. Такий драйвер зазвичай, по крайней мере, підтримує системні виклики open. close. read і write. Текстовий екран (/ dev / console) і послідовні порти (/ dev / ttyS0 і подібні) є прикладами символьних пристроїв, так як вони добре представлені абстракцією потоку. Для звернення до символьних пристроїв використовують вузли (node) файлової системи, такі як / dev / tty1 і / dev / lp0. Єдине важлива відмінність між символьними пристроями і звичайними файлами - ви завжди можете рухатися вперед і назад в звичайному файлі, в той час як більшість символьних пристроїв - це тільки канали даних, до яких ви можете звертатися тільки послідовно. Існують, однак, символьні пристрої, які виглядають як області даних, і ви можете рухатися по ним назад і вперед; наприклад, це зазвичай використовується в Граббери екрану, де додатки можуть отримувати доступ до всього отриманого зображенню використовуючи mmap або lseek.

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

Багато мережеві з'єднання (особливо використовують TCP) є поточно-орієнтованими, але мережеві пристрої зазвичай розроблені для передачі і прийому пакетів. Мережевий драйвер нічого не знає про окремі з'єднаннях; він тільки обробляє пакети. Не будучи поточно-орієнтованим пристроєм, мережевий інтерфейс нелегко уявити як вузол в файлової системі зразок / dev / tty1. Unix все ж забезпечує доступ до інтерфейсів через призначення їм унікальних імен (таких як eth0), але це ім'я не має відповідного елемента в файлової системі. Обмін між ядром і мережевим пристроєм сильно відрізняється від використовуваного в символьних і блокових драйвери. Замість read і write ядро ​​викликає функції, пов'язані з передачі пакетів.

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

Останнім часом в ядро ​​були додані інші класи драйверів пристроїв, що включають драйвери FireWire і I2C. Таким же чином, як вони додали підтримку драйверів USB і SCSI, розробники ядра зібрали особливості всього класу і передали їх розробникам драйверів, щоб уникнути подвійної роботи і помилок, спростивши і стабілізувавши таким чином процес написання цих драйверів.

На додаток до драйверів пристроїв в ядрі у вигляді модулів реалізовані і інші функціональні можливості, що включають і апаратні засоби і програмне забезпечення. Загальний приклад - файлові системи. Тип файлової системи визначає, як організована інформація на блоковому пристрої, щоб показати дерево файлів і директорій. Це не драйвер пристрою, тут немає ніякого устрою, пов'язаного зі способом розміщення інформації; замість цього, тип файлової системи - це програмний драйвер, тому що він відображає структури даних нижнього рівня на структури даних верхнього рівня. Він і є файлової системою, яка визначає, якої довжини може бути ім'я файлу і яка інформація про кожен файл зберігається в записі каталогу. Модуль файлової системи повинен здійснити найнижчий рівень системних викликів, які звертаються до каталогам і файлам, відображаючи імена файлу і шляху (так само як іншу інформацію, таку як режими доступу) до структур даних, збереженим в блоках даних. Такий інтерфейс повністю незалежний від фактичної передачі даних на і від диска (або іншого носія), що досягнуто за допомогою драйвера блочного пристрою.

Якщо ви подумаєте про те, як сильно система Unix залежить від нижележащей файлової системи, то ви зрозумієте, що таке програмне поняття життєво важливо для функціонування системи. Здатність декодувати інформацію файлової системи залишається на найнижчому рівні ієрархії ядра та має гранично важливе значення; навіть якщо ви напишете блоковий драйвер для свого нового CD-ROM, це буде марно, якщо ви не в змозі виконати команди ls або cp для даних цього пристрою. Linux підтримує поняття модуля файлової системи, програмний інтерфейс якого декларує різні операції, які можуть бути виконані з індексом файлової системи (inode), каталогом, файлом і суперблоком. Навряд чи в дійсності програмісту потрібно написати модуль файлової системи, тому що офіційне ядро ​​вже включає код для найважливіших типів файлових систем.