Gentoo Logo

Praca z udev w Gentoo

Spis treści:

1.  Czym jest udev?

Katalog /dev

Kiedy użytkownicy Linuksa rozmawiają o ich sprzęcie w pobliżu ludzi, którzy wierzą, że Linux jest pewnego rodzaju wirusem lub gatunkiem kawy, użycie słów "ukośnik dev ukośnik coś tam" spowoduje, że zaczną się oni dziwnie na nich patrzeć. Ale szczęśliwy użytkownik (i to jesteśmy my) używając /dev/hda1 skrótowo wyjaśnia, że rozmowa tyczy się pierwszej partycji dysku, który jest podpięty jako primary master. Czy nie mam racji?

Wszyscy wiemy czym jest plik urządzenia. Niektórzy nawet wiedzą dlaczego pliki urządzeń posiadają specjalne numery, które widać wykonując polecenie ls -l w /dev. Ale zawsze dysk podpięty jako primary master jest widoczny jako /dev/hda. Można tego nie widzieć w ten sposób, ale jest to wada projektu.

Pomyślmy o urządzeniach podłączanych podczas pracy takich jak USB, IEEE1394, PCI... Co jest pierwszym urządzeniem? I na jak długo? Jak będą inne urządzenia nazwane, kiedy to pierwsze zniknie? Jaki to będzie miało wpływ na inne procesy? Czyż nie byłoby to zabawne gdyby zadanie do drukowania zostało nagle przeniesione z naszej nowiutkiej drukarki laserowej do naszej zrupieciałej drukarki mozaikowej, ponieważ mama zdecydowała się wyciągnąć wtyczkę drukarki laserowej, która była pierwszą drukarką, z kontaktu?

Wchodzimy do udev. Główne cele projektu udev są zarówno ciekawe jak i konieczne:

  • Działa w przestrzeni użytkownika
  • Dynamicznie tworzy lub usuwa pliki urządzeń
  • Dostarcza spójne nazewnictwo
  • Dostarcza interfejsu API przestrzeni użytkownika

Aby dostarczyć te cechy, udev jest rozwijany w trzech odrębnych projektach: namedev, libsysfs oraz udev.

namedev

Namedev pozwala zdefiniować odrębne nazewnictwo niż to w udev. To pozwala na elastyczne polityki i schematy nazewnictwa rozwijane przez odrębne jednostki. Ten podsystem nazewnictwa urządzeń dostarcza standardowego interfejsu, którego może używać udev.

Obecnie namedev dostarcza tylko jeden schemat nazewnictwa - LANANA, który jest używany przez większość obecnych systemów Linuksowych, a zatem pasuje on większości użytkowników Linuksa.

Namedev używa pięciostopniowej procedury pozyskiwania nazwy urządzenia. Jeśli nazwa urządzenia zostanie znaleziona w tych pięciu krokach, wtedy zostanie ona użyta. Są nimi:

  • etykieta lub numer seryjny
  • numer urządzenia magistrali
  • topologia magistrali
  • statycznie przydzielana nazwa
  • nazwa dostarczona przez jądro

Krok etykieta lub numer seryjny sprawdza czy urządzenie posiada jednoznaczny identyfikator. Na przykład urządzenia USB posiadają unikalny numer seryjny, urządzenia SCSI posiadają unikalny UUID. Jeśli namedev znajdzie odpowiednią nazwę wtedy zostanie ona użyta.

Krok numer urządzenia magistrali sprawdza numer urządzenia magistrali. Dla systemów, które nie mają możliwości podłączania urządzeń w trakcie pracy, ten krok jest wystarczający. Ponieważ numery magistrali bardzo rzadko są zmieniane. Ponownie jeśli namedev znajdzie odpowiednią nazwę wtedy zostanie ona użyta.

Podobnie krok topologia magistrali jest statycznym sposobem przydzielania nazw, pod warunkiem, że użytkownik nie zamieni urządzeń. Jeśli pozycja urządzenia będzie zgodna z tym co podał użytkownik, wtedy towarzysząca temu nazwa zostanie użyta.

Krok czwarty, statycznie przydzielana nazwa, jest prostym zastępowaniem ciągów znaków. Kiedy nazwa dostarczona przez jądro (domyślna nazwa) pasuje do danego ciągu znaków, wtedy ten ciąg zostanie zastąpiony.

