>  기사  >  시스템 튜토리얼  >  Linux 장치 모델에 대한 자세한 설명(7)_클래스

Linux 장치 모델에 대한 자세한 설명(7)_클래스

WBOY
WBOY앞으로
2024-02-13 22:39:191241검색

1. 개요

장치 모델에서 버스, 장치, 장치 드라이버 등은 모두 실제 사물에 해당하고 모든 논리가 이러한 엔터티를 중심으로 돌아가기 때문에 상대적으로 이해하기 쉽습니다. 다만, 본 글에서 설명하는 클래스는 가상 클래스이므로 장치의 공통성을 추상화하기 위해 다소 차이가 있다.

Linux 장치 모델에 대한 자세한 설명(7)_클래스

예를 들어, 비슷한 나이대에 비슷한 지식이 필요한 사람들이 모여서 공부한다면, 그들은 반을 형성합니다. 이 클래스는 고유한 이름(예: "295")을 가질 수 있지만 이를 구성하는 학생(장치)이 없으면 의미가 없습니다. 또한, 클래스의 존재의 가장 큰 의미는 무엇입니까? 모든 강좌는 선생님이 진행합니다! 교사는 한 번만 말하면 되기 때문에 수업에 참여하는 학생들은 그 내용을 들을 수 있습니다. 모든 학생이 집에서 공부한다면 각 학생마다 교사를 고용하여 이런 식으로 가르칠 것입니다. 대부분의 내용이 동일해서 엄청난 낭비입니다.

장치 모델의 클래스는 유사한 기능을 제공합니다. 예를 들어 일부 유사한 장치(학생)는 사용자 공간에 유사한 인터페이스(강의)를 제공해야 합니다. 각 장치 드라이버를 한 번만 구현해야 한다면 커널에 많은 양의 중복 코드가 발생하게 되어 엄청난 낭비가 됩니다. 그래서 Class는 "사용 방법을 알고 있는 한 구현을 도와드리겠습니다."라고 말했습니다.

기기 모델의 클래스 기능입니다. 커널 설명과 결합하면 클래스는 낮은 수준의 구현 세부 정보(include/linux/device.h line326)를 추상화하는 장치의 상위 수준 보기이므로 이해하기 쉽습니다.

2. 데이터 구조 설명

2.1 구조체 클래스

struct 클래스는 클래스의 추상화이며 정의는 다음과 같습니다.

으아아아

사실 구조체 클래스와 구조체 버스는 매우 유사하며 다음과 같이 설명됩니다.

name, 클래스 이름은 "/sys/class/" 디렉터리에 반영됩니다.

이 클래스의 기본 속성인 class_atrrs는 클래스가 커널에 등록되면 "/sys/class/xxx_class" 아래에 해당 속성 파일을 자동으로 생성합니다.

dev_attrs, 이 클래스에 속한 각 장치의 속성은 장치가 커널에 등록될 때 장치의 sysfs 디렉터리에 해당 속성 파일을 자동으로 생성합니다.

dev_bin_attrs는 dev_attrs와 유사하며 바이너리 유형 속성일 뿐입니다.

dev_kobj는 이 클래스 아래의 장치가 /sys/dev/ 아래의 디렉터리에 있음을 의미합니다. 현재 일반적으로 char 및 block의 두 가지 유형이 있습니다. dev_kobj가 NULL이면 기본적으로 char가 선택됩니다.

dev_uevent, 이 클래스 아래의 장치가 변경되면 해당 클래스의 uevent 콜백 함수가 호출됩니다.

class_release, 릴리스 자체에 사용되는 콜백 함수입니다.

dev_release, 릴리스 클래스 내의 장치에 대한 콜백 함수로 사용됩니다. device_release 인터페이스에서는 릴리스 인터페이스가 등록되어 있는지 확인하기 위해 Device, Device Type 및 Device가 위치한 클래스를 검사합니다. 등록된 경우 해당 릴리스 인터페이스를 호출하여 장치 포인터를 해제합니다.

p, "Linux Device Model (6)_Bus"의 버스 구조체 구조와 동일하므로 다시 설명하지 않겠습니다.

2.2 구조체 클래스_인터페이스

struct class_interface는 클래스 아래에 장치가 추가되거나 제거될 때 클래스 드라이버가 미리 설정된 콜백 함수(add_dev 및 제거_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: };

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的注册类似,主要包括:

  • 클래스 구조에서 struct subsys_private 유형 포인터(cp)에 공간을 할당하고 cp->subsys.kobj.kset, cp->subsys.kobj.ktype 등을 포함하여 그 안의 필드를 초기화합니다.
  • kset_register를 호출하여 클래스를 등록합니다("Linux Device Model (6)_Bus"의 설명을 기억하세요. 클래스는 하위 시스템이므로 클래스 등록도 등록 하위 시스템입니다). 프로세스가 완료되면 /sys/class/ 디렉터리에 클래스(서브시스템)에 해당하는 디렉터리가 생성됩니다
  • add_class_attrs 인터페이스를 호출하여 클래스 구조의 class_attrs 포인터가 가리키는 속성을 커널에 추가합니다. 실행 후에는 /sys/class/xxx_class/ 디렉터리
  • 에서 이러한 속성에 해당하는 파일을 볼 수 있습니다.

3.3 기기 등록 중 수업 관련 작업

"Linux 장치 모델(5)_device 및 장치 드라이버"에서 우리는 struct device와 struct device_driver라는 두 가지 데이터 구조에 대해 이야기했습니다. struct 장치 구조에는 구조체 클래스 포인터가 포함됩니다(이것은 클래스가 장치 A라는 측면에서 보여줍니다). 심지어 클래스의 컬렉션은 장치의 드라이버가 될 수도 있습니다). 클래스 드라이버가 커널에 클래스를 등록할 때 클래스에 대한 자체 클래스 포인터를 가리켜 클래스의 장치를 사용해야 합니다. 커널은 장치를 등록할 때 나머지를 처리합니다.

이 섹션에서는 장치 등록 시 수업 관련 작업에 대해 설명합니다.

장치 등록은 궁극적으로 device_add 인터페이스(drivers/base/core.c)에 의해 구현됩니다. 이 인터페이스의 클래스 관련 작업은 다음과 같습니다.

  • device_add_class_symlinks 인터페이스를 호출하여 섹션 3.1에 설명된 다양한 심볼릭 링크를 생성합니다. 즉, 해당 클래스의 디렉터리에서 장치를 가리키는 심볼릭 링크를 생성하고, 해당 클래스를 가리키는 subsystem이라는 심볼릭 링크를 생성합니다. 해당 수업 디렉토리
  • 클래스에 지정된 속성을 추가하려면 device_add_attrs를 호출하세요(class->dev_attrs)
  • 해당 클래스에 해당하는 add_dev 콜백 함수가 있으면 콜백 함수를 호출하세요

4. 결론

사실 이 글이 끝난 후에도 Wowo는 커널에서 클래스가 어떻게 사용되는지 아직 파악하지 못했습니다. 그러나 이는 중요하지 않습니다. 하위 시스템(예: 입력 하위 시스템, RTC 하위 시스템 등)에 대한 후속 분석에서는 클래스의 많은 사용 사례를 볼 수 있습니다. 때가 되면 우리가 되돌아보고 요약하면 매우 분명해질 것입니다.

위 내용은 Linux 장치 모델에 대한 자세한 설명(7)_클래스의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 lxlinux.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제