6/26/2011 8:52:56 PM

本文深入探讨了Linux设备模型中的关键概念和技术实现,包括如何通过函数bus_add_attrs为总线添加属性文件,设备类的结构及注册过程,以及设备类接口的作用和管理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

6/26/2011 8:52:56 PM

函数bus_add_attrs为本总线添加缺省属性文件,它将属性结构实例转换为sysfs中的属性文件,其列出如下:

static int bus_add_attrs(struct bus_type *bus)
{
 int error = 0;
 int i;
 
 if (bus->bus_attrs) {
  for (i = 0; attr_name(bus->bus_attrs[i]); i++) { /*遍历所有的总线属性实例*/
   error = bus_create_file(bus, &bus->bus_attrs[i]); /*创建属性文件*/
   if (error)
    goto err;
  }
 }
done:
 return error;
err:
 while (--i >= 0)
  bus_remove_file(bus, &bus->bus_attrs[i]);
 goto done;
}

添加缺省属性文件

一个设备类描述了一个设备类型,如音频设备和网卡设备,设备类结构device_class列出如下(在include/linux/devices.h中):

struct class {
 const char  *name;
 struct module  *owner;
 
 struct class_attribute  *class_attrs;   /*类属性*/
 struct device_attribute  *dev_attrs;
 struct kobject   *dev_kobj;
 
 int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
 
    /*下面域用于电源管理*/
 void (*class_release)(struct class *class);
 void (*dev_release)(struct device *dev);
 
 int (*suspend)(struct device *dev, pm_message_t state);
 int (*resume)(struct device *dev);
 
 struct pm_ops *pm;
 struct class_private *p;
};
结构class_private持有设备类对象结构class的私有数据,用于驱动程序核心代码,用户不应该使用。该结构描述了设备类内核对象间的关系。

结构class_private列出如下(在drivers/base/base.h中):

struct class_private {
 struct kset class_subsys;   /*设备类的内核对象集*/
 struct list_head class_devices;  /*与此设备类相关的设备链表*/
 struct list_head class_interfaces; /*与此设备类相关的类接口链表*/
 struct kset class_dirs;       /*与此设备类相关的虚拟设备的“胶合”目录*/
 struct mutex class_mutex;     /*保护设备类链表的互斥锁*/
 struct class *class;         /*回指结构class的指针*/
};
在sysfs文件系统中,所有设备类对象都在class目录下。该目录下的设备通过符号链接指向devices目录下的设备。目录class的部分内容列出如下:

^-^$ tree /sys/class
/sys/class
|-- backlight
|-- block
|   |-- dm-0 -> ../../devices/virtual/block/dm-0
|   |-- dm-1 -> ../../devices/virtual/block/dm-1
……
|-- mem
|   |-- full -> ../../devices/virtual/mem/full
|   |-- kmsg -> ../../devices/virtual/mem/kmsg
|   |-- mem -> ../../devices/virtual/mem/mem
|   |-- null -> ../../devices/virtual/mem/null
|   |-- oldmem -> ../../devices/virtual/mem/oldmem
|   |-- port -> ../../devices/virtual/mem/port
|   |-- random -> ../../devices/virtual/mem/random
|   |-- urandom -> ../../devices/virtual/mem/urandom
|   `-- zero -> ../../devices/virtual/mem/zero
……
|-- scsi_disk
|   |-- 0:0:0:0
|   |   |-- FUA
|   |   |-- allow_restart
|   |   |-- cache_type
|   |   |-- device -> ../../../devices/pci0000:00/0000:00:0d.0/host0/target0:0:0/0:0:0:0
|   |   |-- manage_start_stop
|   |   |-- subsystem -> ../../scsi_disk
|   |   `-- uevent
设备类用下列函数注册和注销:

extern int __must_check __class_register(struct class *class, struct lock_class_key *key);
extern void class_unregister(struct class *class);


设备类接口结构
设备类接口是直接与用户空间接口相关的设备类的逻辑接口,就象设备节点,用户可通过每个设备类的多个接口来访问同一个设备。如:一个SCSI硬盘将支持硬盘接口、SCSI通用接口和原始流设备接口。

设备注册到它们所属的类,当设备加到设备类中时,它们被加到与设备类注册到一起的每个接口中。这此接口负责决定设备是否支持某个接口。

设备类接口结构class_interface列出如下:

struct class_interface {
 struct list_head node;
 struct class  *class;
 
 int (*add_dev)  (struct device *, struct class_interface *);
 void (*remove_dev) (struct device *, struct class_interface *);
};
设备类接口的注册和注销函数列出如下:

extern int __must_check class_interface_register(struct class_interface *);
extern void class_interface_unregister(struct class_interface *);

类接口的注册和注销

一个接口必须定义它所属于的设备类,在注册时,该接口也被加到设备类的接口链表。接口在任何时候可被加到设备类中,当它被加入时,设备类中的每个设备被传递到接口的回调函数add_device。当一个接口被移除时,每个设备被从这个接口中移去。

当一个设备加到一个设备类时,它被加到设备类注册的每个接口中。

类接口

nest.js. [Nest] 84585 - 03/18/2025, 7:56:29 PM ERROR [TypeOrmModule] Unable to connect to the database. Retrying (2)... TypeError: Cannot convert undefined or null to object at Function.entries (<anonymous>) at validEnumValues (/Users/zhangshiyou/Desktop/study/nest-microservices/node_modules/.pnpm/class-validator@0.14.1/node_modules/src/decorator/typechecker/IsEnum.ts:18:17) at IsEnum (/Users/zhangshiyou/Desktop/study/nest-microservices/node_modules/.pnpm/class-validator@0.14.1/node_modules/src/decorator/typechecker/IsEnum.ts:30:29) at Object.<anonymous> (/Users/zhangshiyou/Desktop/study/nest-microservices/apps/service-base/src/modules/message/dto/index.ts:52:10) at Module._compile (node:internal/modules/cjs/loader:1562:14) at Object..js (node:internal/modules/cjs/loader:1699:10) at Module.load (node:internal/modules/cjs/loader:1313:32) at Function._load (node:internal/modules/cjs/loader:1123:12) at TracingChannel.traceSync (node:diagnostics_channel:322:14) at wrapModuleLoad (node:internal/modules/cjs/loader:217:24) [Nest] 84585 - 03/18/2025, 7:56:33 PM ERROR [TypeOrmModule] Unable to connect to the database. Retrying (3)... TypeError: Cannot convert undefined or null to object at Function.entries (<anonymous>) at validEnumValues (/Users/zhangshiyou/Desktop/study/nest-microservices/node_modules/.pnpm/class-validator@0.14.1/node_modules/src/decorator/typechecker/IsEnum.ts:18:17) at IsEnum (/Users/zhangshiyou/Desktop/study/nest-microservices/node_modules/.pnpm/class-validator@0.14.1/node_modules/src/decorator/typechecker/IsEnum.ts:30:29) at Object.<anonymous> (/Users/zhangshiyou/Desktop/study/nest-microservices/apps/service-base/src/modules/message/dto/index.ts:52:10) at Module._compile (node:internal/modules/cjs/loader:1562:14) at Object..js (node:internal/modules/cjs/loader:1699:10) at Module.load (node:internal/modules/cjs/loader:1313:32) at Function._load (node:internal/modules/cjs/loade
03-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值