Heim  >  Artikel  >  System-Tutorial  >  Detaillierte Erläuterung des Linux-Gerätemodells (7)_Klasse

Detaillierte Erläuterung des Linux-Gerätemodells (7)_Klasse

WBOY
WBOYnach vorne
2024-02-13 22:39:191220Durchsuche

1. Übersicht

Im Gerätemodell sind Bus, Gerät, Gerätetreiber usw. relativ einfach zu verstehen, da sie alle realen Dingen entsprechen und sich die gesamte Logik um diese Entitäten dreht. Die in diesem Artikel beschriebene Klasse ist jedoch etwas anders, da sie virtuell ist, nur um die Gemeinsamkeit des Geräts zu abstrahieren.

Detaillierte Erläuterung des Linux-Gerätemodells (7)_Klasse

Wenn sich beispielsweise Menschen gleichen Alters, die sich ähnliche Kenntnisse aneignen müssen, zum Lernen zusammenschließen, bilden sie eine Klasse. Diese Klasse kann einen eigenen Namen haben (z. B. „295“), hat aber ohne die Schüler (Geräte), aus denen sie besteht, keine Bedeutung. Was ist außerdem die größte Bedeutung der Existenz von Klassen? Jeder Kurs wird von einem Lehrer unterrichtet! Da der Lehrer nur einmal sprechen muss, können die Schüler einer Klasse es hören. Wenn jeder Schüler zu Hause lernt, wird für jeden Schüler ein Lehrer eingestellt, der ihn auf diese Weise unterrichtet. Die meisten Inhalte sind gleich, was eine große Verschwendung darstellt.

Klasse im Gerätemodell bietet ähnliche Funktionalität. Beispielsweise müssen einige ähnliche Geräte (Studenten) ähnliche Schnittstellen (Kurse) zum Benutzerbereich bereitstellen. Wenn jeder Gerätetreiber einmal implementiert werden muss, führt dies zu einer großen Menge an redundantem Code im Kernel, was eine enorme Verschwendung darstellt. Also sagte Class: „Lass mich dir bei der Umsetzung helfen, solange du weißt, wie man es benutzt.“

Dies ist die Funktion der Klasse im Gerätemodell. In Kombination mit den Kommentaren des Kernels: Eine Klasse ist eine Ansicht eines Geräts auf höherer Ebene, die Implementierungsdetails auf niedriger Ebene abstrahiert (include/linux/device.h Zeile 326). Dies ist leicht zu verstehen.

2. Beschreibung der Datenstruktur

2.1 Strukturklasse

Strukturklasse ist die Abstraktion einer Klasse, ihre Definition lautet wie folgt:

   1: /* include/linux/device.h, line 332 */
   2: struct class {
   3:         const char              *name;
   4:         struct module           *owner;
   5:  
   6:         struct class_attribute          *class_attrs;
   7:         struct device_attribute         *dev_attrs;
   8:         struct bin_attribute            *dev_bin_attrs;
   9:         struct kobject                  *dev_kobj;
  10:  
  11:         int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
  12:         char *(*devnode)(struct device *dev, umode_t *mode);
  13:  
  14:         void (*class_release)(struct class *class);
  15:         void (*dev_release)(struct device *dev);
  16:  
  17:         int (*suspend)(struct device *dev, pm_message_t state);
  18:         int (*resume)(struct device *dev);
  19:  
  20:         const struct kobj_ns_type_operations *ns_type;
  21:         const void *(*namespace)(struct device *dev);
  22:  
  23:         const struct dev_pm_ops *pm;
  24:  
  25:         struct subsys_private *p;
  26: };

Tatsächlich sind Strukturklasse und Strukturbus sehr ähnlich, was wie folgt erklärt wird:

Name, der Name der Klasse, wird im Verzeichnis „/sys/class/“ angezeigt.

class_atrrs, das Standardattribut dieser Klasse, erstellt automatisch die entsprechende Attributdatei unter „/sys/class/xxx_class“, wenn die Klasse im Kernel registriert wird.

dev_attrs, die Attribute jedes Geräts unter dieser Klasse, erstellen automatisch die entsprechende Attributdatei im sysfs-Verzeichnis des Geräts, wenn das Gerät beim Kernel registriert wird.

dev_bin_attrs ist, ähnlich wie dev_attrs, nur ein binäres Attribut.

dev_kobj gibt das Verzeichnis unter /sys/dev/ für Geräte dieser Klasse an. Derzeit gibt es im Allgemeinen zwei Typen: char und block. Wenn dev_kobj NULL ist, ist char standardmäßig ausgewählt.

dev_uevent: Wenn sich ein Gerät unter dieser Klasse ändert, wird die uevent-Rückruffunktion der Klasse aufgerufen.

class_release, die Rückruffunktion, die für die Veröffentlichung selbst verwendet wird.

dev_release, wird als Rückruffunktion für Geräte innerhalb der Release-Klasse verwendet. In der Schnittstelle „device_release“ werden das Gerät, der Gerätetyp und die Klasse, in der sich das Gerät befindet, überprüft, um festzustellen, ob die Freigabeschnittstelle registriert ist. Wenn ja, wird die entsprechende Freigabeschnittstelle aufgerufen, um den Gerätezeiger freizugeben.