Ostatnim krokiem (nazwa dostarczona przez jądro) jest nadanie wszystkim urządzeniom domyślnej nazwy dostarczonej wraz z jądrem. Większości systemów Linuksowych ten krok jest wystarczający.

libsysfs

udev komunikuje się z jądrem poprzez pseudo system plików sysfs. Projekt libsysfs dostarcza interfejsu API, który zezwala na dostęp do informacji danych przez system plików sysfs. To pozwala na sprawdzenie całego sprzętu bez konieczności posiadania wiedzy jakiego typu sprzęt jest sprawdzany.

udev

Za każdym razem kiedy jądro zauważy zmianę w drzewie urządzeń konsultuje się z udev. udev najpierw postępuje zgodnie z zasadami z katalogu /etc/udev/rules.d/, następnie wprowadza zmiany zasugerowane przez jądro (usuwając lub dodając pliki w katalogu /dev.

2.  Praca z udev w Gentoo

Wymagania

udev został stworzony do pracy wraz jądrem 2.6 (na przykład gentoo-sources w domyślnym profilu 2007.0). Jeśli używamy takiego jądra, wtedy należy się upewnić, że posiadamy najnowszą wersję pakietu sys-apps/baselayout.

Listing 2.1: Instalacja udev

# emerge udev

Użytkownicy korzystający z ręcznie skompilowanego jądra muszą włączyć następujące opcje:

Listing 2.2: Wymagane opcje jądra

General setup --->
  [*] Support for hot-pluggable devices

File systems --->
  Pseudo filesystems --->
    [*] /proc file system support
    [*] Virtual memory file system support (former shm fs)

Użytkownicy genkernela, muszą uruchomić ten skrypt z flagą --udev, aby włączyć wszystkie instrukcje konfigurujące jądro. Jednak domyślna konfiguracja wykonana przez samo polecenie genkernel również wystarczy do prawidłowego uruchomienia systemu.

Konfiguracja

Jeśli chcemy, aby poprawki dodane przez deweloperów Gentoo ułatwiły nam życie wtedy należy ominąć ten rozdział. Gentoo będzie używał udev, ale katalog /dev będzie statyczny, żebyśmy nigdy nie doświadczyli braku jakiegokolwiek węzła urządzenia. W tym wariancie skrypty Gentoo nie uruchomią demona devfs i wyłączą devfs podczas uruchamiania systemu.

Jeśli jesteśmy twardzi i chcemy, aby nasz system używał tylko i wyłącznie udev (mogą pojawić się brakujące węzły urządzeń spowodowane przez brak wsparcia ze strony udev), wtedy należy czytać dalej.

Wyłączymy reguły, które zachowują węzły urządzeń do pliku: edytujemy zmienną RC_DEVICE_TARBALL w /etc/conf.d/rc i ustawiamy ją na no:

Listing 2.3: /etc/conf.d/rc

RC_DEVICE_TARBALL="no"

Jeśli włączyliśmy w jądrze wsparcie dla devfs, możemy je wyłączyć dopisując do parametrów jądra w pliku konfiguracyjnym bootloadera: gentoo=nodevfs. Jeśli chcemy używać devfs i wyłączyć udev, wtedy jako parametr jądra dodajemy gentoo=noudev.

3.  Znane problemy

Brakujące pliki węzła urządzenia podczas ładowania systemu

Jeśli nie potrafimy pomyślnie zakończyć procesu uruchamiania systemu ponieważ wyskakuje nam błąd o nie znalezieniu /dev/null lub ponieważ brakuje konsoli startowej, wtedy problemem jest brak pewnych plików urządzeń, które muszą być dostępne przed zamontowaniem katalogu /dev.

Jeśli posiadamy sys-apps/baselayout-1.8.12 lub nowszy, wtedy ten problem jest złagodzony ponieważ proces uruchamiania systemu powinien zakończyć się powodzeniem. Jednakże, aby pozbyć się tych denerwujących ostrzeżeń, należy stworzyć brakujące węzły urządzeń tak jak jest to przedstawione poniżej.

Aby sprawdzić które węzły urządzeń są obecne przed zamontowaniem katalogu /dev należy wykonać następujące polecenia:

Listing 3.1: Wyświetlanie węzłów urządzeń dostępnych podczas uruchamiania systemu

# mkdir test
# mount --bind / test
# cd test/dev
# ls

Urządzenia wymagane do pomyślnego załadowania systemu są umieszczone w /dev/null oraz w /dev/console. Jeśli się nie pojawiły, to należy je stworzyć ręcznie. Będąc w katalogu test/dev/ należy wykonać:

Listing 3.2: Tworzenie wymaganych plików węzłów urządzeń

# mknod -m 660 console c 5 1
# mknod -m 660 null c 1 3

Kiedy skończymy nie należy zapomnieć o odmontowaniu katalogu test/:

Listing 3.3: Odmontowywanie katalogu test/

# cd ../..
# umount test
# rmdir test

udev i nVidia

Jeśli używamy odpowiednich sterowników nVidii, ale serwer X nie uruchamia się, wtedy należy upewnić się, że mamy:

  • moduł nvidia w /etc/modules.autoload.d/kernel-2.6
  • wersję baselayout równą lub wyższą sys-apps/baselayout-1.8.12

Spójne nazewnictwo pomiędzy DevFS a udev

Pomimo naszych starań, aby posiadać spójne nazewnictwo pomiędzy tymi dwoma dynamicznymi sposobami nazewnictwa urządzeń, czasami pewne różnice w nazwach występują.

Jednym ze zgłoszonych błędów jest kolizja z kontrolerem HP Smart Array 5i RAID (a dokładniej modułem jądra cciss). W udev, urządzenia są nazywane /dev/cciss/cXdYpZ gdzie X, Y i Z są normalnymi liczbami. W devfs urządzeniami są /dev/hostX/targetY/partZ lub dowiązane symbolicznie z /dev/cciss/cXdY.

W tym przypadku należy pamiętać o zaktualizowaniu pliku /etc/fstab oraz o konfiguracji plików bootloadera

To samo dzieje się ze wszystkimi dowiązaniami z katalogu /dev, takimi jak /dev/mouse, których udev już nie tworzy. Należy się upewnić, że w pliku konfiguracyjnym X-ów posiadamy odpowiednie ustawienia.

Kolejny problemem jest różnica w nazwach terminali pomiędzy devfs i udev. Terminale w devfs nazywają się tty, a w udev vc lub tty. Może to przysporzyć kłopotu, gdy ogranicza się dostęp do konsoli za pomocą pliku /etc/securetty. Należy zmienić wpis tty1 na vc/1 w pliku /etc/securetty, aby root mógł logować się w konsoli.

Zmiana nazw plików urządzeń

Nowsze wersje udev (104 i wyżej) oraz nowsze wersje jądra (2.6.19 i wyżej) mogą zmienić nazwy plików urządzeń dyskowych, co ma związek ze zmianami implementacji libata w jądrze. W związku z tym na przykład urządzenie nagrywarki CD-RW, które kiedyś nazywało się /dev/hdc może zmienić nazwę na /dev/sr0. W większości systemów nie powoduje to żadnych problemów. Istnieje jednak pewna ilość programów, które mają na stałe wpisane gdzie powinno znajdować się dane urządzenie, a to może prowadzić do błędów. Przykładem takiego programu jest media-sound/rip, który zakłada, że znajdzie czytnik płyt CD w pliku /dev/cdrom. W nowszych wersjach udev i jądra czytnik ten może się nazywać na przykład /dev/cdrom1.

Aby zapobiec tego typu problemom, należy odpowiednio zmienić plik /etc/udev/rules.d/70-persistent-cd.rules przypisując prawidłowe nazwy problematycznym urządzeniom.

Więcej informacji na temat składni reguł udev znajduje się w tekście Daniela Drake'a.

udev ładuje moduły w niemożliwej do przewidzenia kolejności

Czasami udev ładuje moduły w niepożądanej, niemożliwej do przewidzenia i pozornie przypadkowej kolejności. To zjawisko występuje najczęściej w systemach, które posiadają wiele urządzeń tego samego typu, takich jak urządzenia multimedialne. Może to wpłynąć na przydzielanie numerów urządzeniom; na przykład, karty dzwiękowe mogą niekiedy wymieniać się numerami.

Jest kilka sposobów na przypisanie numerów urządzeniom i/lub ustalenie kolejności ładowania modułów. W najlepszym przypadku, aby określić pożądany numer urządzenia, można użyć parametrów modułu. Niektóre moduły, takie jak ALSA, zawierają parametr "index". Moduły używające tego parametru mogą zostać dostosowane w następujący sposób. Przykład jest oparty na systemie z dwiema kartami dzwiękowymi. Karta o indeksie 0 jest oznaczona jako pierwsza karta. Aby zmienić jej parametry, należy zaktualizować pliki konfiguracyjne modułu.

Listing 3.4: Ustalanie parametrów modułu

# echo "option snd-ice1724 index=0" >> /etc/modules.d/alsa
# echo "option snd-ymfpci index=1" >> /etc/modules.d/alsa
# update-modules

Powyższy przykład prezentuje najlepszą sytuację. Lecz nie wszystkie moduły wspierają parametry takie jak "index". Dla tych modułów należy wymusić poprawną kolejność ich ładowania. Po pierwsze, konieczne jest powstrzymanie udev od automatycznego ładowania modułów przez wpisanie ich na czarną listę. Wpisując, należy być pewnym nazwy ładowanego modułu. Dla urządzeń PCI, trzeba użyć nazwy modułu uzyskanego z wyjścia pcimodules, dostępnego w pakiecie pciutils. Poniższy przykład opisuje użycie modułu DVB

Listing 3.5: Wpisywanie modułów na czarną listę

# echo "blacklist b2c2-flexcop-pci" >> /etc/modprobe.d/dvb
# echo "blacklist budget" >> /etc/modprobe.d/dvb
# update-modules

Następnie należy załadować moduły w poprawnej kolejności. Trzeba dodać je do /etc/modules.autoload.d/kernel-2.6 w dokładnie takiej kolejności w jakiej mają zostać załadowane.

Listing 3.6: Ładowanie modułów w poprawnej kolejności

# echo "budget" >> /etc/modules.autoload.d/kernel-2.6
# echo "b2c2-flexcop-pci" >> /etc/modules.autoload.d/kernel-2.6

Inne problemy

Jeśli węzły urządzeń nie są tworzone podczas ładowania modułu z /etc/modules.autoload.d/kernel-2.6, ale są tworzone jeśli załadujemy moduł ręcznie, należy spróbować aktualizacji pakietu baselayout do wersji sys-apps/baselayout-1.8.12 lub nowszej.

Wsparcie dla urządzeń bufora ramki (/dev/fb/*) jest w jądrze 2.6.6-rc2 i powyżej.

W jądrach starszych od 2.6.4 należy włączyć wsparcie dla systemu plików /dev/pts.

Listing 3.7: Włączanie systemu plików /dev/pts

File systems --->
  Pseudo filesystems --->
    [*] /dev/pts file system for Unix98 PTYs

4.  Zasoby i podziękowania

Wykład o udev na Linux Symposium (Ottawa, Ontario Canada - 2003) prowadzony przez Greg Kroah-Hartman (IBM Corporation) dostarczył solidnego zrozumienia systemu udev.

Decibel's UDEV Primer jest wyczerpującym źródłem o udev i Gentoo.

Writing udev rules stworzony przez dewelopera Gentoo Daniela Drake jest doskonałym przykładem dostosowywania systemu udev do własnych potrzeb.



Drukuj

Zaktualizowano 16 czerwca 2008

Podsumowanie: Ten dokument wyjaśnia czym jest udev oraz jak go używać.

Sven Vermeulen
Autor

Gregorio Guidi
Współpracownik

Joshua Saddler
Redaktor

Mateusz Kotyrba
Tłumaczenie

Donate to support our development efforts.

Support OSL

Support OSL

Gentoo Centric Hosting: vr.org

VR Hosted

Tek Alchemy

Tek Alchemy

SevenL.net

SevenL.net

Global Netoptex Inc.

Global Netoptex Inc.

Bytemark

Bytemark

Linux World Expo

Linux World Expo

Copyright 2001-2008 Gentoo Foundation, Inc. Questions, Comments? Contact us.