Linux设备驱动模型,主要函数分析
整个驱动模型中,最核心的三个函数分别是
__bus_register、driver_register、device_register
int __bus_register(struct bus_type *bus, struct lock_class_key *key)
retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);//设置总线的名字
retval = kset_register(&priv->subsys);//注册总线容器
priv->devices_kset = kset_create_and_add("devices", NULL,&priv->subsys.kobj);//创建一个在总线目录下的devices目录
priv->drivers_kset = kset_create_and_add("drivers", NULL,&priv->subsys.kobj);//创建一个在总线目录下的drivers目录
klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);//初始化设备链表
klist_init(&priv->klist_drivers, NULL, NULL);//初始化驱动程序链表
int driver_register(struct device_driver *drv)//注册driver到总线bus上
other = driver_find(drv->name, drv->bus);//查找是否已注册进总线
ret = bus_add_driver(drv);//此时总线上没注册该driver,开始注册driver
klist_init(&priv->klist_devices, NULL, NULL);//初始化设备链表
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,"%s", drv->name);//在driver目录中建立一个drv->name目录
error = driver_attach(drv);//进行driver和device的连接
bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);//遍历每个device并且调用__driver_attach
__driver_attach
driver_match_device(drv, dev)//匹配driver和device的名字
driver_probe_device(drv, dev);//匹配成功则调用探测函数probe
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);//将driver放进总线klist_drivers中
int device_register(struct device *dev)//注册device到总线上
device_initialize(dev);//初始化设备
device_add(dev);//添加device到bus中
bus_probe_device(dev);//进行driver和device的连接
device_attach(dev);
bus_for_each_drv(dev->bus, NULL, dev, __device_attach);//遍历每个driver并且调用__device_attach
__device_attach
driver_match_device(drv, dev)//匹配driver和device的名字
driver_probe_device(drv, dev);//匹配成功则调用探测函数probe
klist_add_tail(&dev->p->knode_parent,&parent->p->klist_children);
klist_add_tail(&dev->knode_class,&dev->class->p->klist_devices);//将device添加进总线klist_devices中