Na interface de programação do Linux , §14.1
Cada arquivo de dispositivo possui um número de identificação principal e um número de identificação menor. O ID principal identifica a classe geral do dispositivo e é usado pelo kernel para procurar o driver apropriado para esse tipo de dispositivo. O ID secundário identifica exclusivamente um dispositivo específico dentro de uma classe geral. Os IDs principais e secundários de um arquivo de dispositivo são exibidos pelo comando ls -l.
[...]
Cada driver de dispositivo registra sua associação com um ID de dispositivo principal específico, e essa associação fornece a conexão entre o arquivo especial do dispositivo e o dispositivo. O nome do arquivo do dispositivo não tem relevância quando o kernel procura pelo driver do dispositivo.
Veja também este capítulo antigo (2001) Linux Device Drivers (2e) .
ou seja, a intenção é fornecer um mapeamento exclusivo de instância major: minor to device: para cada tipo de dispositivo. Estritamente, você pode ter dois dispositivos distintos com o mesmo major: menor, desde que um seja char e um seja block:
# 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
No Linux, a qualquer momento no sistema, os principais: números menores para cada tipo de dispositivo são únicos. No entanto, os números podem mudar com o tempo e não precisam ser os mesmos nos diferentes sistemas Linux (mesmo a mesma distribuição, kernel e hardware). Observe que os dispositivos de caracteres e de bloco têm espaços de numeração distintos, por exemplo, o bloco principal 1 é atribuído aos discos RAM, o caractere principal 1 é atribuído a um conjunto de dispositivos do kernel, incluindo nulo e zero.
Historicamente, os majores de dispositivos eram (principalmente) alocados estaticamente por meio de um registro (também ainda presente, embora não mantido, na fonte do kernel Documentation/devices.txt
). Atualmente, muitos dispositivos são alocados dinamicamente, isso é gerenciado pelo udev e os mapeamentos visíveis no /proc/devices
. Os dispositivos fixos ainda existem em incude/uapi/linux/major.h
(movidos recentemente de include/major.h
)
Agora, embora a combinação major: minor identifique exclusivamente instâncias específicas de dispositivos, não há nada para impedir a criação de vários nós (arquivos) de dispositivos que se referem ao mesmo dispositivo. Eles nem precisam ser criados /dev
(mas precisam estar em um sistema de arquivos que suporte a criação de nós do dispositivo e não é montado com a nodev
opção).
Um uso comum é criar dispositivos zero, nulo e aleatórios duplicados em um 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
Os nomes são apenas aliases, o kernel não se importa muito com a maioria dos nomes ou locais, se importa com o número principal para selecionar o driver correto, e o motorista (geralmente) se importa com o número menor para selecionar o instância correta.
A maioria dos nomes é simplesmente convenção (embora alguns sejam definidos pelo POSIX ). Observe também que um dispositivo pode se registrar para vários números principais; verifique o sd
driver /proc/devices
; um nome de módulo de driver ( .ko
) não precisa ser igual ao nome do dispositivo e não deve ser o mesmo que o nó do dispositivo /dev
, e um único módulo de driver pode gerenciar vários dispositivos lógicos / físicos ou nomes de dispositivos.
Para recapitular: você pode ter dois ou mais nós de dispositivo (dentro /dev/
ou fora) que têm o mesmo número maior: números menores, mas, se forem do mesmo tipo, se referirão ao mesmo dispositivo. Você pode ter um driver que pode lidar com várias instâncias principais, mas dentro do kernel e dentro do driver, para cada tipo (caractere ou bloco), o principal: número menor é usado para se referir a um dispositivo específico (principal) e uma instância específica ( menor) do dispositivo.
Você não pode ter dois nós de dispositivo com o mesmo tipo e principal: menor e esperar que eles acessem dois dispositivos lógicos ou físicos diferentes. Quando um dispositivo está sendo acessado, o kernel seleciona um driver com base no tipo e no número principal (e não no nome do nó do dispositivo) e, por convenção, o número menor seleciona deterministicamente uma instância ou sub-função específica.
Atualização
Alguma história interessante e algumas perspectivas do * BSD podem ser encontradas na apresentação do BSDCon de Poul-Henning Kamp em 2002 :
https://www.usenix.org/legacy/events/bsdcon/full_papers/kamp/kamp_html/
Se você voltar no tempo para 1978 (cortesia da Alcatel-Lucent, o Jornal Técnico do Sistema Bell de julho a agosto de 1978), o ' Sistema de compartilhamento de tempo Unix ' o define claramente (pág. 1937):
Os dispositivos são caracterizados por um número principal de dispositivo, um número menor de dispositivo e uma classe (bloco ou caractere). Para cada classe, há uma matriz de pontos de entrada nos drivers de dispositivo. O número do dispositivo principal é usado para indexar a matriz ao chamar o código para um driver de dispositivo específico. O número menor do dispositivo é passado para o driver do dispositivo como argumento. O número menor não tem significado diferente daquele atribuído pelo motorista. Normalmente, o driver usa o número menor para acessar um dos vários dispositivos físicos idênticos.