I Chapter 8, installerte vi udev pakken når eudev 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
enhetsopprettings metode, 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. Den ble lenge merket som utdatert – på
grunn av manglende vedlikehold – 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 muligheten for å utvikle et
brukerområde erstatning for devfs
mer realistisk.
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 av devtmpfs
filesystemet. Enhver driver som
ønsker å registrere en enhetsnode vil gå gjennom devtmpfs
(via driverkjernen) for å gjøre det.
Når devtmpfs
forekomsten er
montert på /dev
, vil enhetsnoden i
utgangspunktet bli opprettet med et fast navn, tillatelser og
eier.
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 katalogene er nummererte og alle tre
kataloger 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 forårsake udevd å kalle /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 nettverks protokoller, 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 hendelse. Denne hendelsen 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-5.19.2, 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 enhetskatalogen under /sys/bus
og sjekk om det er a modalias
filer 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
filer 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-5.19.2, dette er tilfellet med ISA busser. Forvent at dette
problemet blir løst i senere kjerneversjoner.
Udev er ikke ment å laste “wrapper” drivere som f.eks snd-pcm-oss og ikke-maskinvaredrivere som f.eks loop i det hele tatt.
Hvis “wrapper” modulen forbedrer bare
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 for å
laste inn innpakkningen etter at udev laster den innpakket
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 pre:
og
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 suboptimalt 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.
Videre tekst forutsetter at driveren er bygget statisk inn i kjernen eller allerede er lastet inn som en modul, og du allerede har sjekket at udev ikke oppretter en enhet med feil navn.
Udev har ingen nødvendig informasjon for å lage en enhetsnode
hvis en kjernedriver ikke eksporterer dataene sine til
sysfs
. Dette er mest vanlig med
tredjepartsdrivere 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å 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
http://www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf