I Kapittel 8, installerte vi udev nissen når udev ble bygget. Før vi går inn i detaljer om hvordan dette fungerer, er en kort historie om tidligere metoder for å håndtere utstyr i orden.
Generelt brukte Linux systemer tradisjonelt en statisk
enhetsopprettingsmetode , hvor mange enhetsnoder ble opprettet under
/dev
(noen ganger bokstavelig talt
tusenvis av noder), uavhengig av om de tilsvarende maskinvareenhetene
faktisk eksisterte. Dette ble vanligvis gjort via en MAKEDEV skript, som inneholder et
antall anrop til mknod
programmet med det aktuelle hoved- og mindre enhetsnumre for alle
mulige enheter som kan eksistere i verden.
Ved å bruke udev metoden vil bare de enhetene som oppdages av kjernen
få enhetsnoder opprettet for dem. Fordi disse enhetsnodene vil være
opprettet hver gang systemet starter, vil de bli lagret på et
devtmpfs
filsystem (et virtuelt
filsystem som ligger utelukkende i systemminnet). Enhetsnoder krever
ikke mye plass, så minnet som brukes er ubetydelig.
I februar 2000 ble et nytt filsystem kalt devfs
flettet inn i 2.3.46-kjernen og ble gjort
tilgjengelig under 2.4-serien med stabile kjerner. Selv om den var
til stede i selve kjernekilden, fikk denne metoden for å lage
enheter dynamisk aldri overveldende støtte fra kjerneutviklere.
Hovedproblemet med tilnærmingen vedtatt av devfs
var måten den håndterte enheten på ved
oppdagelse, opprettelse og navngivning. Det siste problemet
enhetsnavnet på en enhetsnode, var kanskje den mest kritiske. Det
er generelt akseptert at hvis enhetsnavn kan konfigureres, så skal
enhetsnavn politikken være opp til en systemadministrator, og ikke
pålagt dem av en spesiell(e) utvikler(e). devfs
filsystemet led også av kjøreforhold som
var iboende i utformingen og ikke kunne fikses uten en betydelig
revisjon av kjernen. devfs
ble
merket som utdatert i lang tid, og ble til slutt fjernet fra
kjernen i juni 2006.
Med utviklingen av det ustabile 2.5 kjernetreet, senere utgitt som
2.6-serien med stabile kjerner, et nytt virtuelt filsystem kalt
sysfs
ble opprettet. Jobben til
sysfs
er å eksportere en visning av
systemets maskinvarekonfigurasjon til brukerprosesser. Med dette
brukersynlige representasjonen, ble det mulig å utvikle et
brukerområde erstatning for devfs
.
sysfs
filsystemet ble kort nevnt
ovenfor. Man kan lure på hvordan sysfs
vet om enhetene som finnes på et system
og hvilke enhetsnumre som skal brukes for dem. Drivere som har
blitt kompilert inn i kjernen, registrerer objektene deres
direkte med sysfs
(devtmpfs
internt) når de oppdages av kjernen. For drivere kompilert som
moduler, vil registreringen skje når modulen blir lastet. Først
når sysfs
filsystemet er montert
(på /sys
), data som driverne
registrerer med sysfs
er
tilgjengelig for brukerområdets prosesser og til udevd for
behandling (inkludert modifikasjoner av enhetens noder).
Enhetsfiler opprettes av kjernen i devtmpfs
filsystemet. Enhver driver som
ønsker å registrere en enhetsnode vil bruke devtmpfs
(via driverkjernen) for å gjøre det.
Når en devtmpfs
forekomst er
montert på /dev
, vil enhetsnoden i
utgangspunktet bli eksponert for brukerrom med et fast navn,
tillatelser og eieren.
Kort tid senere vil kjernen sende en uevent til udevd. Basert på reglene
spesifisert i filene i /etc/udev/rules.d
, /usr/lib/udev/rules.d
, og /run/udev/rules.d
mappene, udevd vil opprette flere
symbolkoblinger til enhetsnoden, eller endre tillatelsene, eieren
eller gruppen, eller endre den interne udevd databaseoppføring (navn)
for det objektet.
Reglene i disse tre mappene er nummererte og alle tre mappene
slås sammen. Hvis udevd ikke finner en regel for
enheten den oppretter, vil den opprettholde tillatelsene og
eierskapet som devtmpfs
brukte i
utgangspunktet.
Enhetsdrivere kompilert som moduler kan ha innebygde aliaser.
Aliaser er synlige i utdataene til modinfo programmet og er
vanligvis relatert til de bussspesifikke identifikatorene til
enheter støttet av en modul. For eksempel snd-fm801 driveren støtter PCI-enheter
med leverandør-ID 0x1319 og enhets-ID 0x0801, og har et alias
“pci:v00001319d00000801sv*sd*bc04sc01i*”.
For de fleste enheter eksporterer bussdriveren aliaset til
driveren som vil håndtere enheten via sysfs
. F.eks, /sys/bus/pci/devices/0000:00:0d.0/modalias
filen kan inneholde strengen “pci:v00001319d00000801sv00001319sd00001319bc04sc01i00”.
Standardreglene som følger med udev vil gjøre at udevd kaller /sbin/modprobe med innholdet i
MODALIAS
uevent miljøvariabel (som
skal være samme som innholdet i modalias
filen i sysfs), laster dermed alle
moduler hvis aliaser samsvarer med denne strengen etter jokertegn
ekspansjonen.
I dette eksemplet betyr dette at i tillegg til snd-fm801, det foreldede (og uønskede) forte driveren vil bli lastet hvis den er tilgjengelig. Se nedenfor for måter lasting av uønskede drivere kan bli forhindret.
Kjernen selv er også i stand til å laste moduler for nettverksprotokoller, filsystemer og NLS-støtte på forespørsel.
Når du kobler til en enhet, for eksempel en Universal Serial Bus (USB) MP3 spiller, gjenkjenner kjernen at enheten nå er tilkoblet og genererer en uevent. Denne uevent håndteres deretter av udevd som beskrevet ovenfor.
Det er noen mulige problemer når det kommer til å automatisk opprette enhetsnoder.
Udev vil bare laste en modul hvis den har et bussspesifikt alias
og bussdriveren eksporterer de nødvendige aliasene til
sysfs
. I andre tilfeller bør man
ordne modullasting på andre måter. Med Linux-6.4.12, udev er
kjent for å laste riktig skrevne drivere for INPUT, IDE, PCI,
USB, SCSI, SERIO, og FireWire-enheter.
For å finne ut om enhetsdriveren du trenger har den nødvendige
støtten for udev, kjør modinfo med modulnavnet som
argument. Prøv nå å finne enhetsmappen under /sys/bus
og sjekk om det er en modalias
fil der.
Hvis modalias
filen finnes i
sysfs
, driveren støtter enheten
og kan snakke med den direkte, men har ikke aliaset, det er en
feil i driveren. Last inn driveren uten hjelp fra udev og forvent
at problemet blir fikset senere.
Hvis det ikke er noen modalias
fil
i den aktuelle mappen under /sys/bus
, dette betyr at kjerneutviklerne ennå
ikke har lagt til støtte for modalias for denne busstypen. Med
Linux-6.4.12, dette er tilfellet med ISA busser. Forvent at dette
problemet blir løst i senere kjerneversjoner.
Udev er ikke ment å laste “innpakkede (wrapper)” drivere som f.eks snd-pcm-oss og ikke-maskinvaredrivere som f.eks loop i det hele tatt.
Hvis den “innpakkede” modulen bare forbedrer
funksjonalitet levert av en annen modul (f.eks., snd-pcm-oss forbedrer funksjonaliteten
til snd-pcm ved å gjøre
lydkortene tilgjengelige for OSS applikasjoner), konfigurer
modprobe til å
laste inn innpakkningen etter at udev har lastet den innpakkede
modulen. For å gjøre dette, legg til en “softdep”
linje til den tilsvarende /etc/modprobe.d/
filen. For eksempel:
<filename>
.conf
softdep snd-pcm post: snd-pcm-oss
Merk at “softdep” kommandoen tillater også
pre:
avhengigheter, eller en
blanding av begge (Før) pre:
og
(Etter) post:
avhengigheter. Se
modprobe.d(5)
manualside for mer
informasjon om “softdep” syntaks og muligheter.
Hvis den aktuelle modulen ikke er en innpakning og er nyttig i
seg selv, konfigurer modules oppstartsskriptet til å
laste denne modulen ved systemoppstart. For å gjøre dette, legg
til modulnavnet i /etc/sysconfig/modules
filen på en egen linje.
Dette fungerer også for innpakningsmoduler, men er ikke optimalt
i så fall.
Enten ikke bygg modulen, eller svarteliste den i en /etc/modprobe.d/blacklist.conf
fil som gjort
med forte modulen i
eksemplet nedenfor:
blacklist forte
Svartelistede moduler kan fortsatt lastes inn manuelt med eksplisitt modprobe kommando.
Dette skjer vanligvis hvis en regel uventet samsvarer med en enhet. For eksempel kan en dårlig skrevet regel matche både en SCSI-disk (som ønsket) og den tilsvarende generiske SCSI-enheten (feil) av leverandøren. Finn den krenkende regelen og gjør den mer spesifikk, ved hjelp av udevadm info kommandoen.
Dette kan være en annen manifestasjon av det forrige problemet.
Hvis ikke, og regelen din bruker sysfs
attributter, kan det være et problem
med kjernetiming, som bør fikses i senere kjerner. Foreløpig kan
du omgå det ved å lage en regel som venter på den brukte
sysfs
attributten og tilføye den
til /etc/udev/rules.d/10-wait_for_sysfs.rules
filen
(opprett denne filen hvis den ikke eksisterer). Gi beskjed til
LFS Utviklingsliste hvis du gjør det, og det hjelper.
Først må du være sikker på at driveren er innebygd i kjernen eller allerede lastet inn som en modul, og at udev ikke oppretter en enhet med feil navn.
Hvis en kjernedriver ikke eksporterer dataene sine til
sysfs
, mangler udev informasjon
som trengs for å opprette en enhetsnode. Dette vil mest
sannsynlig skje med tredjepartsdrivere fra utenfor kjernetreet.
Lag en statisk enhetsnode i /usr/lib/udev/devices
med passende hoved/under
nummer (se filen devices.txt
inne i
kjernedokumentasjonen eller dokumentasjon levert av tredjeparts
driverleverandør). Det statiske enhetsnoden vil bli kopiert til
/dev
av udev.
Dette skyldes det faktum at udev, etter design, håndterer uevents og laster moduler parallelt, og dermed i en uforutsigbar rekkefølge. Dette vil aldri bli “fikset”. Du bør ikke stole på at kjerneenhetens navn er stabile. Lag heller dine egne regler som lager symbolkoblinger med stabile navn basert på noen stabile attributter til enheten, for eksempel et serienummer eller utdata fra forskjellige *_id-verktøy installert av udev. Se Section 9.4, “Administrere enheter” og Section 9.5, “Generell nettverkskonfigurasjon” for eksempler.
Ytterligere nyttig dokumentasjon er tilgjengelig på følgende nettsteder:
En brukerromsimplementering av devfs
http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf
sysfs
filsystemet
https://www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf