参考:

1)《LINUX设备驱动程序》第十四章 Linux 设备模型

2)内核源码2.6.38

内核初始化的时候会对设备模型作初始化,见init/main.c: start_kernel->rest_init->kernel_init->do_basic_setup->driver_init

设备模型中重要的数据结构

include/linux/kobject.h:

struct kobject

struct kset

include/linux/device.h:

struct device

struct device_driver

struct bus_type

struct class

1. kobject

Linux设备驱动模型是一个复杂的数据结构,kobject是构成设备驱动模型的基本元素,它总是嵌入到其他结构中,用于把高级对象连接到设备驱动模型上。kobject类似于面向对象中的基类,device,device driver,bus,class便是它的派生产物。struct device,struct device_driver,struct bus_type,struct class中都包含一个类型为struct kobject的成员。

kobject和虚拟文件系统sysfs有着紧密的联系,一个kobject结构对应sysfs下的一个目录。

Documentation/kobject.txt和Documentation/filesystems/sysfs.txt对kobject和sysfs有详细描述。

struct kobject定义在include/linux/kobject.h中:

 60 struct kobject {     
const char *name; /*对应sysfs中的目录名*/
struct list_head entry; /*同类kobject组成一个双向链表,entry是该链表中的一个节点*/
struct kobject *parent; /*指向父kobject*/
struct kset *kset; /*指向所属的kset*/
struct kobj_type *ktype; /*struct kobj_type中的struct attribute对应sysfs中的文件*/
struct sysfs_dirent *sd;
struct kref kref;
unsigned int state_initialized:;
unsigned int state_in_sysfs:;
unsigned int state_add_uevent_sent:;
unsigned int state_remove_uevent_sent:;
unsigned int uevent_suppress:;
};

内核用kobject结构将各个对象连接起来组成一个分层的结构体系,有两种独立的机制用于连接:parent指针和kset。

在kobject结构中的parent成员指向另一个kobject结构,这个结构表示了分层结构中的上一层节点。父kobject和kobject在sysfs中表现为目录与子目录的关系。

kset是同类kobject的集合。

struct kset定义在include/linux/kobject.h中:

 struct kset {
struct list_head list; /*kset包含的kobject组成一个链表,list指向该链表头*/
spinlock_t list_lock;
struct kobject kobj;
const struct kset_uevent_ops *uevent_ops;
};

kset通过链表来管理集合中的kobject,struct kset中的list成员指向该链表头。

struct kset结构中亦有一个struct kobject类型的成员,故kset在sysfs中同样对应一个目录。

大部分情况下,kset集合中koject的父kobject都指向该kset中的kobject成员。

kset,parent,kobject的关系如下图:

对kobject的操作函数定义在lib/kobject.c中。

2. 总线、设备、驱动、类

下面主要描述一下总线、设备、驱动、类之间的关系,Documentation/driver-model下亦有描述。对于总线、设备、驱动、类的操作函数的实现,code shows you everything,详见drivers/base下的bus.c,core.c,driver.c,dd.c,class.c等。

2.1 总线

总线是处理器与一个或多个设备之间的通道,在设备模型中,所有的设备都通过总线相连。总线用struct bus_type来描述,bus_type是该总线下设备和驱动的管理机构。

struct bus_type定义在include/linux/device.h中:

  struct bus_type {
const char *name;
struct bus_attribute *bus_attrs;
struct device_attribute *dev_attrs;
struct driver_attribute *drv_attrs; int (*match)(struct device *dev, struct device_driver *drv);
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
void (*shutdown)(struct device *dev); int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev); const struct dev_pm_ops *pm; struct subsys_private *p;
};

重点看一下结构struct subsys_private,该结构描述了总线与设备和驱动的关系:

  struct subsys_private {
struct kset subsys;
struct kset *devices_kset; struct kset *drivers_kset;
struct klist klist_devices;
struct klist klist_drivers;
struct blocking_notifier_head bus_notifier;
unsigned int drivers_autoprobe:;
struct bus_type *bus; struct list_head class_interfaces;
struct kset glue_dirs;
struct mutex class_mutex;
struct class *class;
};

