1.5. /dev

/dev è la directory dove si trovano i file speciali, o di dispositivo. È una directory molto interessante che evidenzia un aspetto importante del filesystem di Linux: ogni cosa è un file o una directory. Scorrendo questa directory, se tutto va bene si dovrebbero vedere dei file denominati hda1, hda2 etc..., che rappresentano le diverse partizioni sulla prima unità master del sistema; /dev/cdrom e /dev/fd0 rappresentano l'unità CD-ROM e l'unità floppy. Questo può sembrare strano, ma ha un significato se si paragonano le caratteristiche dei file a quelle dell'hardware. È possibile leggere da entrambi e scrivere sia nell'uno che nell'altro. Si prenda /dev/dsp, per esempio. Questo file rappresenta il dispositivo microfono. Ogni dato scritto in questo file verrà ridiretto verso il microfono. Se si fa una prova con "cat /boot/vmlinuz > /dev/dsp" (su un sistema configurato in modo appropriato) si dovrebbe sentire qualche suono sulle casse. Cioé il suono del kernel! Un file inviato a /dev/lp0 viene mandato in stampa. Inviando dati a /dev/ttyS0 e leggendo dallo stesso si comunica con un dispositivo collegato alla prima porta seriale, per esempio un modem.

La maggior parte dei dispositivi sono a blocchi o a caratteri; esistono comunque altri tipi di dispositivo e ne possono essere creati di nuovi. In generale, i "dispositivi a blocchi" (block devices) sono dispositivi che memorizzano o manipolano dati, i "dispositivi a caratteri" (character devices) possono essere pensati come dispositivi che trasmettono o trasferiscono dati. Per esempio, unità a dischetti, dischi rigidi e unità CD-ROM sono tutti dispositivi a blocchi mentre le porte seriali, mouse e stampanti parallele sono tutti dispositivi a caratteri. C'è uno schema per denominare i tipi di dispositivo ma nella stragrande maggioranza dei casi questi non seguono una logica particolare.


