Із інтерфейсу програмування Linux , §14.1
Кожен файл пристрою має основний ідентифікаційний номер та незначний ідентифікаційний номер. Основний ідентифікатор визначає загальний клас пристрою і використовується ядром для пошуку відповідного драйвера для цього типу пристроїв. Незначний ідентифікатор однозначно ідентифікує певний пристрій у загальному класі. Основні та незначні ідентифікатори файлу пристрою відображаються командою ls -l.
[...]
Кожен драйвер пристрою реєструє свою асоціацію з певним основним ідентифікатором пристрою, і ця асоціація забезпечує з'єднання між спеціальним файлом пристрою та пристроєм. Ім'я файлу пристрою не має значення, коли ядро шукає драйвер пристрою.
Дивіться також цю стару (2001р.) Драйвери пристроїв Linux (2e) .
тобто намір полягає в наданні унікального відображення основного: другорядного для пристрою: екземпляра для кожного типу пристроїв. Суворо, ви можете мати два різних пристрої з одним і тим же основним: другорядним, якщо один є символом, а один - блоком:
# ls -l /dev/ram1 /dev/mem
crw-r----- 1 root kmem 1, 1 Jan 1 1970 /dev/mem
brw-rw---- 1 root disk 1, 1 Jan 1 1970 /dev/ram1
В Linux в будь-який момент часу в одній системі головне: незначні числа для кожного типу пристроїв є унікальними. Однак цифри можуть змінюватися з часом і не повинні бути однаковими в різних системах Linux (навіть однакові дистрибутиви, ядра та обладнання). Зауважте, що символьні та блокові пристрої мають чіткі нумерації просторів, наприклад, основний блок 1 призначений дискам оперативної пам'яті, char major 1 присвоюється набору пристроїв ядра, включаючи null і zero.
Історично великі пристрої (в основному) були статично розподілені через реєстр (також все ще присутні, хоча і не збережені, у джерелі ядра Documentation/devices.txt
). У наші дні багато пристроїв розподіляються динамічно, цим керує udev , а відображення відображаються в /proc/devices
. Виправлені пристрої все ще існують у incude/uapi/linux/major.h
(нещодавно переїхали з include/major.h
)
Тепер, хоча основна: незначна комбінація однозначно ідентифікує конкретні екземпляри пристрою, нічого не може зупинити створення декількох вузлів (файлів) пристроїв, що стосуються одного пристрою. Їх навіть не потрібно створювати в /dev
(але вони повинні бути у файловій системі, яка підтримує створення вузлів пристрою, і не змонтована за допомогою цієї nodev
опції).
Загальне використання - це створення дублікатів нульових, нульових та випадкових пристроїв у chroot:
# find /dev /var/chroot -regextype posix-extended -regex ".*/(zero|null|random)" -type c |
xargs ls -l
crwxrwxrwx 1 root root 1, 3 2012-11-21 03:22 /dev/null
crw-rw-r-- 1 root root 1, 8 2012-05-07 10:35 /dev/random
crw-rw-rw- 1 root root 1, 5 2012-11-21 03:22 /dev/zero
crwxrwxrwx 1 root root 1, 3 2012-11-21 03:22 /var/chroot/sendmail/dev/null
crw-rw-r-- 1 root root 1, 8 2012-05-07 10:35 /var/chroot/sendmail/dev/random
crw-rw-rw- 1 root root 1, 5 2012-11-21 03:22 /var/chroot/sendmail/dev/zero
Назви - це лише псевдоніми, ядро не сильно піклується про більшість імен чи локацій, воно дбає про основне число, щоб він міг вибрати правильний драйвер, а драйвер (як правило) дбав про незначне число, щоб він міг вибрати правильний екземпляр.
Більшість імен є просто умовними (хоча деякі визначаються POSIX ). Зауважте також, що один пристрій може зареєструвати кілька основних номерів, перевірити sd
драйвер /proc/devices
; ім'я модуля драйвера ( .ko
) не повинно бути таким самим, як ім'я пристрою та не повинно бути таким самим, як вузол пристрою /dev
, і один модуль драйвера може керувати кількома логічними / фізичними пристроями або іменами пристроїв.
Для повторного підбору підсумків: у вас можуть бути два чи більше вузлів пристрою ( /dev/
або в інших місцях), які мають однакові основні: незначні числа, але якщо вони одного типу, вони відносяться до одного пристрою. У вас може бути один драйвер, який може обробляти декілька основних екземплярів, але всередині ядра та всередині драйвера, для кожного типу (char або блок) основне: незначне число приймається для позначення конкретного пристрою (основного) та конкретного примірника ( другорядне) пристрою.
У вас не може бути двох вузлів пристроїв з одним типом і основним: другорядним і очікувати, що вони матимуть доступ до двох різних логічних або фізичних пристроїв. Під час доступу до пристрою до ядра вибирають один драйвер на основі типу та основного числа (а не на основі імені вузла пристрою), а за умовою незначне число детерміновано вибирає конкретний екземпляр або підфункцію.
Оновіть
цікаву історію та деяку перспективу BSD можна знайти у презентації BSDCon Poul-Henning Kamp 2002 року :
https://www.usenix.org/legacy/events/bsdcon/full_papers/kamp/kamp_html/
Якщо перейти назад у часі до 1978 року (люб’язно надано Alcatel-Lucent, Технічний журнал Bell System, липень-серпень 1978 р.), То система Unix Time Sharing чітко визначає це (p1937):
Пристрої характеризуються основним номером пристрою, другорядним номером пристрою та класом (блоком або символом). Для кожного класу існує масив вхідних точок до драйверів пристроїв. Основний номер пристрою використовується для індексації масиву під час виклику коду для певного драйвера пристрою. Незначний номер пристрою передається драйверу пристрою як аргумент. Незначне число не має жодного значення, крім того, яке йому приписує водій. Зазвичай водій використовує незначне число для доступу до одного з декількох однакових фізичних пристроїв.