1)devices_kset和drivers_kset分别指向该总线下所有设备和驱动的集合,在sysfs中,/sys/bus/xxx/下总是存在/sys/bus/xxx/devices和/sys/bus/xxx/drivers目录。

2)bus_type还管理着两个链表,klist_devices和 klist_drivers,分别表示该总线下的所有设备和所有驱动。

2.2 设备

设备驱动模型中,每一个设备都用struct device描述,struct device定义在include/linux/device.h中,下面只列出部分成员:

 struct device {
struct device *parent; struct device_private *p; struct kobject kobj;
......
...... struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
421 device */
......
...... struct klist_node knode_class;
struct class *class;
......
......
};
  struct device_private {
struct klist klist_children;
struct klist_node knode_parent;
struct klist_node knode_driver;
struct klist_node knode_bus;
void *driver_data;
struct device *device;
};

1)父子关系:它是一个父设备,它维护一个子设备的链表klist_children;它同时是一个子设备, parent指向它的父设备,knode_parent是该设备在其父设备的子设备链表中的节点;

2)与总线的关系:它挂在某个总线下,bus指向该总线的bus_type结构, knode_bus是其所在总线所维护的设备链表中的一个节点;

3)与驱动的关系:它是一个设备,理所当然要跟一个驱动匹配, driver指向与该设备匹配的device_driver结构,bus下的每一个驱动会维护一个设备链表表示该驱动支持的所有设备, knode_driver便表示该链表下的一个节点;

4)与类的关系:类是一个设备的高层视图,它抽象出了底层的实现细节,允许用户空间使用设备所提供的功能,而不关心设备是如何连接以及它们是如何工作的。即具体相似功能的设备被划为一类。class 指向该设备所属的类,每个类会维护一个链表表示该类型下的所有设备, knode_class便是该链表中的一个节点。

2.3 驱动

struct device_driver用来描述驱动程序,其定义在include/linux下:

 struct device_driver {
const char *name;
struct bus_type *bus; ......
......
struct driver_private *p;
};
  struct driver_private {
struct kobject kobj;
struct klist klist_devices;
struct klist_node knode_bus;
struct module_kobject *mkobj;
struct device_driver *driver;
};

1)与设备的关系:每个驱动程序可以支持多个设备,device_driver维护了一个链表表示该驱动支持的所有设备,klist_devices指向该链表头;

2)与总线的关系:每个总线维护一个链表表示该总线下的所有驱动,knode_bus便是该链表下的一个节点, bus指向该驱动所在的总线;

2.4

类是一个设备的高层视图,它抽象出了底层的实现细节,允许用户空间使用设备所提供的功能,而不关心设备是如何连接以及它们是如何工作的。即具体相似功能的设备被划为一类。类用struct class描述,定义在include/device.h中:

 struct class {
const char *name;
struct module *owner; struct class_attribute *class_attrs;
struct device_attribute *dev_attrs;
struct bin_attribute *dev_bin_attrs;
struct kobject *dev_kobj; int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
char *(*devnode)(struct device *dev, mode_t *mode); 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); const struct kobj_ns_type_operations *ns_type;
const void *(*namespace)(struct device *dev); const struct dev_pm_ops *pm; struct subsys_private *p;
};
 struct subsys_private {
struct kset subsys;
struct kset *devices_kset; struct kset *drivers_kset;
struct klist klist_devices;
struct klist klist_drivers;
struct blocking_notifier_head bus_notifier;
unsigned int drivers_autoprobe:;
struct bus_type *bus; struct list_head class_interfaces;
struct kset glue_dirs;
struct mutex class_mutex;
struct class *class;
};

1)与设备的关系:每个类会维护一个链表表示该类型下的所有设备, devices_kset指向该链表头