p, es ist dasselbe wie die Strukturbusstruktur in „Linux Device Model (6)_Bus“ und wird nicht noch einmal erläutert.

2.2 struct class_interface

struct class_interface ist eine Struktur, die es dem Klassentreiber ermöglicht, voreingestellte Rückruffunktionen (add_dev und remove_dev) aufzurufen, wenn ein Gerät unter der Klasse hinzugefügt oder entfernt wird. Was machst du also, wenn du sie anrufst? Sie können tun, was Sie wollen (z. B. den Namen des Geräts ändern), und dies wird vom jeweiligen Klassentreiber implementiert.

Die Struktur ist wie folgt definiert:

   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: };

3. 功能及内部逻辑解析

3.1 class的功能

看完上面的东西,蜗蜗依旧糊里糊涂的,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/mice

root@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 uevent

root@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)的功能,仅仅是:

  • 在/sys/class/目录下,创建一个本class的目录(input)
  • 在本目录下,创建每一个属于该class的设备的符号链接(如,把“sys/devices/platform/s3c2440-i2c.3/i2c-3/3-0048/input/input2/event2”设备链接到”/sys/class/input/event2”),这样就可以在本class目录下,访问该设备的所有特性(即attribute)
  • 另外,device在sysfs的目录下,也会创建一个subsystem的符号链接,链接到本class的目录

算了,我们还是先分析一下Class的核心逻辑都做了哪些事情,至于class到底有什么用处,可以在后续具体的子系统里面(如input子系统),更为细致的探讨。

3.2 class的注册

class的注册,是由__class_register接口(它的实现位于”drivers/base/class.c, line 609″)实现的,它的处理逻辑和bus的注册类似,主要包括:

  • Weisen Sie Platz für den Typzeiger struct subsys_private (cp) in der Klassenstruktur zu und initialisieren Sie die darin enthaltenen Felder, einschließlich cp->subsys.kobj.kset, cp->subsys.kobj.ktype usw.
  • Rufen Sie kset_register auf, um die Klasse zu registrieren (denken Sie an die Beschreibung in „Linux Device Model (6)_Bus“, eine Klasse ist ein Subsystem, daher ist die Registrierung einer Klasse auch ein Registrierungssubsystem). Nach Abschluss des Vorgangs wird im Verzeichnis /sys/class/ ein der Klasse (Subsystem) entsprechendes Verzeichnis erstellt
  • Rufen Sie die Schnittstelle add_class_attrs auf, um das Attribut, auf das der Zeiger class_attrs in der Klassenstruktur zeigt, zum Kernel hinzuzufügen. Nach der Ausführung sehen Sie die diesen Attributen entsprechenden Dateien im Verzeichnis /sys/class/xxx_class/

3.3 Klassenbezogene Aktionen während der Geräteregistrierung

In „Linux-Gerätemodell (5)_Gerät und Gerätetreiber“ haben wir über die beiden Datenstrukturen struct device und struct device_driver gesprochen. Die Struktur-Gerätestruktur enthält einen Strukturklassenzeiger (dies zeigt von der Seite, dass es sich bei der Klasse um Gerät A handelt). (Sammlung, sogar die Klasse kann der Treiber des Geräts sein). Wenn ein Klassentreiber eine Klasse beim Kernel registriert, muss er das Gerät der Klasse verwenden, indem er seinen eigenen Klassenzeiger auf die Klasse zeigt. Den Rest erledigt der Kernel bei der Registrierung des Geräts.

In diesem Abschnitt werden wir über die klassenbezogenen Aktionen bei der Registrierung des Geräts sprechen:

Die Geräteregistrierung wird letztendlich durch die Schnittstelle „device_add“ (drivers/base/core.c) implementiert. Zu den klassenbezogenen Aktionen in dieser Schnittstelle gehören:

  • Rufen Sie die Schnittstelle device_add_class_symlinks auf, um verschiedene in Abschnitt 3.1 beschriebene symbolische Links zu erstellen, d entsprechendes Klassenverzeichnis
  • Rufen Sie device_add_attrs auf, um durch die Klasse (class->dev_attrs) angegebene Attribute hinzuzufügen
  • Wenn es eine add_dev-Rückruffunktion gibt, die der Klasse entspricht, rufen Sie die Rückruffunktion auf

4. Fazit

Tatsächlich hat Wowo nach dem Ende dieses Artikels immer noch nicht herausgefunden, wie Klassen im Kernel verwendet werden. Aber das spielt keine Rolle. Bei der anschließenden Analyse von Subsystemen (wie Eingabesubsystem, RTC-Subsystem usw.) werden wir viele Anwendungsfälle von Klassen sehen. Wenn die Zeit gekommen ist, wird es sehr klar sein, wenn wir zurückblicken und zusammenfassen.

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Linux-Gerätemodells (7)_Klasse. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:lxlinux.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen