个人对kobject的一点研究(3)

在platform的注册中,分为两个部分,一部分是注册到devices中,另一部分是注册到bus中,代码在/drivers/base/platform.c中
int __init platform_bus_init(void)
{
        int error;
       
        //注册到devices目录中
        error = device_register(&platform_bus);
        if (error)
                return error;

        //注册到bus目录中
        error =  bus_register(&platform_bus_type);
       
if (error)
                device_unregister(&platform_bus);
        return error;
}

首先是device_register,注册的参数为platform_bus,如下所示
struct device platform_bus = {
        .bus_id                = "platform",
};
很简单,只有一个参数,表明了目录名

int device_register(struct device *dev)
{
        //初始化dev结构
        device_initialize(dev);
        //添加dev至目录
        return device_add(dev);
}

void device_initialize(struct device *dev)
{
        //重要的一步,指明了父容器为devices_kset,而devices_kset的注册在前面已经介绍过了
        dev->kobj.kset = devices_kset;
        //初始化kobj的ktype为device_ktype
        kobject_init(&dev->kobj, &device_ktype);
        klist_init(&dev->klist_children, klist_children_get,
                   klist_children_put);
        INIT_LIST_HEAD(&dev->dma_pools);
        INIT_LIST_HEAD(&dev->node);
        init_MUTEX(&dev->sem);
        spin_lock_init(&dev->devres_lock);
        INIT_LIST_HEAD(&dev->devres_head);
        device_init_wakeup(dev, 0);
        set_dev_node(dev, -1);
}

int device_add(struct device *dev)
{
        struct device *parent = NULL;
        struct class_interface *class_intf;
        int error;

        dev = get_device(dev);
        if (!dev || !strlen(dev->bus_id)) {
                error = -EINVAL;
                goto Done;
        }

        pr_debug("device: '%s': %s\n", dev->bus_id, __func__);

        parent = get_device(dev->parent);
        setup_parent(dev, parent);

        if (parent)
                set_dev_node(dev, dev_to_node(parent));

        //设置dev->kobj的名字和父对象,并建立相应的目录
        error = kobject_add(&dev->kobj, dev->kobj.parent, "%s", dev->bus_id);
        if (error)
                goto Error;

        if (platform_notify)
                platform_notify(dev);

        if (dev->bus)
                blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                                             BUS_NOTIFY_ADD_DEVICE, dev);

        //建立uevent文件
        error = device_create_file(dev, &uevent_attr);
        if (error)
                goto attrError;

        if (MAJOR(dev->devt)) {
                error = device_create_file(dev, &devt_attr);
                if (error)
                        goto ueventattrError;
        }
        //建立subsystem连接文件连接到所属class,这里没有设置class对象所以不会建立
        error = device_add_class_symlinks(dev);
        if (error)
                goto SymlinkError;
        //建立dev的描述文件,这里没有设置描述文件所以不会建立
        error = device_add_attrs(dev);
        if (error)
                goto AttrsError;
        //建立链接文件至所属bus,这里没有设置所属bus所以不会建立
        error = bus_add_device(dev);
        if (error)
                goto BusError;
        //添加power文件,因为platform不属于设备,所以不会建立power文件
        error = device_pm_add(dev);
        if (error)
                goto PMError;
        kobject_uevent(&dev->kobj, KOBJ_ADD);

        //检测驱动中有无适合的设备进行匹配,但没有设置bus,所以不会进行匹配
        bus_attach_device(dev);
        if (parent)
                klist_add_tail(&dev->knode_parent, &parent->klist_children);

        if (dev->class) {
                down(&dev->class->sem);
                list_add_tail(&dev->node, &dev->class->devices);

                list_for_each_entry(class_intf, &dev->class->interfaces, node)
                        if (class_intf->add_dev)
                                class_intf->add_dev(dev, class_intf);
                up(&dev->class->sem);
        }
Done:
        put_device(dev);
        return error;
PMError:
        bus_remove_device(dev);
BusError:
        if (dev->bus)
                blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                                             BUS_NOTIFY_DEL_DEVICE, dev);
        device_remove_attrs(dev);
AttrsError:
        device_remove_class_symlinks(dev);
SymlinkError:
        if (MAJOR(dev->devt))
                device_remove_file(dev, &devt_attr);
ueventattrError:
        device_remove_file(dev, &uevent_attr);
attrError:
        kobject_uevent(&dev->kobj, KOBJ_REMOVE);
        kobject_del(&dev->kobj);
Error:
        cleanup_device_parent(dev);
        if (parent)
                put_device(parent);
        goto Done;
}



在kobject_add-> kobject_add_varg-> kobject_add_internal中

//提取父对象,因为没有设置,所以为空
parent = kobject_get(kobj->parent);

//父容器存在则设置父对象,在前面的dev->kobj.kset = devices_kset中设为了devices_kset
if (kobj->kset) {
//检测是否已经设置父对象
        if (!parent)
                //无则使用父容器为父对象
                parent = kobject_get(&kobj->kset->kobj);
//添加该kobj到父容器的链表中
        kobj_kset_join(kobj);

        //设置父对象
        kobj->parent = parent;
}
 

现在devices下的platform目录建立好了,模型如下,其中红线描绘了目录关系

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值