1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml">
5 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
7 7.9. LFS システムにおけるデバイスとモジュールの扱い
9 <link rel="stylesheet" href="../stylesheets/lfs.css" type="text/css" />
10 <meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
11 <link rel="stylesheet" href="../stylesheets/lfs-print.css" type=
12 "text/css" media="print" />
14 <body class="lfs" id="lfs-6.8">
15 <div class="navheader">
17 Linux From Scratch - Version 6.8
24 <a accesskey="p" href="profile.html" title=
25 "Bash シェルの初期起動ファイル">前のページ</a>
31 <a accesskey="n" href="symlinks.html" title=
32 "デバイスへのシンボリックリンクの生成">次のページ</a>
38 <a accesskey="u" href="chapter07.html" title=
39 "第7章 ブートスクリプトの設定">上に戻る</a>
42 <a accesskey="h" href="../index.html" title=
43 "Linux From Scratch - Version 6.8">ホーム</a>
47 <div class="sect1" lang="ja" xml:lang="ja">
49 <a id="ch-scripts-udev" name="ch-scripts-udev"></a>7.9. LFS
53 <a class="xref" href="../chapter06/chapter06.html" title=
54 "第6章 基本的なソフトウェアのインストール">第6章</a>にて Udev パッケージをインストールしました。
55 このパッケージがどのように動作するかの詳細を説明する前に、デバイスを取り扱うかつての方法について順を追って説明していきます。
58 Linux システムは一般に、スタティックなデバイス生成方法を採用していました。 この方法では <code class=
59 "filename">/dev</code> のもとに膨大な量の (場合によっては何千にもおよぶ) デバイスノードが生成されます。
60 現実に存在するハードウェアデバイスが存在するかどうかに関わらずです。 これは <span class=
61 "command"><strong>MAKEDEV</strong></span> スクリプトを通じて生成されます。 このスクリプトからは
62 <span class="command"><strong>mknod</strong></span>
63 プログラムが呼び出されますが、その呼び出しは、この世に存在するありとあらゆるデバイスのメジャー/マイナー番号を用いて行われます。
66 Udev による方法では、カーネルが検知したデバイスだけがデバイスノードとなります。
67 デバイスノードはシステムが起動するたびに生成されることになるので、 <code class=
68 "systemitem">tmpfs</code> ファイルシステム上に保存されます。 (<code class=
69 "systemitem">tmpfs</code> は仮想ファイルシステムであり、メモリ上に置かれます。)
70 デバイスノードの情報はさほど多くないので、消費するメモリ容量は無視できるほど少ないものです。
72 <div class="sect2" lang="ja" xml:lang="ja">
77 2000年2月に新しいファイルシステム <code class="systemitem">devfs</code> がカーネル
78 2.3.46 に導入され、2.4系の安定版カーネルにて利用できるようになりました。
79 このファイルシステムはカーネルのソース内に含まれ実現されていましたが、デバイスを動的に生成するこの手法は、主要なカーネル開発者の十分な支援は得られませんでした。
82 <code class="systemitem">devfs</code>
83 が採用した手法で問題になるのは、主にデバイスの検出・生成・命名の方法です。 特にデバイスの命名方法がおそらく最も重大な問題です。
84 一般的に言えることとして、デバイス名が変更可能であるならデバイス命名の規則はシステム管理者が考えることであって、特定の開発者に委ねるべきことではありません。
85 また <code class="systemitem">devfs</code>
86 にはその設計に起因した競合の問題があるため、根本的にカーネルを修正しなければ解消できる問題ではありません。
87 そこで長い間、保守されることがなかったために非推奨 (deprecated) として位置づけられ、最終的に
88 2006年6月にはカーネルから取り除かれました。
91 開発版の 2.5 系カーネルと、後にリリースされた安定版のカーネル 2.6 系を経て、新しい仮想ファイルシステム
92 <code class="systemitem">sysfs</code> が登場しました。 <code class=
93 "systemitem">sysfs</code>
94 が実現したのは、システムのハードウェア設定をユーザー空間のプロセスとして表に出したことです。
95 ユーザー空間での設定を可視化したことによって <code class="systemitem">devfs</code>
96 が為していたことを、ユーザー空間にて現実に見ることが可能になったわけです。
99 <div class="sect2" lang="ja" xml:lang="ja">
103 <div class="sect3" lang="ja" xml:lang="ja">
105 7.9.2.1. Sysfs ファイルシステム
108 <code class="systemitem">sysfs</code> ファイルシステムについては上で簡単に触れました。
109 <code class="systemitem">sysfs</code>
110 はどのようにしてシステム上に存在するデバイスを知るのか、そしてどのデバイス番号が利用されるのか。 そこが知りたいところです。
111 カーネルに直接組み込まれて構築されたドライバでは、対象のオブジェクトがカーネルによって検出されたものとしてそのオブジェクトを
112 <code class="systemitem">sysfs</code> に登録します。
113 モジュールとしてコンパイルされたドライバでは、その登録がモジュールのロード時に行われます。 <code class=
114 "systemitem">sysfs</code> ファイルシステムが (<code class=
115 "filename">/sys</code> に) マウントされると、組み込みのドライバによって <code class=
116 "systemitem">sysfs</code> に登録されたデータは、ユーザー空間のプロセスとデバイスノード生成を行う
117 <span class="command"><strong>udevd</strong></span> にて利用可能となります。
120 <div class="sect3" lang="ja" xml:lang="ja">
122 7.9.2.2. Udev ブートスクリプト
125 初期起動スクリプト <span class="command"><strong>S10udev</strong></span>
126 は、Linux のブート時にデバイスノード生成を受け持ちます。 このスクリプトは <span class=
127 "command"><strong>/sbin/hotplug</strong></span> のデフォルトから uevent
128 ハンドラを取り除きます。 この時点でカーネルは、他の実行モジュールを呼び出す必要がないからです。 そのかわりに、カーネルが起動する
129 uevent をネットリンクソケット (netlink socket) 上で待ち受けます。 そしてブートスクリプトが
130 <code class="filename">/lib/udev/devices</code>
131 内にある静的なデバイスノードをすべて <code class="filename">/dev</code> にコピーします。
132 デバイスやディレクトリ、シンボリックリンクがこの時点で利用可能になっていないと、システム起動の初期段階において動的デバイスを扱う処理が動作しないためです。
133 あるいは <span class="command"><strong>udevd</strong></span>
134 自身がそれを必要とするからでもあります。 <code class=
135 "filename">/lib/udev/devices</code>
136 内に静的なデバイスノードを生成することで、動的デバイスを取り扱うことができないデバイスも動作させることができます。
137 こうしてブートスクリプトは Udev デーモン、つまり <span class=
138 "command"><strong>udevd</strong></span> を起動し、それがどのような uevent
139 であっても対応できるものとなります。 最後にブートスクリプトはカーネルに対して、すべてのデバイスにおいて既に登録されている
140 uevent を再起動させ、 <span class=
141 "command"><strong>udevd</strong></span> がそれを待ち受けるものとなります。
144 <div class="sect3" lang="ja" xml:lang="ja">
149 Udev はデバイスのメジャー番号、マイナー番号を認識するために <code class=
150 "filename">/sys</code> ディレクトリ内の <code class=
151 "systemitem">sysfs</code> の情報を参照します。 例えば <code class=
152 "filename">/sys/class/tty/vcs/dev</code> には 「<span class=
153 "quote">7:0</span>」 という文字があります。 この文字は <span class=
154 "command"><strong>udevd</strong></span> が利用するもので、メジャー番号が
155 <span class="emphasis"><em>7</em></span>、マイナー番号が <span class=
156 "emphasis"><em>0</em></span> のデバイスノードを生成します。 <code class=
157 "filename">/dev</code> ディレクトリ配下に生成されるノードの名称とパーミッションは、
158 <code class="filename">/etc/udev/rules.d/</code>
159 ディレクトリにある各種ファイルが指定する規則に従って決まります。 それらのファイルは番号付けがされています。
160 LFS-ブートスクリプトパッケージにおける方法に似ています。 Udev
161 がデバイスを生成しようとしてその生成規則が見つけられなかった場合は、デフォルトのパーミッションは <span class=
162 "emphasis"><em>660</em></span>、デフォルトの所有者は <span class=
163 "emphasis"><em>root:root</em></span> となります。 Udev
164 におけるデバイス生成規則を設定するファイルについて、その文法を示したドキュメントが <code class=
165 "filename">/usr/share/doc/udev-166/writing_udev_rules/index.html</code>
169 <div class="sect3" lang="ja" xml:lang="ja">
174 モジュールとしてコンパイルされたデバイスドライバの場合、デバイス名の別名が作り出されています。 その別名は
175 <span class="command"><strong>modinfo</strong></span>
176 プログラムを使えば確認することができます。 そしてこの別名は、モジュールがサポートするバス固有の識別子に関連づけられます。 例えば
177 <span class="emphasis"><em>snd-fm801</em></span> ドライバは、ベンダーID
178 0x1319 とデバイスID 0x0801 の PCI ドライバをサポートします。 そして 「<span class=
179 "quote">pci:v00001319d00000801sv*sd*bc04sc01i*</span>」
180 というエイリアスがあります。 たいていのデバイスでは、<code class="systemitem">sysfs</code>
181 を通じてドライバがデバイスを扱うものであり、ドライバのエイリアスをバスドライバが提供します。 <code class=
182 "filename">/sys/bus/pci/devices/0000:00:0d.0/modalias</code>
183 ファイルならば 「<span class=
184 "quote">pci:v00001319d00000801sv00001319sd00001319bc04sc01i00</span>」
185 という文字列を含んでいるはずです。 Udev が提供するデフォルトの生成規則によって <span class=
186 "command"><strong>udevd</strong></span> から <span class=
187 "command"><strong>/sbin/modprobe</strong></span>
188 が呼び出されることになり、その際には uevent に関する環境変数 <code class=
189 "envar">MODALIAS</code> の設定内容が利用されます。 (この環境変数の内容は sysfs 内の
190 <code class="filename">modalias</code> ファイルの内容と同じはずです。)
191 そしてワイルドカードが指定されているならそれが展開された上で、エイリアス文字列に合致するモジュールがすべてロードされることになります。
194 上の例で <span class="emphasis"><em>forte</em></span>
195 ドライバがあったとすると、<span class="emphasis"><em>snd-fm801</em></span>
196 の他にそれもロードされてしまいます。 これは古いものでありロードされて欲しくないものです。
197 不要なドライバのロードを防ぐ方法については後述しているので参照してください。
200 カーネルは、ネットワークプロトコル、ファイルシステム、NLS
201 サポートといった各種モジュールも、要求に応じてロードすることもできます。
204 <div class="sect3" lang="ja" xml:lang="ja">
206 7.9.2.5. ホットプラグ可能な/ダイナミックなデバイスの扱い
209 USB (Universal Serial Bus) で MP3
210 プレイヤーを接続しているような場合、カーネルは現在そのデバイスが接続されているということを認識しており、uevent
211 が生成済の状態にあります。 その uevent は上で述べたように <span class=
212 "command"><strong>udevd</strong></span> が取り扱うことになります。
216 <div class="sect2" lang="ja" xml:lang="ja">
218 7.9.3. モジュールロードとデバイス生成の問題
221 自動的にデバイスが生成される際には、いくつか問題が発生します。
223 <div class="sect3" lang="ja" xml:lang="ja">
225 7.9.3.1. カーネルモジュールが自動的にロードされない問題
228 Udev がモジュールをロードできるためには、バス固有のエイリアスがあって、バスドライバが <code class=
229 "systemitem">sysfs</code> に対して適切なエイリアスを提供していることが必要です。
230 そうでない場合は、別の手段を通じてモジュールのロードを仕組まなければなりません。 Linux-2.6.37 においての Udev
231 は、 INPUT、IDE、PCI、USB、SCSI、SERIO、FireWire の各デバイスに対するドライバをロードします。
232 それらのデバイスドライバが適切に構築されているからです。
235 目的のデバイスドライバが Udev に対応しているかどうかは、 <span class=
236 "command"><strong>modinfo</strong></span>
237 コマンドに引数としてモジュール名を与えて実行します。 <code class="filename">/sys/bus</code>
238 ディレクトリ配下にあるそのデバイス用のディレクトリを見つけ出して、 <code class=
239 "filename">modalias</code> ファイルが存在しているかどうかを見ることで分かります。
242 <code class="systemitem">sysfs</code> に <code class=
243 "filename">modalias</code>
244 ファイルが存在しているなら、そのドライバはデバイスをサポートし、デバイスとの直接のやり取りが可能であることを表します。
245 ただしエイリアスを持っていなければ、それはドライバのバグです。 その場合は Udev
246 に頼ることなくドライバをロードするしかありません。 そしてそのバグが解消されるのを待つしかありません。
249 <code class="filename">/sys/bus</code> ディレクトリ配下の対応するディレクトリ内に
250 <code class="filename">modalias</code>
251 ファイルがなかったら、これはカーネル開発者がそのバス形式に対する modalias のサポートをまだ行っていないことを意味します。
252 Linux-2.6.37 では ISA バスがこれに該当します。 最新のカーネルにて解消されることを願うしかありません。
255 Udev は <span class="emphasis"><em>snd-pcm-oss</em></span> のような
256 「<span class="quote">ラッパー (wrapper)</span>」 ドライバや <span class=
257 "emphasis"><em>loop</em></span>
258 のような、現実のハードウェアに対するものではないドライバは、ロードすることができません。
261 <div class="sect3" lang="ja" xml:lang="ja">
263 7.9.3.2. カーネルモジュールが自動的にロードされず Udev もロードしようとしない問題
266 「<span class="quote">ラッパー (wrapper)</span>」
267 モジュールが単に他のモジュールの機能を拡張するだけのものであるなら (例えば <span class=
268 "emphasis"><em>snd-pcm-oss</em></span> は <span class=
269 "emphasis"><em>snd-pcm</em></span> の機能拡張を行うもので、 OSS
270 アプリケーションに対してサウンドカードを利用可能なものにするだけのものであるため) <span class=
271 "command"><strong>modprobe</strong></span>
272 の設定によってラッパーモジュールを先にロードし、その後でラップされるモジュールがロードされるようにします。 これは以下のように
273 <code class="filename">/etc/modprobe.d/<em class=
274 "replaceable"><code><filename></code></em>.conf</code>
275 ファイル内にて 「<span class="quote">install</span>」 の記述行を加えることで実現します。
278 <code class="literal">install snd-pcm /sbin/modprobe -i snd-pcm ; \
279 /sbin/modprobe snd-pcm-oss ; true</code>
282 問題のモジュールがラッパーモジュールではなく、単独で利用できるものであれば、 <span class=
283 "command"><strong>S05modules</strong></span>
284 ブートスクリプトを編集して、システム起動時にこのモジュールがロードされるようにします。 これは <code class=
285 "filename">/etc/sysconfig/modules</code>
286 ファイルにて、そのモジュール名を単独の行に記述することで実現します。
287 この方法はラッパーモジュールに対しても動作しますが、この場合は次善策となります。
290 <div class="sect3" lang="ja" xml:lang="ja">
292 7.9.3.3. Udev が不必要なモジュールをロードする問題
295 不必要なモジュールはこれをビルドしないことにするか、あるいは <code class=
296 "filename">/etc/modprobe.d/blacklist.conf</code> ファイルにブラックリスト
297 (blacklist) として登録してください。 例えば <span class=
298 "emphasis"><em>forte</em></span> モジュールをブラックリストに登録するには以下のようにします。
301 <code class="literal">blacklist forte</code>
304 ブラックリストに登録されたモジュールは <span class=
305 "command"><strong>modprobe</strong></span>
306 コマンドを使えば手動でロードすることもできます。
309 <div class="sect3" lang="ja" xml:lang="ja">
311 7.9.3.4. Udev が不正なデバイスを生成する、または誤ったシンボリックリンクを生成する問題
314 デバイス生成規則が意図したデバイスに合致していないと、この状況が往々にして起こります。
315 例えば生成規則の記述が不十分であった場合、SCSI ディスク (本来望んでいるデバイス)
316 と、それに対応づいたものとしてベンダーが提供する SCSI ジェネリックデバイス (これは誤ったデバイス)
317 の両方に生成規則が合致してしまいます。 記述されている生成規則を探し出して正確に記述してください。 その際には
318 <span class="command"><strong>udevadm info</strong></span>
322 <div class="sect3" lang="ja" xml:lang="ja">
324 7.9.3.5. Udev 規則が不審な動きをする問題
327 この問題は、一つ前に示したものが別の症状となって現れたものかもしれません。 そのような理由でなく、生成規則が正しく
328 <code class="systemitem">sysfs</code>
329 の属性を利用しているのであれば、それはカーネルの処理タイミングに関わる問題であって、カーネルを修正すべきものです。
330 今の時点では、該当する <code class="systemitem">sysfs</code>
331 の属性の利用を待ち受けるような生成規則を生成し、 <code class=
332 "filename">/etc/udev/rules.d/10-wait_for_sysfs.rules</code>
333 ファイルにそれを追加することで対処できます。 (<code class=
334 "filename">/etc/udev/rules.d/10-wait_for_sysfs.rules</code>
335 ファイルがなければ新規に生成します。) もしこれを実施してうまくいった場合は LFS 開発メーリングリストにお知らせください。
338 <div class="sect3" lang="ja" xml:lang="ja">
340 7.9.3.6. Udev がデバイスを生成しない問題
344 まずドライバがカーネル内に静的に組み入れられて構築されているか、あるいは既にモジュールとしてロードされていること。 そして
345 Udev が異なった名前のデバイスを生成していないことです。
348 Udev がデバイスノード生成のために必要となる情報を知るためには、カーネルドライバが <code class=
349 "systemitem">sysfs</code> に対して属性データを提供していなければなりません。
350 これはカーネルツリーの外に配置されるサードパーティ製のドライバであれば当たり前のことです。 したがって <code class=
351 "filename">/lib/udev/devices</code>
352 において、適切なメジャー・マイナー番号を用いた静的なデバイスノードを生成してください。 (カーネルのドキュメント
353 <code class="filename">devices.txt</code>
354 またはサードパーティベンダーが提供するドキュメントを参照してください。) この静的デバイスノードは、<span class=
355 "command"><strong>S10udev</strong></span> ブートスクリプトによって
356 <code class="filename">/dev</code> にコピーされます。
359 <div class="sect3" lang="ja" xml:lang="ja">
361 7.9.3.7. 再起動後にデバイスの命名順がランダムに変わってしまう問題
364 これは Udev の設計仕様に従って発生するもので、uevent の扱いとモジュールのロードが平行して行われるためです。
365 このために命名順が予期できないものになります。 これを 「<span class="quote">固定的に</span>」
367 ですからカーネルがデバイス名を固定的に定めるようなことを求めるのではなく、シンボリックリンクを用いた独自の生成規則を作り出して、そのデバイスの固定的な属性を用いた固定的な名前を用いる方法を取ります。
368 固定的な属性とは例えば、Udev によってインストールされる様々な *_id
369 という名のユーティリティが出力するシリアル番号などです。 設定例については <a class="xref" href=
370 "symlinks.html" title=
371 "7.10. デバイスへのシンボリックリンクの生成">7.10.「デバイスへのシンボリックリンクの生成」</a> や
372 <a class="xref" href="network.html" title=
373 "7.13. ネットワークスクリプトの設定">7.13.「ネットワークスクリプトの設定」</a> を参照してください。
377 <div class="sect2" lang="ja" xml:lang="ja">
382 さらに参考になるドキュメントが以下のサイトにあります:
384 <div class="itemizedlist">
388 <code class="systemitem">devfs</code> のユーザー空間での実装方法 <a class=
390 "http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf">
391 http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf</a>
396 <code class="systemitem">sysfs</code> ファイルシステム <a class=
398 "http://www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf">
399 http://www.kernel.org/pub/linux/kernel/people/mochel/doc/papers/ols-2005/mochel.pdf</a>
404 より詳細なドキュメントへのリンク <a class="ulink" href=
405 "http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html">
406 http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html</a>
413 <div class="navfooter">
416 <a accesskey="p" href="profile.html" title=
417 "Bash シェルの初期起動ファイル">前のページ</a>
423 <a accesskey="n" href="symlinks.html" title=
424 "デバイスへのシンボリックリンクの生成">次のページ</a>
430 <a accesskey="u" href="chapter07.html" title=
431 "第7章 ブートスクリプトの設定">上に戻る</a>
434 <a accesskey="h" href="../index.html" title=
435 "Linux From Scratch - Version 6.8">ホーム</a>