ホームページ > 記事 > システムチュートリアル > Linuxデバイスモデルの詳細説明(7)_Class
######1。概要######
たとえば、同じような年齢で同じような知識を習得する必要がある人が集まって勉強する場合、クラスを形成します。このクラスには独自の名前 (「295」など) を付けることができますが、それを構成する生徒 (デバイス) がなければ意味がありません。また、授業の存在の最大の意義は何でしょうか?どのコースも講師が丁寧に指導します!教師が話す必要があるのは 1 回だけであるため、クラスの生徒全員がそれを聞くことができます。生徒全員が自宅で勉強している場合、この方法で生徒を指導するために生徒ごとに教師が雇われることになります。内容はほとんど同じなので、非常にもったいないです。
デバイス モデルのクラスは同様の機能を提供します。たとえば、一部の同様のデバイス (学生) は、ユーザー空間に同様のインターフェイス (コース) を提供する必要があります。各デバイス ドライバーを 1 回実装する必要がある場合、カーネル内に大量の冗長コードが発生し、非常に無駄になります。したがって、クラスは「使用方法を知っている限り、実装を手伝いましょう。」と言いました。
これはデバイスモデルのクラスの機能です。カーネルのコメントと組み合わせると、クラスは低レベル実装の詳細 (include/linux/device.h line326) を抽象化したデバイスの高レベルのビューであり、理解しやすくなります。
2. データ構造の説明
」
実際、構造体クラスと構造体バスは非常に似ており、次のように説明されます:構造は次のように定義されます:name (クラスの名前) は、「/sys/class/」ディレクトリに反映されます。 クラスのデフォルト属性である class_atrrs は、クラスがカーネルに登録されるときに、対応する属性ファイルを「/sys/class/xxx_class」の下に自動的に作成します。
dev_attrs、このクラスの各デバイスの属性は、デバイスがカーネルに登録されるときに、デバイスの sysfs ディレクトリに対応する属性ファイルを自動的に作成します。
dev_bin_attrs は、dev_attrs と同様、単なるバイナリ型の属性です。
dev_kobj は、このクラス配下のデバイスの /sys/dev/ 配下のディレクトリを示します。現在、一般的に char と block の 2 種類があり、dev_kobj が NULL の場合、デフォルトで char が選択されます。
dev_uevent、このクラスのデバイスが変更されると、クラスの uevent コールバック関数が呼び出されます。
class_release、リリース自体に使用されるコールバック関数。
dev_release。リリース クラス内のデバイスのコールバック関数として使用されます。 device_release インターフェイスでは、デバイス、デバイス タイプ、およびデバイスが配置されているクラスをチェックして、リリース インターフェイスが登録されているかどうかを確認し、登録されている場合は、対応するリリース インターフェイスを呼び出してデバイス ポインターを解放します。
p は、「Linux デバイス モデル (6)_Bus」の構造体バス構造と同じであるため、説明を省略します。
」 #2.2 構造体クラスインターフェイスstruct class_interface は、クラスの下でデバイスが追加または削除されたときに、クラス ドライバーが事前に設定されたコールバック関数 (add_dev および Remove_dev) を呼び出すことを可能にする構造体です。それで、彼らに電話してどうするのですか?必要な操作 (デバイス名の変更など) を行うことができ、それは特定のクラス ドライバーによって実装されます。
1: /* include/linux/device.h, line 434 */ 2: struct class_interface { 3: struct list_head node; 4: struct class *class; 5: 6: int (*add_dev) (struct device *, struct class_interface *); 7: void (*remove_dev) (struct device *, struct class_interface *); 8: };
看完上面的东西,蜗蜗依旧糊里糊涂的,class到底提供了什么功能?怎么使用呢?让我们先看一下现有Linux系统中有关class的状况(这里以input class为例):
“
root@android:/ # ls /sys/class/input/ -l
lrwxrwxrwx root root 2014-04-23 03:39 event0 -> ../../devices/platform/i2c-gpio.17/i2c-17/17-0066/max77693-muic/input/input0/event0
lrwxrwxrwx root root 2014-04-23 03:39 event1 -> ../../devices/platform/gpio-keys.0/input/input1/event1
lrwxrwxrwx root root 2014-04-23 03:39 event10 -> ../../devices/virtual/input/input10/event10
lrwxrwxrwx root root 2014-04-23 03:39 event2 -> ../../devices/platform/s3c2440-i2c.3/i2c-3/3-0048/input/input2/event2
…
lrwxrwxrwx root root 2014-04-23 03:39 event8 -> ../../devices/platform/soc-audio/sound/card0/input8/event8
lrwxrwxrwx root root 2014-04-23 03:39 event9 -> ../../devices/platform/i2c-gpio.8/i2c-8/8-0020/input/input9/event9
lrwxrwxrwx root root 2014-04-23 03:39 input0 -> ../../devices/platform/i2c-gpio.17/i2c-17/17-0066/max77693-muic/input/input0
…
lrwxrwxrwx root root 2014-04-23 03:39 mice -> ../../devices/virtual/input/miceroot@android:/ # ls /sys/devices/platform/s3c2440-i2c.3/i2c-3/3-0048/input/input2/event2/ -l
-r–r–r– root root 4096 2014-04-23 04:08 dev
lrwxrwxrwx root root 2014-04-23 04:08 device -> ../../input2
drwxr-xr-x root root 2014-04-23 04:08 power
lrwxrwxrwx root root 2014-04-23 04:08 subsystem -> ../../../../../../../../class/input
-rw-r–r– root root 4096 2014-04-23 04:08 ueventroot@android:/ # ls /sys/devices/virtual/input/mice/ -l
-r–r–r– root root 4096 2014-04-23 03:57 dev
drwxr-xr-x root root 2014-04-23 03:57 power
lrwxrwxrwx root root 2014-04-23 03:57 subsystem -> ../../../../class/input
-rw-r–r– root root 4096 2014-04-23 03:57 uevent”
看上面的例子,发现input class也没做什么实实在在的事儿,它(input class)的功能,仅仅是:
算了,我们还是先分析一下Class的核心逻辑都做了哪些事情,至于class到底有什么用处,可以在后续具体的子系统里面(如input子系统),更为细致的探讨。
“
class的注册,是由__class_register接口(它的实现位于”drivers/base/class.c, line 609″)实现的,它的处理逻辑和bus的注册类似,主要包括:
- クラス構造内で struct subsys_private 型ポインター (cp) 用のスペースを割り当て、その中のフィールド (cp->subsys.kobj.kset、cp->subsys.kobj.ktype など) を初期化します。
- kset_register を呼び出してクラスを登録します (「Linux デバイス モデル (6)_Bus」の説明を思い出してください。クラスはサブシステムであるため、クラスの登録も登録サブシステムです)。処理が完了すると、/sys/class/ディレクトリ
にクラス(サブシステム)に対応したディレクトリが作成されます。- add_class_attrs インターフェイスを呼び出して、クラス構造内の class_attrs ポインターが指す属性をカーネルに追加します。実行後、これらの属性に対応するファイルが /sys/class/xxx_class/ ディレクトリ
# に表示されます。#''
このセクションでは、デバイスを登録するときのクラス関連のアクションについて説明します。
#「実際のところ、この記事を終えた後でも、Wowo はカーネル内でクラスがどのように使用されるかをまだ理解していません。その後のサブシステム (入力サブシステム、RTC サブシステムなど) の分析では、クラスの使用例が多数登場します。その時が来て、振り返って要約すると、非常に明確になります。」 デバイスの登録は、最終的に device_add インターフェイス (drivers/base/core.c) によって実装されます。このインターフェイスのクラス関連アクションには次のものが含まれます:
device_add_class_symlinks インターフェイスを呼び出して、セクション 3.1 で説明されているさまざまなシンボリック リンクを作成します。つまり、クラスに対応するディレクトリにデバイスを指すシンボリック リンクを作成し、デバイスのディレクトリにサブシステムを指すサブシステムという名前のシンボリック リンクを作成します。対応するクラスディレクトリ
- device_add_attrs を呼び出して、クラスで指定された属性を追加します (class->dev_attrs)
- クラスに対応する add_dev コールバック関数がある場合は、そのコールバック関数を呼び出します。
- #''
4 結論
以上がLinuxデバイスモデルの詳細説明(7)_Classの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。