linux device model简述的更多相关文章

  1. The Linux device model

    /sys和 /dev的疑问 1./dev 下放的是设备文件,是由应用层mknod创建的文件.假设底层驱动对mknod的设备号有相应的驱动,如open等函数.那么应用层open "/dev/* ...

  2. The Linux usage model for device tree data

    Linux and the Device Tree The Linux usage model for device tree data Author: Grant Likely grant.like ...

  3. Linux Device Driver && Device File

    catalog . 设备驱动程序简介 . I/O体系结构 . 访问设备 . 与文件系统关联 . 字符设备操作 . 块设备操作 . 资源分配 . 总线系统 1. 设备驱动程序简介 设备驱动程序是内核的关 ...

  4. Linux device tree 简要笔记

    第一.DTS简介     在嵌入式设备上,可能有不同的主板---它们之间差异表现在主板资源不尽相同,比如I2C.SPI.GPIO等接口定义有差别,或者是Timer不同,等等.于是这就产生了BSP的一个 ...

  5. linux device tree源代码解析--转

    //Based on Linux v3.14 source code Linux设备树机制(Device Tree) 一.描述 ARM Device Tree起源于OpenFirmware (OF), ...

  6. How to learn linux device driver

    To learn device driver development, like any other new knowledge, the bestapproach for me is to lear ...

  7. linux device driver —— 环形缓冲区的实现

    还是没有接触到怎么控制硬件,但是在书里看到了一个挺巧妙的环形缓冲区实现. 此环形缓冲区实际为一个大小为bufsize的一维数组,有一个rp的读指针,一个wp的写指针. 在数据满时写进程会等待读进程读取 ...

  8. 《Linux Device Drivers》第十四章 Linux 设备型号

    基本介绍 2.6内核设备模型来提供的抽象叙述性描述的一般系统的结构,为了支持各种不同的任务 电源管理和系统关机 用户空间与通信 热插拔设备 设备类型 kobject.kset和子系统 kobject是 ...

  9. linux输入子系统简述【转】

    本文转载自:http://blog.csdn.net/xubin341719/article/details/7678035 1,linux输入子系统简述 其实驱动这部分大多还是转载别人的,linux ...

随机推荐

  1. NSSet类型 以及与NSArray区别

    NSSet到底什么类型,其实它和NSArray功能性质一样,用于存储对象,属于集合: NSSet  , NSMutableSet类声明编程接口对象,无序的集合,在内存中存储方式是不连续的,不像NSAr ...

  2. 计算机硬件——pci卡图片

    搞IT的还是软硬都要了解的好.1. PCI插槽 2. PCI-E 3. PCI-X 4. mini PCI  

  3. win xp32位与64位怎么查看是多少位系统

    方法一: Windows XP/Server2003几乎都是32位的操作系统 1. 单击“开始”,然后单击“运行”. 2. 在“打开”框中,键入cmd(再键入systeminfo)或者winmsd.e ...

  4. 20145305《JAVA程序设计》课程总结

    每周读书笔记链接汇总 问卷调查 第0周学习心得 第1周学习总结 第2周学习总结 第3周学习总结 第4周学习总结 第5周学习总结 第6周学习总结 第7周学习总结 第8周学习总结 第9周学习总结 第10周 ...

  5. 第十章 Vim程序编辑器学习

    1.Vim是进阶版的vi,vim不但可以用不同颜色显示文字内容,还能进行诸如shell script,C program等程序编辑功能. 区别:vi是老师的字处理器,不过功能已经很齐全,但还是有可以进 ...

  6. delphi TServerSocket阻塞线程单元 实例

    TServerSocket阻塞线程单元,希望对你有所帮助.需要注意的是:1.如果你使用TServerSocket的stNonBlocking模式,重写TServerClientThread线程时要重载 ...

  7. VS2013配置WTL90_4140_Final

    网上关于WTL的文章,尤其是中文的文章不多,根据收集的资料整理出了VS2013安装WTL的方法. 1.下载.文件很小的,地址:http://sourceforge.net/projects/wtl/f ...

  8. Chapter Schema

    Chapter Schema Schema是XF的核心,每一个读写方法都有一个相关联的Schema.方法首先解析Schema,然后再根据Schema的配置的执行. 那Schema是什么呢?Schema ...

  9. ASP.NET fails to detect Internet Explorer 10

    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9"> http://www.han ...

  10. 强大的内网劫持框架之MITMf

    Mitmf 是一款用来进行中间人攻击的工具.它可以结合 beef 一起来使用,并利用 beef 强大的 hook 脚本来控制目标客户端.下面让我们一起看看如何在 Kali2.0上安装使用 Mitmf ...