HP-UX主・副設備番号の表示
プライマリ/セカンダリ・デバイス番号の表示
文字デバイスが駆動する特殊なファイルは、ls-l出力の最初の列の「c」で表記できます./devの下にはブロックデバイスもありますが、それらは「b」で識別されます.以下に説明するいくつかの内容はブロックデバイスにも適用されるが,この章では文字デバイスにのみ注目する.
ls-lコマンドを実行すると、デバイスファイルエントリの最新の変更日までに2つの数(カンマで区切られた)が表示されます.この位置には通常、ファイル長が表示されます.この2つの数は、対応するデバイスのプライマリ・デバイス番号とセカンダリ・デバイス番号です.次のリストは、私が使用しているシステム上のデバイスを示しています.プライマリ・デバイス番号は10,7,1,4であり、セカンダリ・デバイス番号は0,3,5,64,5,129である.
crw-rw-rw- 1 root root 1, 3 Feb23 1999 null
crw------- 1 root root 10, 1 Feb23 1999 psaux
crw------- 1 rubini tty 4, 1 Aug16 22:22 tty1
crw-rw-rw- 1 root dialout 4, 64 Jun30 11:19 ttyS0
crw-rw-rw- 1 root dialout 4, 65 Aug16 00:00 ttyS1
crw------- 1 root sys 7, 1 Feb23 1999 vcs1
crw------- 1 root sys 7, 129 Feb 23 1999 vcsa1
crw-rw-rw- 1 root root 1, 5 Feb23 1999 zero
プライマリ・デバイス番号は、デバイスに対応するドライバを識別します.たとえば、/dev/nullおよび/dev/zeroはドライバ1によって管理され、すべての仮想コンソールおよびシリアルポート端末はドライバ4によって管理され、同様にvcs 1およびvcsa 1はドライバ7によって管理される.デバイスがオープンすると、カーネルはプライマリ・デバイス番号で対応するドライバを実行します.
セカンダリ・デバイス番号は、対応するデバイス・ドライバのみで使用されます.カーネルの他の部分は使用されず、ドライバにのみ渡されます.したがって、1つのドライバが複数のデバイスを管理することは珍しくなく(上記の例に示すように)、セカンダリシーケンス番号はそれらを区別する方法を提供する.2.4バージョンのカーネルには、デバイスファイルシステム、devfsという新しい特性が導入されています(オプション).このようなファイルシステムを使用すると、デバイスファイルは簡単になりますが、もともと大きな違いがあります.一方,この新しいファイルシステムは,一部のユーザに見られる互換性のない特性をもたらす.
適用
devfsが使用されていない場合、ドライバをシステムに追加することは、プライマリ・デバイス番号を割り当てることを意味します.この付与プロセスは、
int register_chrdev(unsigned intmajor, const char *name, struct file_operations *fops);
成功または失敗を示す値を返します.エラーを示す負の値を返します.成功を表すゼロまたは正の値を返します.パラメータmajorは要求されたプライマリ・デバイス番号であり、nameはあなたのデバイスの名前であり、/proc/devicesに表示されます.fopsは関数キューを指すポインタであり、デバイス関数の呼び出しを完了します.
プライマリ・デバイス番号は、静的文字デバイス・グループをインデックスする整数です.「≪プライマリ・デバイス番号の動的割当て|Dynamic Assign Primary Number|emdw≫」では、この章の後述で、プライマリ・デバイス番号の選択方法について説明します.2.0カーネルは128個のデバイスドライバをサポートし、2.2および2.4カーネルは256個をサポートします(数値0および255は将来使用されます).セカンダリ・バージョン番号(8ビットバイトの数)はregister_に渡されませんchrdev関数は、セカンダリバージョン番号がドライバ自身で使用されるためです.開発チームは、カーネルがサポートする可能性のあるデバイスの数を増やすために大きな圧力をもたらし、開発ツリー2.5バージョンのカーネルのターゲットでは、デバイス番号は少なくとも16ビットです.
デバイスドライバがカーネルテーブルに登録されると、その操作は割り当てられたプライマリ・デバイス番号と一致し、文字デバイス・ファイル上の操作がプライマリ・デバイス番号に関連付けられると、カーネルはfile_を通過します.operations構造体は、対応するドライバの関数を検索して呼び出します.そのためregister_に伝えるchrdevのポインタは、ローカルのモジュール初期化関数ではなく、ドライバ内のグローバル構造体を指すべきである.
次の問題は、デバイスドライバを要求するためにプログラムに名前を付ける方法です.この名前は/devディレクトリに挿入し、ドライバのプライマリ・デバイス番号とセカンダリ・デバイス番号に接続する必要があります.
ファイルシステム上でデバイスノードを作成するコマンドはmknodであり、操作するにはスーパーユーザーでなければなりません.作成するノード名に加えて、このコマンドには3つのパラメータがあります.たとえば、コマンド:
mknod/dev/scull0 c 254 0
プライマリ・デバイス番号254、セカンダリ・デバイス番号0の文字デバイス(c)を作成します.履歴上、セカンダリ・デバイス番号は0〜255の範囲内であるべきであり、1バイトに格納される場合がある.使用可能なセカンダリ・デバイス番号の範囲を拡張する理由はいくつかありますが、現在でも8ビットの制限があります.
mknodで特別なデバイスファイルを生成すると、削除しない限り、ハードディスク(HDD)に永遠に存在します.コマンド「rm」コマンドを実行することで、例のデバイスを削除できます.
rm/dev/scull0
プライマリ・デバイス番号の動的割当て
一部のプライマリ・デバイス番号は、ほとんどの一般的なデバイスに静的に割り当てられています.カーネルソースツリーのDocumentation/device.txtファイルには、これらのデバイスのリストが表示されます.多くの番号が割り当てられているため、新しいデバイスの一意の番号を選択することは困難です.構成可能なデバイスはプライマリ・デバイス番号よりずっと多いです.
幸いなことに、プライマリ・デバイス番号を動的に割り当てることができます.register_を呼び出すとchrdevでmajorを0に設定すると、関数は自動的に空き番号を選択し、デバイスとしてのプライマリデバイス番号を返します.返されるプライマリ・デバイス番号は常に正の値であり、負の値が返されるとエラーが表示されます.呼び出し者が動的なプライマリ・デバイス番号を要求すると関数register_chrdevの戻り値は、割り当てられたプライマリ・デバイス番号であり、予め定義されたプライマリ・デバイス番号に正常に登録された場合(すなわち、動的割り当てではなく静的割り当て方式)、関数の戻り値は0であり、プライマリ・デバイス番号ではない.
private dirversの場合、プライマリ・デバイス番号を得るには、動的に割り当てられた方法を使用することを強くお勧めします.逆に、ほとんどの場合、公式のカーネルツリーに含まれるデバイスが一般的に適用されている場合は、プライマリ・デバイス番号を専用に割り当てる必要があります.
動的割り当ての欠点は、プライマリ・デバイス番号が常に同じであることを保証できないため、mknodコマンドでデバイス・ノード(すなわち、デバイス・ファイル)を事前に作成することはできません(モジュールのロード時にスクリプトで自動的に作成できます).これは、Chapter 11で説明した「オンデマンド・ロード・モジュール(loading-on-demandof your driver)」の先進的な特性を使用できないことを意味します.一般的な用途に使用されるドライバでは、デバイス番号が割り当てられると、/proc/devicesから関連するデバイス番号情報を読み取ることができるため、これは問題ではありません.
動的割り当てでプライマリ・デバイス番号を取得するドライバをロードするには、insmodの呼び出しを簡単なスクリプトに置き換える必要があります.このスクリプトは、insmodを呼び出し、/proc/devicesを読み取り、プライマリ・デバイス番号を取得し、デバイス・ファイルを作成します.
≪インスタンス|Instance|emdw≫
次のスクリプト、scull_loadは、scullリリースの一部です.モジュール形式で発行するドライバを使用するユーザは、システムのrcから利用することができる.localファイルでこのスクリプトを呼び出すか、モジュールが必要なときに手動で呼び出す.rc.localは/etc/rc.d/で見つけます.(中国語版ではkerneldを使用する方法も記載されています.)
#!/bin/sh
module=”scull”
device =”scull”
mode =”664”
#invoke insmod with all
arguments we were passed
#and use a pathname, as
newer modutils don’t look in. by default
/sbin/insmod –f ./$module.o
$* || exit
#remove stale nodes
rm –f /dev/$(device)[0-3]
major=’awk “
[url=file://///$2==/]\\$2==\[/url]
”$module\” {print
[url=file://///$1]\\$1[/url]
}” /proc/devices’
mknod /dev/${device}0 c
$major 0
mknod /dev/${device}1 c
$major 1
mknod /dev/${device}2 c
$major 2
mknod /dev/${device}3 c
$major 3
#give appropriate group/permissions, and change the group.
#Not all distributions have staff; some have “wheel” instead.
group=”staff”
grep ‘^staff:’ /etc/group
> /dev/null || group=’wheel’
chgrp $group
/dev/${device}[0-3]
chmod $mode
/dev/${device}[0-3]
スクリプト内の変数を再定義し、mknodコマンドラインを修正すれば、スクリプトはドライバにも使用できます.