linux的sysfs与驱动模型体会1

使用的linux版本是2.6.18

 1、概念与重要的数据结构

 SYSFS是一个虚拟的文件系统,这个文件系统的目录结构实质上就是内核对象模型树。

 Kobject:内核对象,是模型树中的基本组成单位

53struct kobject {
 
54 const char * k_name;
 
55 char name[KOBJ_NAME_LEN];
 
56 struct kref kref;
 
57 struct list_head entry;
 
58 struct kobject * parent;
 
59 struct kset * kset;
 
60 struct kobj_type * ktype;
 
61 struct dentry * dentry;
 
62 wait_queue_head_t poll;
 
63};

kset:对象集合

127struct kset {
 
128 struct subsystem * subsys;
 
129 struct kobj_type * ktype;
 
130 struct list_head list;
 
131 spinlock_t list_lock;
 
132 struct kobject kobj;
 
133 struct kset_uevent_ops * uevent_ops;
 
134};

ktype:描述kobject的属性,可通过对属性的操作来作一些信息的获取或更改

96 struct kobj_type {
 
97 void (*release)(struct kobject *);
 
98 struct sysfs_ops * sysfs_ops;
 
99 struct attribute ** default_attrs;
 
100};

subsystem:子系统,实则上是一个kset,在高层次的概念 

176struct subsystem {
 
177 struct kset kset;
 
178 struct rw_semaphore rwsem;
 
179};

2、结构图

 <参见LDD3sysfs部分>关于ksetkobject之间的关系图。

 从该图可以看出,结构的组成,主要就是ksetkobject来组成各种高层次的结构。

 3bus子系统基本结构

38struct bus_type {
 
39 const char * name;
 
40
 
41 struct subsystem subsys;
 
42 struct kset drivers;
 
43 struct kset devices;
 
44 struct klist klist_devices;
 
45 struct klist klist_drivers;
 
46
 
47 struct blocking_notifier_head bus_notifier;
 
48
 
49 struct bus_attribute * bus_attrs;
 
50 struct device_attribute * dev_attrs;
 
51 struct driver_attribute * drv_attrs;
 
52
 
53 int (*match)(struct device * dev, structdevice_driver * drv);
 
54 int (*uevent)(struct device *dev, char **envp,
 
55 int num_envp, char *buffer, intbuffer_size);
 
56 int (*probe)(struct device * dev);
 
57 int (*remove)(struct device * dev);
 
58 void (*shutdown)(struct device * dev);
 
59
 
60 int (*suspend)(struct device * dev, pm_message_t state);
 
61 int (*suspend_late)(struct device * dev, pm_message_t state);
 
62 int (*resume_early)(struct device * dev);
 
63 int (*resume)(struct device * dev);
 
64};

bus_type内嵌了一个subsystem subsys,所以bus_type可以看作是一个类子系统,实则上就是一个子系统。

 通过分析i2c总线的注册过程和对应在sysfs中的目录结构来看。

bus_type– i2c_bus_type

 在/sys/目录下,看到目录实际上对应一个子系统。而我们要在这些子系统下新建一些子系统,对于i2c总线,我们要在bus子系统下挂接我们的i2c子系统。通过bus_register(&i2c_bus_type)来完成这一操作。具体的操作实际上就是插入一个kobject

 (1)对i2csub_syskobject设置名称,唯一的名称,这个名称会在/sys/bus/下看到。

kobject_set_name(i2c_bus_type.sub_sys.kset.kobject);
(2)然后就是设置这个子系统的父结点,也就是设定这个子系统的父子系统。所有总线的父子系统都是 bus_subsys
i2c_bus_type.sub_sys.kset.kobject.kset= bus_subsys.kset
(3)最后将 i2c_bus_type子系统加入到 bus_subsys集合内的子系统链表中。
i2c_bus_type.sub_sys.kset.kobject.parent= bus_subsys.kset.kobject
add_list_tail(i2c_bus_type.sub_sys.kset.kobject.entry,
bus_subsys.kset.list)

 以上的操作,基本上把i2c_bus_type对应的子系统加入到bus_subsys下面了,在/sys/bus/下面可以看到i2c目录。

 在bus_type中可以看到有两个kset,driversdevices。这两个kset属于i2c子系统下的两个集合。所以将这两个kset挂接到i2c子系统下面。

