Produkty Novinky Články Návody Kontakty

Soubory zařízení

Nyní si něco řekneme o tom, jak aplikace v uživatelském prostoru (user space) přistupují k ovladači (modulu) nějakého zařízení.
Už dříve jsme se zmínili o tom, že ve světě Unixu (Linux nevyjímaje) je snaha všechny systémové prostředky zpřístupňovat jako soubor. Vyjímkou nejsou ani zařazení, resp. ovladače zařízení. V adresáři /dev se nacházejí speciální soubory zvané soubory zařízení (device files) někdy také uzly zařízení (device nodes), které v uživatelském prostoru reprezentují zařízení. Kdykoliv když aplikace prostřednictvím systémového volání, resp. knihovní funkce knihovny libc přistoupí k souboru zařízení, jádro zavolá zaregistrovaný ovladač (modul), který požadavek aplikace zpracuje a zajistí obsluhu příslušného zařízení.
Výhoda tohoto přístupu je zřejmá - k zařízením lze přistupovat pomocí běžných systémových volání používaných pro přístup k souboru, resp. knihovních funkcí knihovny libc. Tím, že je zařízení ”jen” souborem odpadá nutnost, na rozdíl např. od OS MS Windows, používat pro přístup k zařízením speciální API funkce.
Na obrázku 1.4 je zkrácený výpis obsahu adresáře /dev na mém počítači. Vidíme, že mám v systému dvě bloková zařízení sda (pevný disk) a hda (CDROM mechanika). Že jsou bloková poznáme podle písmene b v prvním sloupci. Mechanika CDROM je zpřístupněna ještě pomocí symbolického odkazu (písmeno l) na zařízení hda. Kromě blokových zařízení jsou v mém počítači i dvě znaková zařízení tty0 a tty1 (písmeno c), tedy dvě terminálová zařízení.
obrázek vypis-adresare-dev
Obrázek 1.4 Výpis adresáře /dev
Jestliže nějaká aplikace, potřebuje pracovat např. s prvním terminálovým zařízením, zavolá metodu open() s parametrem /dev/tty0 a může začít číst nebo psát znaky z/na terminál pomocí metod read() a write(). Práci s terminálem pak aplikace jednoduše ukončí metodou close(). Elegantní, že?

Major a minor čísla

Před chvílí jsme si ukázali, že pro přístup k zařízením z uživatelského prostoru se používají soubory zařízení v adresáři /dev. Na obrázku 1.4 si však můžeme všimnout, že každý soubor zařízení má mimo jiné přidělena dvě čísla: hlavní (major) a vedlejší (minor). Například zařízení hda má přiděleno hlavní číslo 3 a vedlejší číslo 0.
Hlavní číslo identifikuje ovladač, kterému jádro předá požadavek aplikace na přístup k zařízení. Vedlejší číslo pak pomáhá ovladači určit dílčí část zařízení nebo, v případě většího počtu zařízení obsluhovaných jedním ovladačem, určit o které konkrétní zařízení jde. Typickým případem, kdy jeden ovladač obsluhuje více zařízení, je terminálové zařízení tty. Například můj počítač má dvě terminálová zařízení (viz obrázek 1.4), která jsou řízena jedním modulem zaregistrovaným pod hlavním číslem 4. Vedlejší čísla 0 a 1 slouží ovladači k rozlišení terminálových zařízení od sebe. Jinými slovy lze říci, že hlavní číslo udává třídu zařízení (terminál), zatímco vedlejší číslo potom konkrétní instanci zařízení (terminál 0).
Obě čísla mají povolený rozsah 0 - 255, resp. 1 - 254 (krajní hodnoty by neměly být využívány). V jádře 2.6 je sice možné používat i vyšší čísla, ovšem z důvodů zpětné kompatibility obvykle nejsou využívána. Tento rozsah platí zvlášť pro znaková a zvlášť pro bloková zařízení. Může se tedy stát, že v systému budou existovat dvě zařízení se stejnými čísly, jedno znakové, druhé blokové.
Hlavní a vedlejší číslo se při volání metody open() předávají ovladači, který pak s nimi může dále pracovat.

Jak vytvořit soubor zařízení

