linux设备模型

来源:互联网 发布:乐知英语电话 编辑:程序博客网 时间:2024/06/06 03:06

linux2.6提供了新的设备模型:总线、驱动、设备。基本关系简要的概括如下:
驱动核心可以注册多种类型的总线。
每种总线下面可以挂载许多设备。(通过kset devices)
每种总线下可以用很多设备驱动。(通过包含一个kset drivers)}
每个驱动可以处理一组设备。按照我的理解就是所有的设备都挂载到总线上,当加载驱动时,驱动就支总线上找到自己对应的设备。或者先把驱动加载上,来了一个设备就去总线找驱动。

总线是处理器与设备之间通道,在设备模型中,所有的设备都通过总线相连

(1)bus_type.
struct bus_type {
 const char  * name;//设备名称

 struct subsystem subsys;//代表自身
 struct kset  drivers;   //当前总线的设备驱动集合
 struct kset  devices; //所有设备集合
 struct klist  klist_devices;
 struct klist  klist_drivers;

 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, char **envp,   
      int num_envp, char *buffer, int buffer_size);//热拔插事件
 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);
};

在后面的实例当中用到了里面的两个成员

1:const char *name;

2: int  (*match)(struct device * dev, struct device_driver * drv);//设备驱动匹配函数

这个匹配函数是很关键的东西,这是建立总线上设备与驱动的桥梁,当一个新的设备或驱动被添加到一个总线上时被调用。不同的bus会有不同的match实现,比如platform bus就是通过比较device和driver的名字来做匹配。

通常,我们是在board初始化(arch_initcall)时注册device,然后在驱动加载时注册driver(module_init或late_initcall),那么在加载driver的流程大致如下:

driver_register()

|

bus_add_driver()

|

bus_for_each_dev()

|

__driver_attach()

|

driver_probe_device()


而如果先注册driver,后注册device,那么流程如下:

device_add()

|

bus_probe_device()

|

device_attach()

|

bus_for_each_drv()

|

driver_probe_device()


0 0