http://blog.chinaunix.net/uid-20672257-id-3147001.html
linux中每个设备驱动由一个struct device_driver描述:
- struct device_driver {
- const char *name; //设备驱动程序的名称
- struct bus_type *bus; //该驱动所管理的设备挂接的总线类型
- struct module *owner;
- const char *mod_name; /* used for built-in modules */
- 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);
- struct attribute_group **groups;
- struct dev_pm_ops *pm;
- 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;
- };
- struct driver_attribute {
- struct attribute attr;
- ssize_t (*show)(struct device_driver *driver, char *buf);
- ssize_t (*store)(struct device_driver *driver, const char *buf,
- size_t count);
- };
可以看出device结构体中也包含了一个kobject对象和连接设备的链表。
当设备从系统总删除是remove被调用。
当系统关机的时候shutdown被调用。
int driver_register(struct driver *drv)
删除一个设备驱动
void driver_unregister(struct driver *drv)
struct device_driver中有个int (*probe) (struct device *dev)函数,它什么时候调用呢?
device_driver中name指向驱动的名字,前面的struct device中也有一个名为bus_id的字符数组。查看一下,struct bus_type中有一个match函数,这个是干什么用的呢。设备有了驱动才可以工作,只有驱动没有设备也是不行,驱动和设备需要关联上,这就需要这个match函数。驱动和设备是通过name来管理的,所以在总线驱动match函数中要比较device的bus_id和driver中的name是否相等,什么时候比较?只要往总线添加设备或驱动时,总线都会把调用match函数对新添加的设备或驱动中名字与总线中已经注册的驱动或设备的名字一一比较。如果有相等,就说明驱动和设备互相找到了,这时device_driver中的probe函数就被调用。
添加设备驱动例子,添加到前面创建的my_bus总线上:
创建一个名为“bus_dev”的驱动,并将bus成员指向第一步创建的my_bus_type总线
加载驱动将会打印:Driver found device which my driver can handle!查看/sys/bus/my_bus/driver
ls /sys/bus/my_bus/driver
my_dev