参考:

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. Java线程新特性--- Lock

    在Java5中,专门提供了锁对象,利用锁可以方便的实现资源的封锁,用来控制对竞争资源并发访问的控制,这些内容主要集中在java.util.concurrent.locks包下面,里面有三个重要的接口C ...

  2. proxmox3.2安装FreeBSD或者FreeNAS注意事项

    别的不多说了,白般尝试,终于安装成功,原来硬件要如下设置才行,如下: 1)内存要开大点,512M  800M都不行,最后开导2G才可以,如下: 2)kvm硬件虚拟化一定要选择“否”,默认是“是”,这里 ...

  3. centos6.4添加fedora-epel源

    1. 去sohu镜像下载epel-release-6包 并安装.#wget http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8. ...

  4. NodeJS常用工具

    一.NodeJS版本管理器n或者nvm npm install -g n npm install n -g --registry=https://registry.npm.taobao.org --v ...

  5. SelectedValue 失效

    /// <summary> /// 绑定代表下拉选项 /// </summary> public void BindOwnerDataII(string unitId, str ...

  6. Inno Setup中做补丁通过注册表获取原程序安装目录

    今天找VM补丁看到的,是个innosetup封装的,所以习惯性的喜欢去看人家的iss文件是怎么编写的. DefaultDirName={reg:HKLM\SOFTWARE\VMware%2c%20In ...

  7. affine transformation matrix 仿射变换矩阵 与 OpenGL

    变换模型是指根据待匹配图像与背景图像之间几何畸变的情况,所选择的能最佳拟合两幅图像之间变化的几何变换模型.可采用的变换模型有如下几种:刚性变换.仿射变换.透视变换和非线形变换等,如下图: 参考: ht ...

  8. C Primer Plus(第五版)6

    第 6 章 C 控制语句 : 循环 在本章中你将学习下列内容 已经多次学过,没怎么标注 · 关键字: for while do while · 运算符: < > >= <= ! ...

  9. 安装配置opensips

    opensips提供了一个视频教程(这个页面有下载链接,90M),参考教程 wget http://opensips.org/pub/opensips/1.9.1/src/opensips-1.9.1 ...

  10. 页面设计--Tree目录树

    Tree目录树控件属性: 根据数据集合来配置相应的信息 加载模式有自动加载.自定加载 web中显示效果图: