Modalias
この文書は、Linux カーネルとモジュールがハードウェアをどのように認識し理解し、それがどのように sysfs の 'modalias' に変換されるかの入門ガイドです。
目次
modalias とは何か
Modalias は、ハードウェア情報を 'modalias' という名前のファイルにエクスポートする小さな sysfs のトリックです。このファイルは、通常のハードウェアが公開する情報のフォーマットされた形式を単純に含んでいます。
$ cat /sys/devices/pci0000:00/0000:00:1f.1/modalias
pci:v00008086d000024DBsv0000103Csd0000006Abc01sc01i8A
modalias ファイルとは何か?
上述の通り、modalias ファイルは、特定のハードウェアがすでにカーネルに伝えている情報を単純に公開します。このファイルは、この情報を公開するための構造を単純に指定します。上記の例に戻りましょう:
$ cat /sys/devices/pci0000:00/0000:00:1f.1/modalias
pci:v00008086d000024DBsv0000103Csd0000006Abc01sc01i8A
それを 1 つずつ分解してみましょう。まず、ファイル名、/sys/devices/pci0000:00/0000:00:1f.1/modalias
:
- pci0000:00は最初の PCI バスの id です。ほとんどのマシンではこれが唯一の PCI バスになりますが、pci0000:01 や pci0000:02 に拡張する可能性があります - 具体的な数字は重要ではなく、おそらく PCI バスは 1 つしか持っていないと推測されます(ヒント:
ls /sys/devices/pci*
で確認してみてください) - 0000:00:1f.1 は PCI バス上の特定のデバイスのインデックスです。具体的には、これはバス 0000:00 上にあり、インデックス 1f.1 を持っています。
- これらの数値がどこから来たのか知りたいのでなければ、これらはすべて重要なことではありません。 完全を期すために、
lspci
の出力をチェックすると、同じ情報が表示されます:
$ lspci
00:1f.1 IDE interface: Intel Corp.: Unknown device 24db (rev 02)
さて、デバイス 00:1f.1 のこの modalias ファイルの内容を覗いてみましょう:
pci:v00008086d000024DBsv0000103Csd0000006Abc01sc01i8A
ほれ、この通り、PCI を見ることができます!それはわかるけど、その後の全ての意味不明な部分は何でしょうか? この意味不明な部分は実際には構造化されたデータです。繰り返しの文字/数字のパターンに気付くでしょう。これを分解して読みやすくします:
v 00008086 d 000024DB sv 0000103C sd 0000006A bc 01 sc 01 i 8A
これらの識別子と、対応する 16 進数は、特定のデバイスが公開する情報の一部を表します。始めに、v は ベンダー ID であり、d は デバイス ID です - これらは非常に標準的な数字です。事実、hwdetect のようなツールはこれら、そして他の sysfs ファイルを使用して、デバイスに関する情報を提供します。ベンダー ID やデバイス ID を基に特定のハードウェアの識別を調べるウェブサイトさえ見つけることができます、例えば、https://devicehunt.com/
これらの数字をここでも見ることができます:
$ lspci -n
00:1f.1 Class 0101: 8086:24db (rev 02)
上記に列挙した v と d トークンに 8086:24db が一致しているのが分かりますか?
言及しておくべきは、sv と sd はベンダーとデバイスの "サブシステム" バージョンです。これらは大半の時間無視されます。主に、ハードウェア開発者が全体としてのデバイスを変えない内部の微妙な違いを区別するために使用されます。
bc(基本クラス)と sc(サブクラス)は、lspci
に表示される "クラス" を作成するために使用されます。順番に "bcsc" です。これはデバイスクラスで、かなり一般的です。この場合、"クラス" は通常の lspci
出力で調べられます。"Class 0101" が "IDE Interface" にマップされているのが見て取れます (lspci
はベンダーとデバイスの id も調べます - 8086 は "Intel Corp." にマップされ、24DB は 'Unknown Device' にマップされます、へへ)
i は "プログラミングインターフェース" で、これはいくつかのデバイスクラスに対してのみ意味を持ちます。
この情報はどのように使われますか?
さて、これでこの情報が何であるかを皆さんは理解しました。各デバイスが公開する一群の奇妙な数字です。それは大したことではないように思えますが、モジュールについて話すとき、この情報がどういう意味を持つのでしょうか?
人々が無視しがちなのは、depmod
が行うすべての作業です。depmod
を実行すると、/lib/modules/uname -r
内にいくつかの "マップ" ファイルが生成されます。これらのファイルは、modprobe が行う必要がある特定の操作をどのように処理するかを指示します。今回のケースでは、それらのほとんどを無視することができます。重要なのは modules.alias
です。このファイルには、モジュールのエイリアス、つまり二次的な名前が含まれています。デモンストレーションとして、例えば、snd_intel8x0m のエイリアスを見てみましょう:
$ grep snd_intel8x0m /lib/modules/$(uname -r)/modules.alias
alias pci:v00008086d00002416sv*sd*bc*sc*i* snd_intel8x0m alias pci:v00008086d00002426sv*sd*bc*sc*i* snd_intel8x0m alias pci:v00008086d00002446sv*sd*bc*sc*i* snd_intel8x0m alias pci:v00008086d00002486sv*sd*bc*sc*i* snd_intel8x0m alias pci:v00008086d000024C6sv*sd*bc*sc*i* snd_intel8x0m alias pci:v00008086d000024D6sv*sd*bc*sc*i* snd_intel8x0m alias pci:v00008086d0000266Dsv*sd*bc*sc*i* snd_intel8x0m alias pci:v00008086d000027DDsv*sd*bc*sc*i* snd_intel8x0m alias pci:v00008086d00007196sv*sd*bc*sc*i* snd_intel8x0m alias pci:v00001022d00007446sv*sd*bc*sc*i* snd_intel8x0m alias pci:v00001039d00007013sv*sd*bc*sc*i* snd_intel8x0m alias pci:v000010DEd000001C1sv*sd*bc*sc*i* snd_intel8x0m alias pci:v000010DEd00000069sv*sd*bc*sc*i* snd_intel8x0m alias pci:v000010DEd00000089sv*sd*bc*sc*i* snd_intel8x0m alias pci:v000010DEd000000D9sv*sd*bc*sc*i* snd_intel8x0m
ちょっと待って!これは前に出てきたベンダー/デバイス ID の情報ではないですか!
はい、その通りです。これは「alias <何か> <実際のモジュール>」という非常にシンプルなフォーマットです。実際、あなたが望むほとんど何でもエイリアスにすることができます。例えば、"alias boogabooga snd_intel8x0m" を追加すれば、安全に "modprobe boogabooga" を実行することができます。
"" は何でもマッチすることを示しており、これはファイルシステムの globbing(ls somedir/
)に似ています。前述のとおり、ほとんどのエイリアスは、"*" がマッチングすることにより、sv、sd、bc、sc、および i を無視します。
この modules.alias ファイルはどこから来るのですか?
さて、今、あなたは「おや、hardware probe はデバイステーブルに基づいてものを調べるために使用されていたが、これはどう違うのだろう?」と思っているかもしれません。
違いは、このルックアップテーブルが静的ではないことです。これは手動で維持されているわけではありません。実際、depmod
を実行するたびに、動的に構築されます。 "この情報はどこから来るのか?" とあなたが尋ねるなら、それはカーネルモジュールそれ自体からきています。考えてみると、各特定のモジュールは、そのハードウェアのために特にコード化されているので、それがサポートするハードウェアを知っているべきです。つまり、 nvidia モジュールの開発者は、そのモジュールがNvidia(ベンダー)のグラフィックスカード(クラス)でのみ動作することを知っています。実際、モジュールはこの情報をエクスポートします。それは「ねえ、私はこれをサポートできるよ」と言っています。
$ modinfo nvidia filename: /lib/modules/2.6.14-ARCH/kernel/drivers/video/nvidia.ko license: NVIDIA alias: char-major-195-* vermagic: 2.6.14-ARCH SMP preempt 686 gcc-4.1 depends: agpgart alias: pci:v000010DEd*sv*sd*bc03sc00i00*
リストされているエイリアスを見ると、特にベンダー "10DE"(Nvidia)と bc/sc 0300(おそらく「グラフィックスカード」を指している)を特定して検索していることがわかります。実際、snd_intel8x0m の modinfo を見てみます:
$ modinfo snd_intel8x0m filename: /lib/modules/2.6.14-ARCH/kernel/sound/pci/snd-intel8x0m.ko author: Jaroslav Kysela <perex@suse.cz> description: Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7013; NVidia MCP/2/2S/3 modems license: GPL vermagic: 2.6.14-ARCH SMP preempt 686 gcc-4.1 depends: snd-ac97-codec,snd-pcm,snd-page-alloc,snd alias: pci:v00008086d00002416sv*sd*bc*sc*i* alias: pci:v00008086d00002426sv*sd*bc*sc*i* alias: pci:v00008086d00002446sv*sd*bc*sc*i* alias: pci:v00008086d00002486sv*sd*bc*sc*i* alias: pci:v00008086d000024C6sv*sd*bc*sc*i* alias: pci:v00008086d000024D6sv*sd*bc*sc*i* alias: pci:v00008086d0000266Dsv*sd*bc*sc*i* alias: pci:v00008086d000027DDsv*sd*bc*sc*i* alias: pci:v00008086d00007196sv*sd*bc*sc*i* alias: pci:v00001022d00007446sv*sd*bc*sc*i* alias: pci:v00001039d00007013sv*sd*bc*sc*i* alias: pci:v000010DEd000001C1sv*sd*bc*sc*i* alias: pci:v000010DEd00000069sv*sd*bc*sc*i* alias: pci:v000010DEd00000089sv*sd*bc*sc*i* alias: pci:v000010DEd000000D9sv*sd*bc*sc*i*
それは、エイリアスファイルを 'grep' で検索して見つけたエイリアスと一致します。各モジュールによってエクスポートされるこれらのエイリアスは、depmod
によって収集され、動的に modules.alias
ファイルにマージされます。ルックアップテーブルを手動で変更することはありません、なぜならそれは即座に構築されるからです。各モジュールは、それがサポートするものを正確に知っているため、depmod
はその情報を使用してモジュールの読み込みを支援することができます。
udev はどのように動作するの?
udev は sysfs(最初に modalias を公開するファイルシステム)と密接に関連しています。実際、新しいデバイスが追加されたとき(または起動時に初めて udev が起動されたとき)に modalias に基づいてモジュールをロードするためには、驚くほどシンプルです:
DRIVER!="?*", ENV{MODALIAS}=="?*", RUN{builtin}="kmod load $env{MODALIAS}"
はい、それだけです。それは一行です。このシンプルな行は、デフォルトの udev ルールの一部であり、hotplug を置き換えます。驚くべきことではありませんか?
See also
This article shows others modalias templates, i.e. for usb, dmi and acpi subtypes
- Modalias strings - a practical way to map "stuff" to hardware by Petter Reinholdtsen