Z interfejsu programowania systemu Linux , § 14.1
Każdy plik urządzenia ma główny numer identyfikacyjny i mniejszy numer identyfikacyjny. Główny identyfikator identyfikuje ogólną klasę urządzenia i jest używany przez jądro do wyszukiwania odpowiedniego sterownika dla tego typu urządzenia. Niewielki identyfikator jednoznacznie identyfikuje określone urządzenie w klasie ogólnej. Główne i mniejsze identyfikatory pliku urządzenia są wyświetlane za pomocą polecenia ls -l.
[...]
Każdy sterownik urządzenia rejestruje swoje powiązanie z określonym głównym identyfikatorem urządzenia, a to powiązanie zapewnia połączenie między specjalnym plikiem urządzenia a urządzeniem. Nazwa pliku urządzenia nie ma znaczenia, gdy jądro szuka sterownika urządzenia.
Zobacz także ten stary (2001 ) rozdział Linux Device Drivers (2e) .
tzn. celem jest zapewnienie unikalnego mapowania major: minor na device: instance dla każdego typu urządzenia. Ściśle, to może mieć dwa różne urządzeń z tym samym główny: poboczny, tak długo, jak jeden jest char a jeden blok:
# 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
W systemie Linux w dowolnym momencie w jednym systemie główne: mniejsze liczby dla każdego typu urządzenia są unikalne. Liczby te mogą się jednak zmieniać z czasem i nie muszą być takie same w różnych systemach Linux (nawet ta sama dystrybucja, jądro i sprzęt). Zauważ, że urządzenia znakowe i blokowe mają odrębne spacje numeracyjne, np. Blok główny 1 jest przypisany do dysków RAM, char główny 1 jest przypisany do zestawu urządzeń jądra, w tym zerowego i zerowego.
Historycznie główne urządzenia były (przeważnie) statycznie przydzielane przez rejestr (również nadal obecny, choć nieobsługiwany, w źródle jądra Documentation/devices.txt
). Obecnie wiele urządzeń jest przydzielanych dynamicznie, zarządza nimi udev , a mapowania są widoczne w /proc/devices
. Naprawione urządzenia nadal istnieją w incude/uapi/linux/major.h
(ostatnio przeniesione include/major.h
)
Teraz, chociaż kombinacja główna: niewielka jednoznacznie identyfikuje określone wystąpienia urządzenia, nic nie stoi na przeszkodzie, aby utworzyć wiele węzłów urządzeń (plików), które odnoszą się do tego samego urządzenia. Nie trzeba ich nawet tworzyć /dev
(ale muszą znajdować się w systemie plików, który obsługuje tworzenie węzłów urządzeń i nie jest montowany z nodev
opcją).
Powszechnym zastosowaniem jest tworzenie duplikatów zerowych, zerowych i losowych urządzeń w 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
Nazwy są tylko aliasami, jądro nie dba o większość nazw lub lokalizacji, dba o numer główny, aby mógł wybrać odpowiedni sterownik, a sterownik (zwykle) dba o mniejszy numer, aby mógł wybrać poprawna instancja.
Większość nazw to po prostu konwencje (choć niektóre są zdefiniowane przez POSIX ). Zauważ też, że jedno urządzenie może zarejestrować wiele głównych numerów, sprawdź sd
sterownik /proc/devices
; nazwa modułu sterownika ( .ko
) nie musi być taka sama jak nazwa urządzenia i nie musi być taka sama jak nazwa węzła urządzenia w /dev
, a pojedynczy moduł sterownika może zarządzać wieloma logicznymi / fizycznymi urządzeniami lub nazwami urządzeń.
Reasumując: możesz mieć dwa lub więcej węzłów urządzeń (w /dev/
lub w innym miejscu), które mają te same główne: mniejsze liczby, ale jeśli są tego samego typu, odnoszą się do tego samego urządzenia. Możesz mieć jeden sterownik, który może obsługiwać wiele głównych instancji, ale w jądrze i w sterowniku, dla każdego typu (char lub block) numer major: minor odnosi się do konkretnego urządzenia (major) i określonej instancji ( drobne) urządzenia.
Nie można mieć dwóch węzłów urządzeń tego samego typu i głównych: mniejszych i oczekiwać, że uzyskają dostęp do dwóch różnych urządzeń logicznych lub fizycznych. Podczas uzyskiwania dostępu do urządzenia jądro wybiera jeden sterownik na podstawie typu i numeru głównego (a nie na podstawie nazwy węzła urządzenia), a zgodnie z konwencją liczba podrzędna deterministycznie wybiera określoną instancję lub podfunkcję.
Aktualizacja
Trochę interesującej historii i niektóre * perspektywy BSD można znaleźć w prezentacji BSDCon Poul-Henning Kamp 2002 :
https://www.usenix.org/legacy/events/bsdcon/full_papers/kamp/kamp_html/
Jeśli cofniesz się w czasie do 1978 r. (Dzięki uprzejmości Alcatela-Lucenta, Bell System Technical Journal, lipiec-sierpień 1978 r.), „ Unix Time Sharing System ” jasno to określa (str. 1937):
Urządzenia charakteryzują się głównym numerem urządzenia, pobocznym numerem urządzenia i klasą (blok lub znak). Dla każdej klasy istnieje szereg punktów wejścia do sterowników urządzeń. Główny numer urządzenia służy do indeksowania tablicy podczas wywoływania kodu dla określonego sterownika urządzenia. Niewielki numer urządzenia jest przekazywany do sterownika urządzenia jako argument. Mniejszy numer nie ma innego znaczenia niż przypisane mu przez kierowcę. Zwykle sterownik używa numeru podrzędnego, aby uzyskać dostęp do jednego z kilku identycznych urządzeń fizycznych.