udevの話、lfs関連

lfs7.1からまとめ

udevの歴史
元来Linuxはデバイスを静的に作成していた。/dev配下にはたくさんのデバイスがあった。本当にハードが存在しているかは関係なかった。それらはMAKEDEVスクリプトによってつくられていた。スクリプトはデバイスとメイジャー番号マイナー番号をもっており、mknodを呼ぶ。

udevを使うとカーネルが検知したデバイスだけを作成する。システムがブートするたびにつくられる。それらは仮想ファイルシステムdevtmpfsに保存される。

2000年月、devfsと呼ばれるファイルシステムが2.3.46カーネルにマージされ、2.4シリーズのステーブルカーネルで利用できた。この動的デバイス作成方法はカーネルソースに組み込まれていたが、カーネル開発者の十分な支援を受けられなかった。

devfsの問題点はデバイスの検知、作成、名前付けの扱い方にあった。とくに名前付けがまずかった。もし名前が設定可能なら、名前付けポリシーはシステム管理者の仕事にであるべきで、開発者の仕事ではない。devfsはレースコンディション問題もあって本格的に直さなければならなかった。そしてメンテナンスがなくなっていき2006年カーネルから削除された。

2.5カーネルの開発上で、sysfsが来た。sysfsの仕事はハードの情報をユーザスペースに見せることだった。これによりdevfsをユーザスペースに移す見通しが立った。

sysfsはどうやってシステム上のハードを知り、デバイスナンバーを知るのだろうか。カーネルに組み込まれたドライバは自身をsysfsに登録し、カーネルに見つけてもらえる。モジュール化されたドライバの場合、登録はモジュールロード時に行われる。sysfsが/sysにいったんマウントされたら、ユーザスペースからはドライバが登録した情報を見ることができるようになる。そしてudevdが処理を開始し、デバイスノードの調整を行う。

カーネルブート時/etc/rc.d/init.d/udevスクリプトがデバイスノードの作成を行う。このときueventハンドラのデフォルトの/sbin/hotplugを解除する。カーネルはもはや外部バイナリーを呼ぶ必要がないためだ。代わりにudevdがnetlinkソケットをlistenし、カーネルがあげたueventsのめんどうを見ることになる。つぎにスクリプトは/lib/udev/devicesにある静的デバイスを/devにコピーする。いくつかのデバイス、ディレクトリ、シムリンクは動的デバイス制御が始まる前に存在しなければならない。これらはブートの初期段階やudevd自体によって利用される。この方法は動的にデバイスが作成されない場合の簡単な対処方法でもある。スクリプトはそして、udevデーモンudevdを起動する、これはueventsを処理することになる。最後にスクリプトはカーネルにueventsのリプレイさせ、udevdの処理が終わるのを待たせる。

/etc/rc.d/init.d/udev_retryスクリプトはサブシステムのために再トリガされたイベントのめんどうを見る。サブシステムのルールはまだmountfsが走っておらずマウントされていないファイルシステム(/usrや/var)に依存するかもしれない。このスクリプトはmountfs実行後に走り、ルールが再トリガされたとき2度目には成功する。これらは/etc/sysconfig/udev_retryで設定される。このファイルの記述はサブシステムの名前でリトライ時トリガされるものである。(デバイスのサブシステムをしるには、udevadm info –attribute-walkを使う)

Udev-181の時点ではudevdはもはや/devにデバイスを作成しない。代わりにdevtmpfsによるカーネルで扱われる。デバイスノードを登録したいドライバはdevtmpfs経由(ドライバコア経由)することになる。devtmpfsが/devにマウントされたとき、最初はデバイスのノードは固定の名前、パーミション、オーナーで作成される。

すぐ後で、カーネルはudevdにueventを送る。/etc/udev/rules.d, /lib/udev/rules.d, /run/udev/rules.dに書かれたルールに則り、udevdはデバイスノードへのシムリンクを作成し、パーミションやオーナー、グループを調整し、udevdデータベースを修整する。

モジュールとしてコンパイルされたドライバはエリアスをもっている場合がある。modinfoで確認できるが通常はモジュールによってサポートされるbus特定のIDになる。たとえばsnd-fm801ドライバはvendorID 0x1319とdeviceID 0x0801のPCIデバイスをサポートするがエリアスは”pci:v00001319d00000801sv*sd*bc04sc01i*”になる。多くのデバイスにとって、エリアスを提供しているドライバがsysfs経由でデバイスを扱う。たとえば/sys/bus/pci/devices/0000:00:0d.0/modaliasファイルは“pci:v00001319d00000801sv00001319sd00001319bc04sc01i00”という文字列を含むだろう。Udevで提供されるデフォルトルールはudevdにueventの環境変数MODALIASによって、/sbin/modprobeを起動させ、それに適合するモジュールをロードする。MODALIASはsysfsのmodaliasと同内容のはずだ。

USBのMP3プレイヤーなどを差し込んだとき、カーネルはそれを検知しueventを発生させる。前述のとおりudevdによって処理される。

Udevがロードできるのはbus特定エリアスをもち、ドライバがそれをsysfsに登録したものに限る。それ以外の場合は他の方法を使わなければならない。

ドライバがUdevで扱えるかはmodinfoを実行してみることだ。

Leave a Reply

Your email address will not be published. Required fields are marked *

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)