Předpokládejme, že máme ovladač pro naše zařízení a potřebujeme jej zpřístupnit aplikacím v uživatelském prostoru - tj. vytvořit pro něj odpovídající soubor zařízení v adresáři /dev. Máme dvě možnosti: vytvořit jej ručně nebo automaticky s pomocí správce zařízení.
Ručně - příkazem mknod
Ručně vytvoříme soubor zařízení skriptem MAKEDEV nebo případně příkazem mknod. Skript MAKEDEV je v případě běžných zařízení preferovanou a pohodlnější cestou. Ovšem pro netypická zařízení, o kterých skript MAKEDEV nemá žádné informace (náš případ), budeme muset vytvořit soubor zařízení příkazem mknod.
Příkaz:
# mknod -m 666 /dev/nazevzarizeni c 240 0
vytvoří v adresáři /dev soubor zařízení nazevzarizeni. Zařízení bude znakové - písmeno c, s hlavním číslem 240 a vedlejším číslem 0. Kromě toho musíme případně pomocí příkazů chown a chgrp podle potřeby upravit přístupová práva souboru zařízení - změnit vlastníka a skupinu.
Při ručním způsobu vytváření souborů zařízení musíme překonat ještě jednu překážku - zvolit správně hlavní a vedlejší číslo. Seznam zařízení a přidělených hlavních a vedlejších čísel nalezneme ve stromu jádra v souboru /Documentation/devices.txt nebo na internetu. V příkladu použití příkazu mknod jsem použil hlavní číslo 240, které je podle souboru devices.txt vyhrazeno pro lokální a experimentální použití - nehrozí tak konflikt při budoucím rozšiřování seznamu známých/běžných zařízení.
Automaticky - udev/mdev
Správa ručně vytvořených souborů zařízení není pružná a ani pohodlná. Což když někdy v budoucnu budeme chtít přidat nějaké zařízení nebo jej zas odebrat? Co kolize hlavních a vedlejších čísel?
Z těchto a mnoha dalších důvodů vnikl správce souborů zařízení - systémová služba udev. Z pohledu uživatele funguje jednoduše - jádro při detekování nového zařízení (ať již při zavádění systému nebo za běhu) vyvolá událost, kterou udev odchytí a na jejímž základě vytvoří odpovídající soubor zařízení v adresáři /dev. Případně také zavede do jádra příslušný modul nebo vykoná jinou definovanou činnost. K tomuto procesu zavádění se váže soubor udev pravidel (udev rules), která umožňují přizpůsobovat reakce udev na události jádra potřebám uživatele.
Udev je velmi mocný a komplexní nástroj, což jej pro potřeby minimalizovaných linuxových distribucí staví mimo hru. Výhody jeho použití jsou však natolik zřejmé, že v distribucích postavených na bázi Busyboxu se používá jeho méně vybavené obdoby - nástroje mdev. Nástroj mdev je součástí Busyboxu a pro základní funkcionalitu dokonce ani nepotřebuje konfigurační soubor. Byl podrobněji popsán jinde, takže si jen stručně připomeneme jak funguje.
Při vzniku události (přidání zařízení) mdev projde konfigurační souborInformationPokud konfigurační soubor neexistuje, tak mdev vytvoří soubor zařízení s názvem zařízení a s právy přístupu 660, uživatel root, skupina root. a podle jména zařízení se v něm pokusí najít odpovídající řádek. Prohledávání konfiguračního souboru končí na prvním řádku, kde dojde ke shodě s jménem zařízení. Podle informací na tomto řádku, pak mdev vytvoří soubor zařízení s požadovanými právy přístupu. Případně také vykoná definovaný příkaz (zavede ovladač, spustí skript, apod.).
Stejně se mdev chová i při startu systému, kdy prohledá adresář /sys a pro všechna zařízení, která najde, vytvoří podle konfiguračního souboru odpovídající soubory zařízení.
Na tomto místě se hodí připomenout, že jak mdev, tak i udev předpokládají, že na místo původního adresáře /dev je při startu systému ve vhodném okamžiku připojen souborový systém vytvořený nad částí operační paměti (tmpfs apod.). Obsah adresáře /dev tak může být měněn za běhu systému dle potřeb bez zbytečných prodlev při čekání na pevný disk nebo jiné záznamové zařízení. Navíc tento způsob přemapování původního adresáře /dev dovoluje nasadit udev, příp. mdev i do zařízení, kde je kořenový souborový systém připojen v režimu ”pouze pro čtení”.
Automatické vytváření souboru zařízení má v moderním jádře ještě jedno opodstatnění - ovladače se při zavádění do jádra musí registrovat k hlavnímu (major) číslu příslušného souboru zařízení. V současnosti je doporučovanou cestou takzvaná dynamická registrace, kdy jádro samo přidělí ovladači nějaké volné hlavní číslo. Pak ovšem soubor zařízení, který bude ovladač reprezentovat v uživatelském prostoru, nesmí existovat před zavedením ovladače do jádra. Musí být vytvořen až po zavedení ovladače, protože až tehdy se ví, ke kterému hlavnímu číslo se ovladač zaregistroval - typický úkol pro správce zařízení udev či mdev.