设备驱动中device_create函数与sys/devices目录

当调用device_create时parent参数为空时,新添加的设备位于sys/devices//sys/devices/virtual目录

以下面代码的为例
my_newcharled.myclass = class_create(THIS_MODULE,dtled);
my_newcharled.mydevice = device_create(my_newcharled.myclass,NULL,my_newcharled.newcharled_devt,NULL,dtled);

最终新添加的类 在/sys/class
在这里插入图片描述
通过在/sys/class进入设备
在这里插入图片描述
新添加的设备在/sys/devices/virtual
在这里插入图片描述

当按照字符设备标准驱动过程新建字符设备时,当调用device_create时parent参数为空时
device_create()
—>device_create_vargs
------>device_create_groups_vargs
--------->device_add
--------------->get_device_parent
------------------->virtual_device_parent   此时在/sys/devices/virtual中新增新的设备
主要是device_add中get_device_parent实现(device_add()函数其它功能学习后再分析)

int device_add(struct device *dev)
{
	struct device *parent;
	struct kobject *kobj;
	struct class_interface *class_intf;
	int error = -EINVAL;
	struct kobject *glue_dir = NULL;

	dev = get_device(dev);
	if (!dev)
		goto done;

	if (!dev->p) {
		error = device_private_init(dev);
		if (error)
			goto done;
	}

	if (dev->init_name) {
		dev_set_name(dev, "%s", dev->init_name);
		dev->init_name = NULL;
	}

	/* subsystems can specify simple device enumeration */
	if (!dev_name(dev) && dev->bus && dev->bus->dev_name)
		dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);

	if (!dev_name(dev)) {
		error = -EINVAL;
		goto name_error;
	}

	pr_debug("device: '%s': %s\n", dev_name(dev), __func__);

	parent = get_device(dev->parent);
	kobj = get_device_parent(dev, parent);
	if (IS_ERR(kobj)) {
		error = PTR_ERR(kobj);
		goto parent_error;
	}
	…………


}
EXPORT_SYMBOL_GPL(device_add);

get_device_parent()

static struct kobject *get_device_parent(struct device *dev,
					 struct device *parent)
{
	if (dev->class) {
		struct kobject *kobj = NULL;
		struct kobject *parent_kobj;
		struct kobject *k;

		 //获取/sys/devices/virtual目录对应的kobj
		if (parent == NULL)
			parent_kobj = virtual_device_parent(dev);
		else if (parent->class && !dev->class->ns_type)
			return &parent->kobj;
		else
			parent_kobj = &parent->kobj;

		mutex_lock(&gdp_mutex);
		//查看设备父目录是否存在
		//k->parent如果指定的话
        //k->parent如果没指定,但不是第一次创建时
		/* find our class-directory at the parent and reference it */
		spin_lock(&dev->class->p->glue_dirs.list_lock);
		list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry)
			if (k->parent == parent_kobj) {
				kobj = kobject_get(k);
				break;
			}
		spin_unlock(&dev->class->p->glue_dirs.list_lock);
		if (kobj) {
			mutex_unlock(&gdp_mutex);
			return kobj;
		}
		 //k->parent如果没指定,且是第一次创建时
		//在/sys/devices/virtual中创建新的设备目录
		/* or create a new class-directory at the parent device */
		k = class_dir_create_and_add(dev->class, parent_kobj);
		/* do not emit an uevent for this simple "glue" directory */
		mutex_unlock(&gdp_mutex);
		return k;
	}

	/* subsystems can specify a default root directory for their devices */
	if (!parent && dev->bus && dev->bus->dev_root)
		return &dev->bus->dev_root->kobj;

	if (parent)
		return &parent->kobj;
	return NULL;
}

virtual_device_parent()

struct kobject *virtual_device_parent(struct device *dev)
{
	static struct kobject *virtual_dir = NULL;
	if (!virtual_dir)
		virtual_dir = kobject_create_and_add("virtual",	&devices_kset->kobj);
	return virtual_dir;
}
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值