4)挂接devicesi2c子系统下面,完成后可在/sys/bus/i2c下看到devices目录

kobject_set_name(devices.kobject,“devices”);
devices.subsys= &i2c_bus_type.sub_sys;
devices.kobject.parent= i2c_bus_type.sub_sys.kset.kobject
add_list_tail(devices.kobject,i2c_bus_type.sub_sys.kset.list);

(5)同理,挂接driversi2c子系统下面,完成后可在/sys/bus/i2c下看到drivers目录

kobject_set_name(devices.kobject,“devices”);
devices.subsys= &i2c_bus_type.sub_sys;
devices.kobject.parent= i2c_bus_type.sub_sys.kset.kobject
add_list_tail(devices.kobject,i2c_bus_type.sub_sys.kset.list);
4bus子系统的设备与驱动
394struct device {
 
395 struct klist klist_children;
 
396 struct klist_node knode_parent; /* node insibling list */
 
397 struct klist_node knode_driver;
 
398 struct klist_node knode_bus;
 
399 struct device * parent;
 
400
 
401 struct kobject kobj;
 
402 char bus_id[BUS_ID_SIZE]; /* position on parent bus */
 
403 struct device_type *type;
 
404 unsigned is_registered:1;
 
405 struct device_attribute uevent_attr;
 
406 struct device_attribute *devt_attr;
 
407
 
408 struct semaphore sem; /* semaphore to synchronizecalls to
 
409 * its driver.
 
410 */
 
411
 
412 struct bus_type * bus; /* type of bus device is on*/
 
413 struct device_driver *driver; /* which driver has allocatedthis
 
414 device */
 
415 void *driver_data; /* data private to the driver*/
 
416 void *platform_data; /* Platform specific data,device
 
417 core doesn't touch it */
 
418 struct dev_pm_info power;
 
420#ifdef CONFIG_NUMA
 
421 int numa_node; /* NUMA node this device isclose to */
 
422#endif
 
423 u64 *dma_mask; /* dma mask (if dma'abledevice) */
 
424 u64 coherent_dma_mask;/* Like dma_mask, but for
 
425 alloc_coherent mappingsas
 
426 not all hardwaresupports
 
427 64 bit addresses forconsistent
 
428 allocations suchdescriptors. */
 
429
 
430 struct list_head dma_pools; /* dma pools (ifdma'ble) */
 
431
 
432 struct dma_coherent_mem *dma_mem; /* internal for coherentmem
 
433 override */
 
434 /* arch specific additions */
 
435 struct dev_archdata archdata;
 
436
 
437 spinlock_t devres_lock;
 
438 struct list_head devres_head;
 
439
 
440 /* class_device migration path */
 
441 struct list_head node;
 
442 struct class *class;
 
443 dev_t devt; /* dev_t, creates thesysfs "dev" */
 
444 struct attribute_group **groups; /* optional groups */
 
445 int uevent_suppress;
 
446
 
447 void (*release)(struct device * dev);
 
448};
 
 
 
120struct device_driver {
 
121 const char * name;
 
122 struct bus_type * bus;
 
123
 
124 struct completion unloaded;
 
125 struct kobject kobj;
 
126 struct klist klist_devices;
 
127 struct klist_node knode_bus;
 
128
 
129 struct module * owner;
 
130 const char * mod_name; /* used for built-inmodules */
 
131 struct module_kobject * mkobj;
 
132
 
133 int (*probe) (struct device * dev);
 
134 int (*remove) (struct device * dev);
 
135 void (*shutdown) (struct device * dev);
 
136 int (*suspend) (struct device * dev, pm_message_tstate);
 
137 int (*resume) (struct device * dev);
 
138
 
139 unsigned int multithread_probe:1;
 
140};

注册驱动程序:

driver_register(&i2c_adapter_driver);
i2c_adapter_driver内嵌了一个 kobject,也就是说它将以一个 kobject的模型挂接在系统的模型树里,在 sysfs中,作为一个目录节点。

kobject_set_name(i2c_adapter_driver.kobject,i2c_adatpter_driver.name)
 
i2c_adapter_driver.kobject.kset= i2c_adapter_driver.bus->sub_sys.kset
 
add_list_tail(i2c_adapter_driver.kobject,i2c_adapter_driver.kobject.kset.klist)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值