total 724
lrwxrwxrwx    1 root     root           13 Sep 28 18:06 MAKEDEV -> /sbin/MAKEDEV
crw-rw----    1 root     audio     14,  14 Oct  7 16:26 admmidi0
crw-rw----    1 root     audio     14,  30 Oct  7 16:26 admmidi1
lrwxrwxrwx    1 root     root           11 Oct  7 16:26 amidi -> /dev/amidi0
crw-rw----    1 root     audio     14,  13 Oct  7 16:26 amidi0
crw-rw----    1 root     audio     14,  29 Oct  7 16:26 amidi1
crw-rw----    1 root     audio     14,  11 Oct  7 16:26 amixer0
crw-rw----    1 root     audio     14,  27 Oct  7 16:26 amixer1
drwxr-xr-x    2 root     root         4096 Sep 28 18:05 ataraid
lrwxrwxrwx    1 root     root           11 Oct  7 16:26 audio -> /dev/audio0
crw-rw----    1 root     audio     14,   4 Oct  7 16:26 audio0
crw-rw----    1 root     audio     14,  20 Oct  7 16:26 audio1
crw-rw----    1 root     audio     14,   7 Mar 15  2002 audioctl
lrwxrwxrwx    1 root     root            9 Oct 14 22:51 cdrom -> /dev/scd1
lrwxrwxrwx    1 root     root            9 Oct 14 22:52 cdrom1 -> /dev/scd0
crw-------    1 root     tty        5,   1 Jan 19 20:47 console
lrwxrwxrwx    1 root     root           11 Sep 28 18:06 core -> /proc/kcore
crw-rw----    1 root     audio     14,  10 Oct  7 16:26 dmfm0
crw-rw----    1 root     audio     14,  26 Oct  7 16:26 dmfm1
crw-rw----    1 root     audio     14,   9 Oct  7 16:26 dmmidi0
crw-rw----    1 root     audio     14,  25 Oct  7 16:26 dmmidi1
lrwxrwxrwx    1 root     root            9 Oct  7 16:26 dsp -> /dev/dsp0
crw-rw----    1 root     audio     14,   3 Oct  7 16:26 dsp0
crw-rw----    1 root     audio     14,  19 Oct  7 16:26 dsp1
crw--w----    1 root     video     29,   0 Mar 15  2002 fb0
crw--w----    1 root     video     29,   1 Mar 15  2002 fb0autodetect
crw--w----    1 root     video     29,   0 Mar 15  2002 fb0current
crw--w----    1 root     video     29,  32 Mar 15  2002 fb1
crw--w----    1 root     video     29,  33 Mar 15  2002 fb1autodetect
crw--w----    1 root     video     29,  32 Mar 15  2002 fb1current
lrwxrwxrwx    1 root     root           13 Sep 28 18:05 fd -> /proc/self/fd
brw-rw----    1 root     floppy     2,   0 Mar 15  2002 fd0
brw-rw----    1 root     floppy     2,   1 Mar 15  2002 fd1
crw--w--w-    1 root     root       1,   7 Sep 28 18:06 full
brw-rw----    1 root     disk       3,   0 Mar 15  2002 hda
brw-rw----    1 root     disk       3,  64 Mar 15  2002 hdb
brw-rw----    1 root     disk      22,   0 Mar 15  2002 hdc
brw-rw----    1 root     disk      22,  64 Mar 15  2002 hdd
drwxr-xr-x    2 root     root        12288 Sep 28 18:05 ida
prw-------    1 root     root            0 Jan 19 20:46 initctl
brw-rw----    1 root     disk       1, 250 Mar 15  2002 initrd
drwxr-xr-x    2 root     root         4096 Sep 28 18:05 input
crw-rw----    1 root     dialout   45, 128 Mar 15  2002 ippp0
crw-rw----    1 root     dialout   45,   0 Mar 15  2002 isdn0
crw-rw----    1 root     dialout   45,  64 Mar 15  2002 isdnctrl0
crw-rw----    1 root     dialout   45, 255 Mar 15  2002 isdninfo
crw-------    1 root     root      10,   4 Mar 15  2002 jbm
crw-r-----    1 root     kmem       1,   2 Sep 28 18:06 kmem
brw-rw----    1 root     cdrom     24,   0 Mar 15  2002 lmscd
crw-------    1 root     root      10,   0 Mar 15  2002 logibm
brw-rw----    1 root     disk       7,   0 Sep 28 18:06 loop0
brw-rw----    1 root     disk       7,   1 Sep 28 18:06 loop1
crw-rw----    1 root     lp         6,   0 Mar 15  2002 lp0
crw-rw----    1 root     lp         6,   1 Mar 15  2002 lp1
crw-rw----    1 root     lp         6,   2 Mar 15  2002 lp2
crw-r-----    1 root     kmem       1,   1 Sep 28 18:06 mem
lrwxrwxrwx    1 root     root           10 Oct  7 16:26 midi -> /dev/midi0
crw-rw----    1 root     audio     14,   2 Oct  7 16:26 midi0
crw-rw----    1 root     audio     14,  18 Oct  7 16:26 midi1
lrwxrwxrwx    1 root     root           11 Oct  7 16:26 mixer -> /dev/mixer0
crw-rw-rw-    1 root     root      14,   0 Nov 11 16:22 mixer0
crw-rw----    1 root     audio     14,  16 Oct  7 16:26 mixer1
lrwxrwxrwx    1 root     root           11 Oct  7 06:50 modem -> /dev/ttyLT0
crw-rw----    1 root     audio     31,   0 Mar 15  2002 mpu401data
crw-rw----    1 root     audio     31,   1 Mar 15  2002 mpu401stat
crw-rw----    1 root     audio     14,   8 Oct  7 16:26 music
crw-rw-rw-    1 root     root       1,   3 Sep 28 18:06 null
crw-rw-rw-    1 root     root     195,   0 Jan  6 03:03 nvidia0
crw-rw-rw-    1 root     root     195,   1 Jan  6 03:03 nvidia1
crw-rw-rw-    1 root     root     195, 255 Jan  6 03:03 nvidiactl
crw-rw----    1 root     lp         6,   0 Mar 15  2002 par0
crw-rw----    1 root     lp         6,   1 Mar 15  2002 par1
crw-rw----    1 root     lp         6,   2 Mar 15  2002 par2
-rw-r--r--    1 root     root       665509 Oct  7 16:41 pcm
crw-r-----    1 root     kmem       1,   4 Sep 28 18:06 port
crw-rw----    1 root     dip      108,   0 Sep 28 18:07 ppp
crw-------    1 root     root      10,   1 Mar 15  2002 psaux
crw-rw-rw-    1 root     root       1,   8 Sep 28 18:06 random
crw-rw----    1 root     root      10, 135 Mar 15  2002 rtc
brw-rw----    1 root     cdrom     11,   0 Mar 15  2002 scd0
brw-rw----    1 root     cdrom     11,   1 Mar 15  2002 scd1
brw-rw----    1 root     disk       8,   0 Mar 15  2002 sda
brw-rw----    1 root     disk       8,   1 Mar 15  2002 sda1
brw-rw----    1 root     disk       8,   2 Mar 15  2002 sda2
brw-rw----    1 root     disk       8,   3 Mar 15  2002 sda3
brw-rw----    1 root     disk       8,   4 Mar 15  2002 sda4
brw-rw----    1 root     disk       8,  16 Mar 15  2002 sdb
brw-rw----    1 root     disk       8,  17 Mar 15  2002 sdb1
brw-rw----    1 root     disk       8,  18 Mar 15  2002 sdb2
brw-rw----    1 root     disk       8,  19 Mar 15  2002 sdb3
brw-rw----    1 root     disk       8,  20 Mar 15  2002 sdb4
crw-rw----    1 root     audio     14,   1 Oct  7 16:26 sequencer
lrwxrwxrwx    1 root     root           10 Oct  7 16:26 sequencer2 -> /dev/music
lrwxrwxrwx    1 root     root            4 Sep 28 18:05 stderr -> fd/2
lrwxrwxrwx    1 root     root            4 Sep 28 18:05 stdin -> fd/0
lrwxrwxrwx    1 root     root            4 Sep 28 18:05 stdout -> fd/1
crw-rw-rw-    1 root     tty        5,   0 Sep 28 18:06 tty
crw-------    1 root     root       4,   0 Sep 28 18:06 tty0
crw-------    1 root     root       4,   1 Jan 19 14:59 tty1
crw-rw----    1 root     dialout   62,  64 Oct  7 06:50 ttyLT0
crw-rw----    1 root     dialout    4,  64 Mar 15  2002 ttyS0
crw-rw----    1 root     dialout    4,  65 Mar 15  2002 ttyS1
crw-rw----    1 root     dialout    4,  66 Mar 15  2002 ttyS2
crw-rw----    1 root     dialout    4,  67 Mar 15  2002 ttyS3
crw-rw----    1 root     dialout  188,   0 Mar 15  2002 ttyUSB0
crw-rw----    1 root     dialout  188,   1 Mar 15  2002 ttyUSB1
cr--r--r--    1 root     root       1,   9 Jan 19 20:46 urandom
drwxr-xr-x    2 root     root         4096 Sep 28 18:05 usb
prw-r-----    1 root     adm             0 Jan 19 14:58 xconsole
crw-rw-rw-    1 root     root       1,   5 Sep 28 18:06 zero

