Chinaunix首页 | 论坛 | 博客
  • 博客访问: 236292
  • 博文数量: 54
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 431
  • 用 户 组: 普通用户
  • 注册时间: 2014-07-26 09:36
文章分类

全部博文(54)

分类: LINUX

2014-09-17 23:43:49

目录:

    1 概述
   
2 总线bus_type
    3 设备device
    4 驱动device_driver





1 概述

    Linux设备驱动模型采用分层分工的思想。设备驱动模型包含总线、设备、驱动三大组件。
    总线、设备、驱动三大组件之间的关系如下:

2 总线bus_type

    在设备驱动模型中,所有的设备都是通过总线连接的。总线是物理总线的一种抽象,同时还包含一些硬件中不存在的虚拟总线。
    在Linux设备驱动模型中,内核中的每一条总线都是通过bus_type来描述的:

点击(此处)折叠或打开

  1. --include/linux/device.h

  2. struct bus_type {
  3.         const char *name;                              /* 总线名称  */
  4.         struct bus_attribute      *bus_attrs;   /* 总线属性和导出到sysfs中的方法  */
  5.         struct device_attribute *dev_attrs;   /* 设备属性和导出到sysfs中的方法 */
  6.         struct driver_attribute  *drv_attrs;   /* 驱动属性和导出到sysfs中的方法  */

  7.         int (*match)(struct device *dev, struct device_driver *drv);         /*匹配函数 检验参数2的驱动知否支持参数1中的设备*/
  8.         int (*uevent)(struct device *dev, struct kobj_uevent_env *env);   /**/
  9.         int (*probe)(struct device *dev);               /* 设备探测函数 */
  10.         int (*remove)(struct device *dev);        /* 设备移除函数 */
  11.         void (*shutdown)(struct device *dev);  /* 设备关闭函数 */

  12.         int (*suspend)(struct device *dev, pm_message_t state);  /*设备挂起函数,用于节能 */
  13.         int (*resume)(struct device *dev);                                         /*设备恢复函数 */

  14.         const struct dev_pm_ops *pm;    /* 用于电源管理 */

  15.         struct bus_type_private *p;          /* 总线的私有数据 */
  16. };


相关资源:
(1)总线私有数据: struct bus_type_private

点击(此处)折叠或打开

  1. --driver/base/base.h

  2. /**
  3.  * struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure.
  4. * @subsys - the struct kset that defines this bus. This is the main kobject
  5.  * @drivers_kset - the list of drivers associated with this bus
  6.  * @devices_kset - the list of devices associated with this bus
  7.  * @klist_devices - the klist to iterate over the @devices_kset
  8.  * @klist_drivers - the klist to iterate over the @drivers_kset
  9.  * @bus_notifier - the bus notifier list for anything that cares about things
  10.  * on this bus.
  11.  * @bus - pointer back to the struct bus_type that this structure is associated
  12.  * with.
  13.  *
  14.  * This structure is the one that is the actual kobject allowing struct
  15.  * bus_type to be statically allocated safely. Nothing outside of the driver
  16.  * core should ever touch these fields.
  17.  */
  18. struct bus_type_private {
  19.         struct kset subsys;                    /* 代表bus子系统,里面的kobj是该bus的主kobj,也就是最顶层 */
  20.         struct kset *drivers_kset;      /*  挂载在该总线上的所有驱动的集合 */
  21.         struct kset *devices_kset;     /*  挂载在该总线上的所有设备的集合 */
  22.         struct klist klist_devices;       /*  总线的设备列表 */
  23.         struct klist klist_drivers;        /*  总线的驱动列表 */
  24.         struct blocking_notifier_head bus_notifier;   /* 通知链表 */
  25.         unsigned int drivers_autoprobe:1;    /* 设置是否在驱动注册时,自动探测设备 */
  26.         struct bus_type *bus;                          /*  总线和私有数据互指的指针  */
  27. };

(2)设备与驱动匹配:

 int (*match)(struct device *dev, struct device_driver *drv);

    该函数是设备和驱动进行关联过程中的一个关键的函数,当一个总线上有新的设备或者驱动添加时,该函数就会被调用(可能多次)。一般使用name或id进行设备和驱动的匹配工作。

(2) 总线的注册:
    总线构建完成好之后,第一个工作就是将总线注册到内核中,这个工作由下列函数来完成:

int bus_register (struct bus_type *bus)

