现在到bus_register了
注册的参数platform_bus_type如下所示
struct bus_type platform_bus_type = {
.name = "platform",
.dev_attrs = platform_dev_attrs,
.match = platform_match,
.uevent = platform_uevent,
.suspend = platform_suspend,
.suspend_late = platform_suspend_late,
.resume_early = platform_resume_early,
.resume = platform_resume,
};
int bus_register(struct bus_type *bus)
{
int retval;
//声明一个总线私有数据并分配空间
struct bus_type_private *priv;
priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
//互相关联
priv->bus = bus;
bus->p = priv;
BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
//设置私有数据中kobj对象的名字
retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
if (retval)
goto out;
//设置父容器为bus_kset,操作集为bus_ktype
priv->subsys.kobj.kset = bus_kset;
priv->subsys.kobj.ktype = &bus_ktype;
priv->drivers_autoprobe = 1;
//注册bus容器
retval = kset_register(&priv->subsys);
if (retval)
goto out;
//建立uevent属性文件
retval = bus_create_file(bus, &bus_attr_uevent);
if (retval)
goto bus_uevent_fail;
//建立devices目录
priv->devices_kset = kset_create_and_add("devices", NULL,
&priv->subsys.kobj);
if (!priv->devices_kset) {
retval = -ENOMEM;
goto bus_devices_fail;
}
//建立drivers目录
priv->drivers_kset = kset_create_and_add("drivers", NULL,
&priv->subsys.kobj);
if (!priv->drivers_kset) {
retval = -ENOMEM;
goto bus_drivers_fail;
}
//初始化klist_devices和klist_drivers链表
klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
klist_init(&priv->klist_drivers, NULL, NULL);
//增加probe属性文件
retval = add_probe_files(bus);
if (retval)
goto bus_probe_files_fail;
//增加总线的属性文件
retval = bus_add_attrs(bus);
if (retval)
goto bus_attrs_fail;
pr_debug("bus: '%s': registered\n", bus->name);
return 0;
bus_attrs_fail:
remove_probe_files(bus);
bus_probe_files_fail:
kset_unregister(bus->p->drivers_kset);
bus_drivers_fail:
kset_unregister(bus->p->devices_kset);
bus_devices_fail:
bus_remove_file(bus, &bus_attr_uevent);
bus_uevent_fail:
kset_unregister(&bus->p->subsys);
kfree(bus->p);
out:
return retval;
}
在kset_register-> kobject_add_internal中
//提取父对象,因为没有设置父对象,所以为空
parent = kobject_get(kobj->parent);
//父容器存在则设置父对象,在上文中设置了父容器priv->subsys.kobj.kset = bus_kset
if (kobj->kset) {
//检测是否已经设置父对象
if (!parent)
//无则使用父容器为父对象
parent = kobject_get(&kobj->kset->kobj);
//添加该kobj到父容器的链表中
kobj_kset_join(kobj);
//设置父对象
kobj->parent = parent;
}
在retval = kset_register(&priv->subsys)完成之后platform在bus下的模型如下图
有印象的话大家还记得在platform下面有两个目录devices和drivers吧~
现在就到这两个目录的注册了
priv->devices_kset = kset_create_and_add("devices", NULL,&priv->subsys.kobj);
priv->drivers_kset = kset_create_and_add("drivers", NULL, &priv->subsys.kobj);
注意这两条语句的头部
priv->devices_kset = kset_create_and_add
priv->drivers_kset = kset_create_and_add
可以清楚的看到bus_type_private下的devices_kset, drivers_kset分别连接到了devices,drivers的kset上
现在来看kset_create_and_add("devices", NULL,&priv->subsys.kobj);
struct kset *kset_create_and_add(const char *name,
struct kset_uevent_ops *uevent_ops,
struct kobject *parent_kobj)
//参数为"devices", NULL,&priv->subsys.kobj
{
struct kset *kset;
int error;
//创建一个kset容器
kset = kset_create(name, uevent_ops, parent_kobj);
if (!kset)
return NULL;
//注册创建的kset容器
error = kset_register(kset);
if (error) {
kfree(kset);
return NULL;
}
return kset;
}
在kset_create 中比较重要的操作为
kset->kobj.ktype = &kset_ktype //设置了ktype,为kset_ktype
kset->kobj.parent = parent_kobj; //设置了父对象,为priv->subsys.kobj,也就是platform_bus_type->p->subsys.kobj
kset->kobj.kset = NULL; //设置父容器为空
在kset_register中
//提取父对象
parent = kobject_get(kobj->parent); //在之前设置为了
//父容器存在则设置父对象,由于父容器为空,不执行以下代码
if (kobj->kset) {
//检测是否已经设置父对象
if (!parent)
//无则使用父容器为父对象
parent = kobject_get(&kobj->kset->kobj);
//添加该kobj到父容器的链表中
kobj_kset_join(kobj);
//设置父对象
kobj->parent = parent;
}
至此, devices的模型就建立好了,drivers模型的建立和devices是一致的,只是名字不同而已,我就不复述了,建立好的模型如下
好了~ 到了这里,bus,devices和platform的基础模型就就建立好了,就等设备来注册了