Depuis l' interface de programmation Linux , §14.1
Chaque fichier de périphérique a un numéro d'identification majeur et un numéro d'identification mineur. L'ID principal identifie la classe générale de périphérique et est utilisé par le noyau pour rechercher le pilote approprié pour ce type de périphérique. L'ID mineur identifie de manière unique un périphérique particulier au sein d'une classe générale. Les ID majeur et mineur d'un fichier de périphérique sont affichés par la commande ls -l.
[...]
Chaque pilote de périphérique enregistre son association avec un ID de périphérique majeur spécifique, et cette association fournit la connexion entre le fichier spécial de périphérique et le périphérique. Le nom du fichier de périphérique n'a aucune pertinence lorsque le noyau recherche le pilote de périphérique.
Voir également cet ancien chapitre (2001) Linux Device Drivers (2e) .
c'est-à-dire que l'intention est de fournir un mappage unique de majeur: mineur à périphérique: instance pour chaque type de périphérique. Strictement, vous pouvez avoir deux appareils distincts avec le même majeur: mineur, tant que l'un est char et l'autre est bloc:
# 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
Sous Linux, à tout moment sur un système, les principaux: les numéros mineurs pour chaque type d'appareil sont uniques. Les nombres peuvent cependant changer avec le temps, et n'ont pas besoin d'être les mêmes sur différents systèmes Linux (même la même distribution, le même noyau et le même matériel). Notez que les périphériques caractère et bloc ont des espaces de numérotation distincts, par exemple le bloc majeur 1 est affecté aux disques RAM, le caractère majeur 1 est affecté à un ensemble de périphériques noyau, y compris null et zéro.
Historiquement, les majors de périphériques étaient (principalement) alloués statiquement via un registre (également toujours présent, bien que non entretenu, dans la source du noyau Documentation/devices.txt
). De nos jours, de nombreux appareils sont alloués dynamiquement, cela est géré par udev et les mappages sont visibles dans /proc/devices
. Les appareils fixes existent toujours dans incude/uapi/linux/major.h
(récemment déplacé de include/major.h
)
Maintenant, bien que la combinaison majeur: mineur identifie de manière unique des instances de périphérique spécifiques, rien ne vous empêche de créer plusieurs nœuds (fichiers) de périphériques qui font référence au même périphérique. Ils n'ont même pas besoin d'être créés dans /dev
(mais ils doivent être sur un système de fichiers qui prend en charge la création de nœuds de périphérique et n'est pas monté avec l' nodev
option).
Une utilisation courante consiste à créer des périphériques zéro, nul et aléatoire en double dans un 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
Les noms ne sont que des alias, le noyau ne se soucie pas beaucoup de la plupart des noms ou des emplacements, il se soucie du numéro majeur pour qu'il puisse sélectionner le bon pilote, et le pilote se soucie (généralement) du numéro mineur pour pouvoir sélectionner le bonne instance.
La plupart des noms sont simplement conventionnels (bien que certains soient définis par POSIX ). Notez également qu'un seul périphérique peut s'inscrire pour plusieurs numéros principaux, vérifiez le sd
pilote /proc/devices
; un nom de module de pilote ( .ko
) ne doit pas nécessairement être le même que le nom de périphérique, et pas nécessairement le même que le nœud de périphérique /dev
, et un seul module de pilote peut gérer plusieurs périphériques logiques / physiques ou noms de périphérique.
Pour récapituler: vous pouvez avoir deux ou plusieurs nœuds de périphérique (dans /dev/
ou ailleurs) qui ont le même majeur: des numéros mineurs, mais s'ils sont du même type, ils se réfèrent au même périphérique. Vous pouvez avoir un pilote qui peut gérer plusieurs instances majeures, mais au sein du noyau et au sein du pilote, pour chaque type (caractère ou bloc), le numéro majeur: mineur est pris pour faire référence à un périphérique spécifique (majeur) et à une instance spécifique ( mineur) de l'appareil.
Vous ne pouvez pas avoir deux nœuds de périphérique de même type et majeur: mineur et attendez-vous à ce qu'ils accèdent à deux périphériques logiques ou physiques différents. Lorsqu'un périphérique est accédé, le noyau sélectionne un pilote en fonction du type et du numéro principal (et non en fonction du nom du nœud du périphérique), et par convention, le numéro mineur sélectionne de manière déterministe une instance ou une sous-fonction spécifique.
Mise à jour
Une histoire intéressante et une certaine perspective * BSD peuvent être trouvées dans la présentation BSDCon 2002 de Poul-Henning Kamp :
https://www.usenix.org/legacy/events/bsdcon/full_papers/kamp/kamp_html/
Si vous remontez dans le temps jusqu'en 1978 (avec la permission d'Alcatel-Lucent, le journal technique de Bell System juillet-août 1978), le « système de partage du temps Unix » le définit clairement (p1937):
Les périphériques sont caractérisés par un numéro de périphérique majeur, un numéro de périphérique mineur et une classe (bloc ou caractère). Pour chaque classe, il existe un tableau de points d'entrée dans les pilotes de périphérique. Le numéro de périphérique principal est utilisé pour indexer le tableau lors de l'appel du code d'un pilote de périphérique particulier. Le numéro de périphérique mineur est transmis au pilote de périphérique comme argument. Le numéro mineur n'a d'autre signification que celle que lui attribue le conducteur. Habituellement, le pilote utilise le numéro mineur pour accéder à l'un des plusieurs périphériques physiques identiques.