Файли символьних пристроїв
Є два основні шляхи для спілкування модуля розмовляти з процесами. Перший йде через файли пристрою (подібно файлам в каталозі / dev), інший повинен використовувати файлову систему proc. Оскільки однією з головних причин написання модуля ядра, є підтримка якогось апаратного пристрою, ми почнемо з файлів пристрою.
Початкова мета файлів пристрою полягає в тому, щоб дозволити процесам зв'язуватися з драйверами пристрою в ядрі, і через них з фізичними пристроями (модеми, термінали, і т.д.).
Кожен драйвер пристрою, який є відповідальним за певний тип апаратних засобів, має власний головний номер. Список драйверів і їх головних номерів доступний в / proc / devices. Кожна фізична пристрій, що керується драйвером пристрою має малий номер. Каталог / dev включає спеціальний файл, названий файлом пристрою, для кожного з тих пристроїв, які реально встановлені в системі.
Наприклад, якщо Ви даєте команду ls -l / dev / hd [ab] *. ви побачите все IDE розділи жорсткого диска, які могли б бути пов'язані з машиною. Зверніть увагу, що всі з них використовують той же самий головний номер, 3, але малі номера у кожного свої! Застереження: Вважається, що ви використовуєте архітектуру PC. Я не знаю нічого щодо файлів пристроїв Linux на інших архітектурах.
Коли система була встановлена, всі файли пристроїв були створені командою mknod. Чи не є ніякої технічної причини, по якій вони повинні бути в каталозі / dev. це тільки корисне угоду. При створенні файлу пристрою для цілей тестування, як з вправою тут, ймовірно мало б сенс помістити його в каталог, де Ви компілюєте модуль.
Цей модуль поділено на дві окремі частини: частина модуля, яка реєструє пристрій і частина драйвера пристрою. init_module викликає module_register_chrdev. щоб додати драйвер пристрою до символьної таблиці драйверів пристроїв ядра. Цей виклик також повертає головний номер, який потрібно використовувати для драйвера. Функція cleanup_module викреслює зі списку пристрій.
Це (реєстрація та скасування реєстрації) основні функціональні можливості цих двох функцій. Дії в ядрі не виконуються за власною ініціативою, подібно процесам, а викликаються процесами через системні виклики або апаратними пристроями через переривання або іншими частинами ядра (просто викликаючи специфічні функції). В результаті, коли Ви додаєте код до ядра, ви реєструєте його як драйвер для деякого типу події, і коли Ви видаляєте його, ви відкидаєте реєстрацію.
Драйвер пристрою виконує чотири дії (функції), які викликаються, коли хтось пробує робити що-небудь з файлом пристрою, який має наш головний номер. Ядро знає, що викликати їх треба через структуру file_operations. Fops. який був даний, коли пристрій було зареєстровано, включає покажчики на ті чотири функції, які даний пристрій виконує.
Ще ми повинні пам'ятати, що ми не можемо дозволяти модулю розвантажуватися командою rmmod щоразу, коли root захоче його вивантажити. Причина в тому що, якщо файл пристрою відкритий процесом, і ми видаляємо модуль, то використання файлу викликало б звернення до точки пам'яті де розташовувалася відповідна функція. Якщо ми щасливі, ніякий інший код не був завантажений туди, і ми отримаємо потворне повідомлення про помилки. Якщо ми невдачливі (зазвичай так і буває), інший модуль був завантажений в той же самий місце, що означає перехід в середину іншої функції всередині ядра. Результати цього неможливо передбачати, але вони не можуть бути позитивними.
Зазвичай, коли Ви не хочете виконувати що-небудь, Ви повертаєте код помилки (негативне число) з функції, яка робить таку дію. З cleanup_module такий фокус не пройде: якщо cleanup_module викликаний, модуль завершився. Однак, є лічильник використань, який вважає, скільки інших модулів використовують цей модуль, названий номером посилання (останній номер рядка в / proc / modules). Якщо це число не нульове, rmmod буде терпіти невдачі. Лічильник модульних посилань доступний в змінної mod_use_count_. Так як є макроси, визначені для обробки цієї змінної (MOD_INC_USE_COUNT і MOD_DEC_USE_COUNT), ми вважаємо за краще використовувати їх, а не mod_use_count_ безпосередньо, так що ми будемо в безпеці, якщо реалізація зміниться в майбутньому.