免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7922 | 回复: 9
打印 上一主题 下一主题

[内核入门] device_create和device_add和udev [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-25 09:38 |只看该作者 |倒序浏览
有看到之前的一个帖子是这么回复
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是怎么工作的,如何自动添加设备结点。

论坛徽章:
0
2 [报告]
发表于 2014-08-25 09:43 |只看该作者
除了函数device_create还有其他的函数可以让udev也可以自动添加设备结点么。
我用source insight查看了下,整个源码调用它的好像并不是很多。

新手小白。多多指教。。各位大婶们。

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
3 [报告]
发表于 2014-08-25 10:52 |只看该作者
在dev下创建节点的是mknod等,由udev干的。好像是内核发了一个notify还是什么记不清楚了

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
4 [报告]
发表于 2014-08-25 13:21 |只看该作者
调用device_create和直接调用device_add的区别,就只是在参数devt上,如果devt为0(即直接调用device_add),那么devtmpfs就不会创建节点
udev也同理,如果uevent中没有devt,那么udev也不会创建这个节点


论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
5 [报告]
发表于 2014-08-25 15:08 |只看该作者
回复 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= ... 6uL6GDxuKlOn41H7u77
   

论坛徽章:
0
6 [报告]
发表于 2014-08-25 15:42 |只看该作者
回复 4# arm-linux-gcc
那这样说的话,在/sys下产生了一个dev属性文件,那么这个设备就会被创建在/dev/目录下咯。
暂且可以理解为,在系统启动之后udev根据dev属性文件来创建设备结点(不考虑热插拔机制)

   

论坛徽章:
0
7 [报告]
发表于 2014-08-25 15:57 |只看该作者
回复 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/目录下创建设备结点。

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
8 [报告]
发表于 2014-08-25 16:18 |只看该作者
darling54454 发表于 2014-08-25 15:42
回复 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文件的必要非充分条件。

论坛徽章:
2
寅虎
日期:2014-11-25 21:47:342015小元宵徽章
日期:2015-03-06 15:58:18
9 [报告]
发表于 2014-08-25 23:11 |只看该作者
回复 5# Tinnal

现在貌似udev是netlink上报的了,不是hotplug_helper了;
可以手动删除设备节点后,udev通过手动触发(也是通过sysfs的uevent)生成和原来相同的设备节点
   

论坛徽章:
9
辰龙
日期:2014-08-18 20:38:42未羊
日期:2014-09-04 08:50:45丑牛
日期:2014-09-06 00:12:55寅虎
日期:2014-12-22 20:50:56摩羯座
日期:2015-01-14 22:28:15巳蛇
日期:2015-01-23 20:39:272015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之青岛
日期:2016-03-13 23:37:1915-16赛季CBA联赛之深圳
日期:2016-03-29 18:52:38
10 [报告]
发表于 2014-08-25 23:45 |只看该作者
镇水铁牛 发表于 2014-08-25 23:11
回复 5# Tinnal

现在貌似udev是netlink上报的了,不是hotplug_helper了;


是的,udev采用的是netlink的方式,由udevd进行监控。
当前busybox的mdev还是采用户hotplug_herper的方式。
因此我后面的贴只提uevent,没有提hotplug_herper。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP