浅析为什么device_create()生成文件添加到/sys/devices/virtual/目录

本文深入探讨了Linux设备模型中设备创建的过程,特别是针对没有指定父设备的情况如何在/sys/devices/virtual/tty/目录下创建设备节点,以及当指定了父设备时如何在父设备的类目录下创建子设备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于没有指定dev->parent的dev都将被添加到/sys/devices/virtual/tty/ 目录下
如果指定了dev->parent,那么同时该dev->class存在,同时parent->class存在,
那么该dev->name目录将被添加到parent->class所在目录下[luther.gliethttp]

luther@gliethttp:~$ ll /sys/class/tty/console
lrwxrwxrwx 1 root root 0 2009-06-30 09:40 /sys/class/tty/console -> ../../devices/virtual/tty/console
luther@gliethttp:~$ ll /sys/devices/virtual/tty/console/
total 0
-rw-r--r-- 1 root root 4.0K 2009-06-30 10:51 uevent
drwxr-xr-x 2 root root 0 2009-06-30 10:51 power
lrwxrwxrwx 1 root root 0 2009-06-30 10:57 subsystem -> ../../../../class/tty
-r--r--r-- 1 root root 4.0K 2009-06-30 10:57 dev

来看看linux2.6.25内核源码,是怎么做得.

device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), "console");
==>device_register
==>device_add
==>setup_parent
==>get_device_parent
==>dev->kobj.parent = kobj("/sys/devices/virtual/tty");//所以所有的文件添加都将指向该目录[luther.gliethttp]

#ifdef CONFIG_SYSFS_DEPRECATED
static struct kobject *get_device_parent(struct device *dev,
                     struct device *parent)
{
    /* class devices without a parent live in /sys/class/<classname>/ */
    if (dev->class && (!parent || parent->class != dev->class))
        return &dev->class->subsys.kobj;
    /* all other devices keep their parent */
    else if (parent)
        return &parent->kobj;

    return NULL;
}
#else
// 在我的ubnutu 8.10中使用的如下函数

static struct kobject *get_device_parent(struct device *dev,
                     struct device *parent)
{
    int retval;

    if (dev->class) {
        struct kobject *kobj = NULL;
        struct kobject *parent_kobj;
        struct kobject *k;

        /*
         * If we have no parent, we live in "virtual".
         * Class-devices with a non class-device as parent, live
         * in a "glue" directory to prevent namespace collisions.
         */

        if (parent == NULL)
            parent_kobj = virtual_device_parent(dev); // 获取/sys/devices/virtual目录对应的kobj

        else if (parent->class)
            return &parent->kobj;
        else
            parent_kobj = &parent->kobj;

        /* find our class-directory at the parent and reference it */
        spin_lock(&dev->class->class_dirs.list_lock);
        // class->class_dirs本身就是一个kset

        // 如果该kset的list链表上没有挂接到/sys/devices/virtual目录上的son,那么说明该class_dirs还没有在

        // /sys/devices/virtual目录下创建,所以就需要创建该class名对应的目录[luther.gliethttp]

        list_for_each_entry(k, &dev->class->class_dirs.list, entry)
            if (k->parent == parent_kobj) {
                kobj = kobject_get(k);
                break;
            }
        spin_unlock(&dev->class->class_dirs.list_lock);
        if (kobj)
            return kobj;
        // 创建/sys/devices/virtual/tty这个tty_class对应的目录

        /* or create a new class-directory at the parent device */
        k = kobject_create();
        if (!k)
            return NULL;
        k->kset = &dev->class->class_dirs; // 名在/sys/devices/virtual/目录下创建以tty_class的name为目录名的目录[luther.gliethttp]

        retval = kobject_add(k, parent_kobj, "%s", dev->class->name); // 将kobj添加到parent_kobj对应目录下[luther.gliethttp]

        if (retval < 0) {
            kobject_put(k);
            return NULL;
        }
        /* do not emit an uevent for this simple "glue" directory */
        return k;
    }

    if (parent)
        return &parent->kobj;
    return NULL;
}
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值