Bus对应kset,driver和device对应kobject
Bus结构体包含2个klist,分别是driver和device的链表,driver和device中对应包含klist_node来插入链表
Driver结构体中包含1个klist,是device的链表,device中对应再包含一个klist_node来插入链表
/** * bus_add_driver - Add a driver to the bus. * @drv: driver. */ int bus_add_driver(struct device_driver *drv) { struct bus_type *bus; struct driver_private *priv; /* 作为device_driver一部分,包含kobject结构体 */ int error = 0;
bus = bus_get(drv->bus); /* 增加计数 */ if (!bus) return -EINVAL;
pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name); /* 分配空间,下文初始化,管理driver的设备驱动模型 */ priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { error = -ENOMEM; goto out_put_bus; } /*初始化klist成员,driver有一个klist结构,作为驱动管理的设备链表 */ klist_init(&priv->klist_devices, NULL, NULL); priv->driver = drv; drv->p = priv; /* 让driver的kobjet的kset成员指向bus的成员,表示driver属于bus */ priv->kobj.kset = bus->p->drivers_kset; /* 初始化driver的kobject,并且将它插到bus的kset中,同时在sysfs中在bus的目录下创建子目录。*/ error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL, "%s", drv->name); if (error) goto out_unregister; /* 将driver插入bus的klist链表 */ klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); /* 如果bus支持driver的自动搜索设备,则driver进入bus的设备链表,寻找匹配设备并调用probe函数初始化设备 */ if (drv->bus->p->drivers_autoprobe) { error = driver_attach(drv); if (error) goto out_unregister; } /* 在/sys/module/目录下显示driver */ module_add_driver(drv->owner, drv);
// 在/sys/bus/driver/目录下创建uevent file error = driver_create_file(drv, &driver_attr_uevent); if (error) { printk(KERN_ERR "%s: uevent attr (%s) failed\n", __func__, drv->name); } /*在/sys/bus/driver/目录下创建各种属性文件 */ error = driver_add_attrs(bus, drv); if (error) { /* How the hell do we get out of this pickle? Give up */ printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", __func__, drv->name); }
if (!drv->suppress_bind_attrs) { error = add_bind_files(drv); if (error) { /* Ditto */ printk(KERN_ERR "%s: add_bind_files(%s) failed\n", __func__, drv->name); } }
return 0;
out_unregister: kobject_put(&priv->kobj); kfree(drv->p); drv->p = NULL; out_put_bus: bus_put(bus); return error; } |
每个kobject必须有一个release方法,kobject嵌入的对象会一直存在,直到该方法被调用。