device_create和device_add和udev
有看到之前的一个帖子是这么回复device_create和device_add的区别:
device_create() 创建一个设备并注册到内核驱动架构...
device_add() 注册一个设备到内核,,少了一个创建设备..
是不是说调用device_create会在/dev/目录下创建结点,device_add不会。
查看源码(2.6.30.4)
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...)
{
.....
dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
....
return dev;
}
struct device *device_create_vargs(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt,
va_list args)
{
struct device *dev = NULL;
int retval = -ENODEV;
if (class == NULL || IS_ERR(class))
goto error;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
retval = -ENOMEM;
goto error;
}
dev->devt = devt;
dev->class = class;
dev->parent = parent;
dev->release = device_create_release;
dev_set_drvdata(dev, drvdata);
retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
if (retval)
goto error;
retval = device_register(dev);
if (retval)
goto error;
return dev;
error:
put_device(dev);
return ERR_PTR(retval);
}
然后device_register会调用device_add。
我想知道,到底device_create相对于device_add多做了什么样的工作,才会让/dev下创建一个结点。
换句话说,就是udev是怎么工作的,如何自动添加设备结点。 除了函数device_create还有其他的函数可以让udev也可以自动添加设备结点么。
我用source insight查看了下,整个源码调用它的好像并不是很多。
新手小白。多多指教。。各位大婶们。 在dev下创建节点的是mknod等,由udev干的。好像是内核发了一个notify还是什么记不清楚了 调用device_create和直接调用device_add的区别,就只是在参数devt上,如果devt为0(即直接调用device_add),那么devtmpfs就不会创建节点
udev也同理,如果uevent中没有devt,那么udev也不会创建这个节点
回复 1# darling54454
device_create
|
+ -- kzalloc struct device
|
+---device_register
|
+-----device_initialize
|
+-----device_add
device_create比device_add多做的事情非常清楚了呀。多一:
1. 新建struct device, device_add是不会新建的,只会加。
2. 进行了初始化, 如果不调device_register, 就得自己去调用device_initiali初始化。
关于第二点,device_register的函数说明说得很清楚:
/**
* device_register - register a device with the system.
* @dev: pointer to the device structure
*
* This happens in two clean steps - initialize the device
* and add it to the system. The two steps can be called
* separately, but this is the easiest and most common.
* I.e. you should only call the two helpers separately if
* have a clearly defined need to use and refcount the device
* before it is added to the hierarchy.
*/
关于正真设备文件的创建(不是指sys下的文件), 最终是由device_add函数里头的kobject_uevent(&dev->kobj, KOBJ_ADD)完成的对hotplug_helper的调用的。
如果想了解uevent的详情,可以阅读《Linux设备模型浅析之uevent篇》或者他的一系列文章。
http://wenku.baidu.com/link?url=CBh1XjmvfQ0Gs2ndHvnjk5Zi5afJ01hrioPdX_NFDOV7bk14XP1SD2SNdyIR3pOKagw0wNr6IqHON2kodayudYZm6uL6GDxuKlOn41H7u77
回复 4# arm-linux-gcc
那这样说的话,在/sys下产生了一个dev属性文件,那么这个设备就会被创建在/dev/目录下咯。
暂且可以理解为,在系统启动之后udev根据dev属性文件来创建设备结点(不考虑热插拔机制)
回复 5# Tinnal
感谢你的回复。之后是需要去了解一下udev的工作原理。
device_create相对于device_add就是分配了一个device结构体,并初始化了dev_t设备号、class类、parent父设备等。
那样说就是调用device_add时候参数dev已经是分配了空间了的。
如果调用device_add的参数dev也对dev_t/class/parent等参数进行了赋值,其效果差不多等价于device_create。。。
按照楼上大哥说,dev_t只要不是为0,那么udev都会在/dev/目录下创建设备结点。 darling54454 发表于 2014-08-25 15:42 static/image/common/back.gif
回复 4# arm-linux-gcc
那这样说的话,在/sys下产生了一个dev属性文件,那么这个设备就会被创建在/dev/目 ...
sys目录是一个伪文件系统,内核代码会直接在此目录下创建文件。和proc文件系统是一样的。下面举几个函数:
sysfs_create_file
sysfs_remove_file
sysfs_create_link
这些函数一般不用我们自己去调用。除非你想在/sys目录下建立你的特殊文件。
而/dev/目录是一个正常的目录。内核是不会直接在此目录下新建文件的。
因此,完整的过程是:我们的驱动注册-》sysfs节点创建-》uevent-》udev通过环境变量或/sys获取对应的信息建立/dev/下的设备文件-》udev调用更高层的用户态命令,如mount
因此/sys文件是/dev文件的必要非充分条件。 回复 5# Tinnal
现在貌似udev是netlink上报的了,不是hotplug_helper了;
可以手动删除设备节点后,udev通过手动触发(也是通过sysfs的uevent)生成和原来相同的设备节点
镇水铁牛 发表于 2014-08-25 23:11 static/image/common/back.gif
回复 5# Tinnal
现在貌似udev是netlink上报的了,不是hotplug_helper了;
是的,udev采用的是netlink的方式,由udevd进行监控。
当前busybox的mdev还是采用户hotplug_herper的方式。
因此我后面的贴只提uevent,没有提hotplug_herper。
页:
[1]