点击(此处)折叠或打开

  1. --driver/base/bus.c

  2. /**
  3.  * bus_register - register a bus with the system.
  4.  * @bus: bus.
  5.  *
  6.  * Once we have that, we registered the bus with the kobject
  7.  * infrastructure, then register the children subsystems it has:
  8.  * the devices and drivers that belong to the bus.
  9.  */
  10. int bus_register(struct bus_type *bus)
  11. {
  12.         int retval;
  13.         struct bus_type_private *priv;

  14.         priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);        /* 构建总线私有数据 */
  15.         if (!priv)
  16.                 return -ENOMEM;

  17.         priv->bus = bus;        /* 总线与私有数据互指 */
  18.         bus->p = priv;              /* 总线与私有数据互指 */

  19.         BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);        /* 初始化通知链表 */

  20.         retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);     /* 设置子系统的名称为总线名称 */
  21.         if (retval)
  22.                 goto out;

  23.         priv->subsys.kobj.kset   =    bus_kset;        /* 私有数据集合指向总线集合 */
  24.         priv->subsys.kobj.ktype = &bus_ktype;       /* kobject属性文件,用于连接sys_ops */
  25.         priv->drivers_autoprobe = 1;                            /* 使能驱动自动加载 */

  26.         retval = kset_register(&priv->subsys);
  27.         if (retval)
  28.                 goto out;

  29.         retval = bus_create_file(bus, &bus_attr_uevent);
  30.         if (retval)
  31.                 goto bus_uevent_fail;

  32.         priv->devices_kset = kset_create_and_add("devices", NULL,
  33.                                                  &priv->subsys.kobj);
  34.         if (!priv->devices_kset) {
  35.                 retval = -ENOMEM;
  36.                 goto bus_devices_fail;
  37.         }

  38.         priv->drivers_kset = kset_create_and_add("drivers", NULL,
  39.         if (!priv->drivers_kset) {
  40.                 retval = -ENOMEM;
  41.                 goto bus_drivers_fail;
  42.         }

  43.         klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
  44.         klist_init(&priv->klist_drivers, NULL, NULL);

  45.         retval = add_probe_files(bus);
  46.         if (retval)
  47.                 goto bus_probe_files_fail;

  48.         retval = bus_add_attrs(bus);
  49.         if (retval)
  50.                 goto bus_attrs_fail;

  51.         pr_debug("bus: '%s': registered\n", bus->name);
  52.         return 0;

  53. bus_attrs_fail:
  54.         remove_probe_files(bus);
  55. bus_probe_files_fail:
  56.         kset_unregister(bus->p->drivers_kset);
  57. bus_drivers_fail:
  58.         kset_unregister(bus->p->devices_kset);
  59. bus_devices_fail:
  60.         bus_remove_file(bus, &bus_attr_uevent);
  61. bus_uevent_fail:
  62.         kset_unregister(&bus->p->subsys);
  63.         kfree(bus->p);
  64. out:
  65.         bus->p = NULL;
  66.         return retval;
  67. }
  68. EXPORT_SYMBOL_GPL(bus_register);
卸载总线由 int bus_unregister(struct bus_type *bus); 函数来完成。

3 设备device

    在Linux设备驱动模型中,每一个设备都有一个device结构体来进行描述:

点击(此处)折叠或打开

  1. --include/linux/device.h


  2. struct device {
  3.         struct device *parent;

  4.         struct device_private *p;

  5.         struct kobject kobj;
  6.         const char *init_name;                 /* initial name of the device ,to replace older version member bus_id
  7.                                                                 * reference to http://blog.chinaunix.net/uid-29767867-id-4536154.html
  8.                                                                 */
  9.         struct device_type *type;

  10.         struct semaphore sem;                /* semaphore to synchronize calls to its driver. */

  11.         struct bus_type *bus;                         /* type of bus device is on */
  12.         struct device_driver *driver;         /* which driver has allocated this device */
  13.         void *platform_data;                         /* Platform specific data, device core doesn't touch it */
  14.         struct dev_pm_info power;

  15. #ifdef CONFIG_NUMA
  16.         int numa_node;                                    /* NUMA node this device is close to */
  17. #endif
  18.         u64 *dma_mask;                                /* dma mask (if dma'able device) */

  19.         u64 coherent_dma_mask;          /* Like dma_mask, but for alloc_coherent mappings as all hardware supports
  20.                                                                 *  64 bit addresses for consistent allocations such descriptors.
  21.                                                                 */

  22.         struct device_dma_parameters *dma_parms;

  23.         struct list_head dma_pools;          /* dma pools (if dma'ble) */

  24.         struct dma_coherent_mem *dma_mem;       /* internal for coherent mem override */
  25.       
  26.       /* arch specific additions */
  27.         struct dev_archdata archdata;

  28.         dev_t devt;                               /* dev_t, creates the sysfs "dev" */

  29.         spinlock_t devres_lock;
  30.         struct list_head devres_head;

  31.         struct klist_node knode_class;
  32.         struct class *class;
  33.         const struct attribute_group **groups;                /* optional groups */

  34.         void (*release)(struct device *dev);
  35. };

4  驱动device_driver

    在设备驱动模型中,驱动使用device_driver结构体进行描述:

点击(此处)折叠或打开

  1. --include/linux/device.h

  2. struct device_driver {
  3.         const char *name;
  4.         struct bus_type *bus;

  5.         struct module *owner;
  6.         const char *mod_name;               /* used for built-in modules */

  7.         bool suppress_bind_attrs;         /* disables bind/unbind via sysfs */

  8.         int (*probe) (struct device *dev);
  9.         int (*remove) (struct device *dev);
  10.         void (*shutdown) (struct device *dev);
  11.         int (*suspend) (struct device *dev, pm_message_t state);
  12.         int (*resume) (struct device *dev);
  13.         const struct attribute_group **groups;

  14.         const struct dev_pm_ops *pm;

  15.         struct driver_private *p;
  16. };


阅读(1281) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~