Alcuni file di dispositivo comuni, così come quelli equivalenti sotto Windows, che si dovrebbero ricordare sono:

/dev/ttyS0 (Prima porta di comunicazione, COM1)

Prima porta seriale (mouse, modem).

/dev/psaux (PS/2)

connessione per il mouse PS/2 (mouse, tastiere).

/dev/lp0 (Prima porta di stampa, LPT1)

Prima porta parallela (stampanti, scanner, etc).

/dev/dsp (Primo dispositivo audio)

Il nome DSP deriva dal termine "digital signal processor" (processore per segnali digitali), un chip processore specializzato ottimizzato per l'analisi del segnale digitale. Le schede audio possono usare un chip DSP dedicato, o possono implementare le funzioni con un gruppo di dispositivi discreti. Altri termini che possono essere usati per questo dispositivo sono voce digitalizzata e PCM.

/dev/usb (Dispositivi USB)

Questa sottodirectory contiene la maggior parte dei nodi di dispositivo USB. Le assegnazioni dei nomi dei dispositivi avvengono in modo piuttosto semplice per cui non è necessario alcun approfondimento.

/dev/sda (C:\, SCSI device)

Il primo dispositivo SCSI (HDD, Memory Stick, dispositivi esterni a memoria di massa come unità CD-ROM sui portatili, etc).

/dev/scd (D:\, dispositivo CD-ROM SCSI)

Il primo dispositivo CD-ROM SCSI.

/dev/js0 (Standard gameport joystick)

Il primo dispositivo joystick.

I dispositivi sono definiti in base al tipo, come "a blocchi" o "a caratteri", e in base al numero "primario" e "secondario". Il numero primario è usato per classificare un dispositivo e il numero secondario è usato per identificare un tipo di dispositivo specifico. Per esempio, tutti i dispositivi IDE connessi al controller primario hanno un numero principale uguale a 3. I dispositivi master e slave, così come le partizioni singole sono ulteriormente definite attraverso i numeri secondari. Questi sono i due numeri che compaiono prima della data nella schermata che segue:

