Dall'interfaccia di programmazione Linux , §14.1
Ogni file del dispositivo ha un numero ID principale e un numero ID secondario. L'ID principale identifica la classe generale del dispositivo e viene utilizzato dal kernel per cercare il driver appropriato per questo tipo di dispositivo. L'ID secondario identifica in modo univoco un determinato dispositivo all'interno di una classe generale. Gli ID principali e secondari di un file dispositivo vengono visualizzati dal comando ls -l.
[...]
Ogni driver di dispositivo registra la propria associazione con uno specifico ID dispositivo principale e questa associazione fornisce la connessione tra il file speciale del dispositivo e il dispositivo. Il nome del file del dispositivo non ha rilevanza quando il kernel cerca il driver del dispositivo.
Vedi anche questo vecchio (2001) Linux Device Driver (2e) capitolo .
cioè l'intenzione è di fornire una mappatura unica di major: minor to device: istanza per ogni tipo di dispositivo. In senso stretto, puoi avere due dispositivi distinti con lo stesso maggiore: minore, purché uno sia carattere e uno sia blocco:
# 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
Su Linux, in qualsiasi momento su un sistema il maggiore: i numeri minori per ogni tipo di dispositivo sono unici. I numeri possono tuttavia cambiare nel tempo e non devono necessariamente essere gli stessi su diversi sistemi Linux (anche la stessa distribuzione, kernel e hardware). Si noti che i dispositivi a caratteri e blocchi hanno spazi di numerazione distinti, ad esempio il blocco maggiore 1 è assegnato ai dischi RAM, il carattere maggiore 1 è assegnato a un insieme di dispositivi del kernel inclusi null e zero.
Storicamente, le major dei dispositivi erano (principalmente) allocate staticamente attraverso un registro (anche presente, anche se non mantenuto, nel sorgente del kernel Documentation/devices.txt
). In questi giorni molti dispositivi sono allocati in modo dinamico, questo è gestito da udev e le mappature sono visualizzabili in /proc/devices
. I dispositivi fissi esistono ancora in incude/uapi/linux/major.h
(recentemente spostati da include/major.h
)
Ora, sebbene la combinazione maggiore: minore identifichi in modo univoco specifiche istanze del dispositivo, non c'è nulla che possa impedirti di creare più nodi (file) di dispositivi che si riferiscono allo stesso dispositivo. Non devono nemmeno essere creati in /dev
(ma devono trovarsi su un filesystem che supporta la creazione di nodi di dispositivo e non è montato con l' nodev
opzione).
Un uso comune è la creazione di dispositivi duplicati zero, null e casuali in 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
I nomi sono solo alias, il kernel non si preoccupa molto della maggior parte dei nomi o delle posizioni, si preoccupa del numero maggiore in modo che possa selezionare il driver corretto e al driver (di solito) interessa il numero minore in modo che possa selezionare il istanza corretta.
La maggior parte dei nomi sono semplicemente convenzionali (sebbene alcuni siano definiti da POSIX ). Si noti inoltre che un dispositivo può registrare più numeri principali, controllare il sd
driver /proc/devices
; il nome di un modulo del driver ( .ko
) non deve necessariamente coincidere con il nome del dispositivo e non deve necessariamente coincidere con il nodo del dispositivo /dev
e un singolo modulo del driver può gestire più dispositivi logici / fisici o nomi di dispositivo.
Ricapitolando: potresti avere due o più nodi dispositivo (dentro /dev/
o altro) che hanno lo stesso numero maggiore: numeri minori, ma se sono dello stesso tipo si riferiscono allo stesso dispositivo. Puoi avere un driver in grado di gestire più istanze principali, ma all'interno del kernel e all'interno del driver, per ogni tipo (carattere o blocco) il maggiore: il numero minore viene preso per riferirsi a un dispositivo specifico (maggiore) e un'istanza specifica ( minore) del dispositivo.
Non è possibile avere due nodi dispositivo con lo stesso tipo e major: minor e aspettarsi che accedano a due diversi dispositivi logici o fisici. Quando si accede a un dispositivo, il kernel seleziona un driver in base al tipo e al numero maggiore (e non in base al nome del nodo del dispositivo), e per convenzione il numero minore seleziona in modo deterministico un'istanza o una funzione secondaria specifica.
Aggiornamento Un
po 'di storia interessante e alcune prospettive * BSD sono disponibili nella presentazione BSDCon del 2002 di Poul-Henning Kamp :
https://www.usenix.org/legacy/events/bsdcon/full_papers/kamp/kamp_html/
Se si fa un salto indietro nel tempo (per gentile concessione di Alcatel-Lucent, la rivista tecnica Bell System luglio-agosto 1978), il " Unix Time Sharing System " lo indica chiaramente (p1937):
I dispositivi sono caratterizzati da un numero di dispositivo principale, un numero di dispositivo minore e una classe (blocco o carattere). Per ogni classe, esiste un array di punti di ingresso nei driver di dispositivo. Il numero di dispositivo principale viene utilizzato per indicizzare l'array quando si chiama il codice per un determinato driver di dispositivo. Il numero di dispositivo secondario viene passato al driver di dispositivo come argomento. Il numero minore non ha altro significato se non quello attribuito dal conducente. Di solito, il driver utilizza il numero minore per accedere a uno di più dispositivi fisici identici.