# ls -l /dev/hd*


brw-rw----    1 root     disk       3,   0 Mar 15  2002 /dev/hda
brw-rw----    1 root     disk       3,   1 Mar 15  2002 /dev/hda1
brw-rw----    1 root     disk       3,  10 Mar 15  2002 /dev/hda10
brw-rw----    1 root     disk       3,  11 Mar 15  2002 /dev/hda11
brw-rw----    1 root     disk       3,  12 Mar 15  2002 /dev/hda12
brw-rw----    1 root     disk       3,  13 Mar 15  2002 /dev/hda13
brw-rw----    1 root     disk       3,  14 Mar 15  2002 /dev/hda14
brw-rw----    1 root     disk       3,  15 Mar 15  2002 /dev/hda15
brw-rw----    1 root     disk       3,  16 Mar 15  2002 /dev/hda16
brw-rw----    1 root     disk       3,  17 Mar 15  2002 /dev/hda17
brw-rw----    1 root     disk       3,  18 Mar 15  2002 /dev/hda18
brw-rw----    1 root     disk       3,  19 Mar 15  2002 /dev/hda19
brw-rw----    1 root     disk       3,   2 Mar 15  2002 /dev/hda2
brw-rw----    1 root     disk       3,  20 Mar 15  2002 /dev/hda20
brw-rw----    1 root     disk       3,   3 Mar 15  2002 /dev/hda3
brw-rw----    1 root     disk       3,   4 Mar 15  2002 /dev/hda4
brw-rw----    1 root     disk       3,   5 Mar 15  2002 /dev/hda5
brw-rw----    1 root     disk       3,   6 Mar 15  2002 /dev/hda6
brw-rw----    1 root     disk       3,   7 Mar 15  2002 /dev/hda7
brw-rw----    1 root     disk       3,   8 Mar 15  2002 /dev/hda8
brw-rw----    1 root     disk       3,   9 Mar 15  2002 /dev/hda9
brw-rw----    1 root     disk       3,  64 Mar 15  2002 /dev/hdb
brw-rw----    1 root     disk       3,  65 Mar 15  2002 /dev/hdb1
brw-rw----    1 root     disk       3,  74 Mar 15  2002 /dev/hdb10
brw-rw----    1 root     disk       3,  75 Mar 15  2002 /dev/hdb11
brw-rw----    1 root     disk       3,  76 Mar 15  2002 /dev/hdb12
brw-rw----    1 root     disk       3,  77 Mar 15  2002 /dev/hdb13
brw-rw----    1 root     disk       3,  78 Mar 15  2002 /dev/hdb14
brw-rw----    1 root     disk       3,  79 Mar 15  2002 /dev/hdb15
brw-rw----    1 root     disk       3,  80 Mar 15  2002 /dev/hdb16
brw-rw----    1 root     disk       3,  81 Mar 15  2002 /dev/hdb17
brw-rw----    1 root     disk       3,  82 Mar 15  2002 /dev/hdb18
brw-rw----    1 root     disk       3,  83 Mar 15  2002 /dev/hdb19
brw-rw----    1 root     disk       3,  66 Mar 15  2002 /dev/hdb2
brw-rw----    1 root     disk       3,  84 Mar 15  2002 /dev/hdb20
brw-rw----    1 root     disk       3,  67 Mar 15  2002 /dev/hdb3
brw-rw----    1 root     disk       3,  68 Mar 15  2002 /dev/hdb4
brw-rw----    1 root     disk       3,  69 Mar 15  2002 /dev/hdb5
brw-rw----    1 root     disk       3,  70 Mar 15  2002 /dev/hdb6
brw-rw----    1 root     disk       3,  71 Mar 15  2002 /dev/hdb7
brw-rw----    1 root     disk       3,  72 Mar 15  2002 /dev/hdb8
brw-rw----    1 root     disk       3,  73 Mar 15  2002 /dev/hdb9
brw-rw----    1 root     disk      22,   0 Mar 15  2002 /dev/hdc
brw-rw----    1 root     disk      22,  64 Mar 15  2002 /dev/hdd

Il numero primario per entrambi i dispositivi hda e hdb è 3. Naturalmente, il numero secondario cambia per ogni specifica partizione. La definizione di ogni categoria di numero principale può essere esaminata guardando il contenuto del file /usr/src/linux/include/linux/major.h . Il file devices.txt inoltre documenta i numeri principali e secondari e si trova nella directory /usr/src/linux/Documentation. Questo file definisce i numeri principali. Quasi tutti i file di dispositivo sono creati, in modo predefinito, al momento dell'installazione. Comunque, si può sempre creare un dispositivo usando il comando mknod o lo script MAKEDEV che si trova nella stessa directory /dev. I dispositivi possono essere creati con questo programma di utilità indicando il dispositivo da creare, il tipo di dispositivo (a blocchi o a caratteri) e i numeri principale e secondario. Per esempio, supponiamo che sia stato accidentalmente cancellato il file /dev/ttyS0 (COM1 sotto Windows); è possibile ricrearlo usando il seguente comando:

# mknod ttyS0 c 4 64

Per i più pigri si può semplicemente eseguire lo script MAKEDEV in questo modo:

# MAKEDEV *

che ricreerà tutti i file di dispositivo in base ai dispositivi rilevati.

Eventualmente la directory /dev può contenere anche un file MAKEDEV.local per la creazione di file di dispositivi locali.

In generale, e come richiesto dal FSSTND, MAKEDEV è capace di creare qualsiasi dispositivo rilevabile nel sistema, non quelli installati da una particolare implementazione.

Qualcuno potrebbe meravigliarsi del fatto che Linux usi un tale sistema primitivo per referenziare i dispositivi; la risposta è che non si è ancora in grado di concepire un meccanismo sufficientemente sofisticato, che fornisca vantaggi sufficienti per il sistema corrente, tale da pervenire a un'adozione diffusa.

Fino ad oggi (a partire dalla versione 2.4 del kernel), il miglior tentativo è stato fatto da Richard Gooch del CSIRO. È chiamato devfsd ed è stato una parte del kernel per molti anni. Ha avuto i consenso degli sviluppatori del kernel e dallo stesso Linus; i dettagli di questa implementazione si possono trovare in /usr/src/linux/Documentation/filesystems/devfs/README. Qui di seguito si riporta un estratto di questo documento.

Devfs è un'alternativa ai dispositivi speciali "reali" a caratteri e a blocchi sul filesystem root. I gestori dei dispositivi del kernel possono registrare i dispositivi per nome piuttosto che registrarli attraverso i numeri principale e secondario. Questi dispositivi appariranno in devfs automaticamente, coi permessi d'accesso fissati in modo predefinito dal gestore dei dispositivi. Un demone (devfsd) può essere usato per sovrascrivere queste impostazioni predefinite. Devfs è stato nel kernel sin dalla versione 2.3.46.

DA NOTARE che devfs è completamente opzionale. Se si preferiscono i vecchi nodi di dispositivo basati sui nomi dei dischi, si deve solamente lasciare CONFIG_DEVFS_FS=n (default). In questo caso non cambierà niente. SI FA RILEVARE INOLTRE che se si abilita devfs, le impostazioni predefinite sono tali da mantenere la piena compatibilità coi vecchi nomi di dispositivo.

Ci sono due aspetti relativi a devfs: uno è il "namespace" del dispositivo sottostante, che è un "namespace" esattamente come qualsiasi filesystem montato. L'altro aspetto è il codice di filesystem che fornisce una vista dei "namespace" del dispositivo. La ragione di questa distinzione è che devfs può essere montato diverse volte, e a ogni montaggio viene mostrato lo stesso "namespace" del dispositivo. I cambiamenti coinvolgono globalmente tutti i filesystem devfs montati. Inoltre, poiché il namespace devfs esiste senza che devfs sia montato, si può montare facilmente il filesystem root riferendosi ad una voce nel namespace devfs.

Il dispendio di devfs è un piccolo incremento della dimensione del codice del kernel e del consumo di memoria. Circa 7 pagine di codice (alcune delle quali nelle sezioni __init) e 72 byte per ogni voce nel namespace. Un sistema modesto ha solo un paio di centinaia di voci di dispositivo, così questo costa qualche pagina in più. Non è paragonabile al suggerimento di mettere /dev su una ramdisc.

Su una macchina tipica, il dispendio è sotto lo 0.2 percento. Su un sistema modesto con 64 MBytes di RAM, il consumo è sotto lo 0.1 percento. Le accuse di "bloatware" lanciata a devfs non sono giustificate.

A partire dal kernel versione 2.6, devfs è stato dichiarato obsoleto ed è stato sostituito da udev. Un sistema molto simile (per lo meno dal punto di vista dell'utente finale) a devfs ma che funziona interamente in "userspace". Una panoramica di udev si può trovare in http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf