免费注册 查看新帖 |

Chinaunix

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

热插拔 [复制链接]

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-15 13:36 |只看该作者 |倒序浏览
30可用积分
本帖最后由 embeddedlwp 于 2011-11-15 13:39 编辑

谁能说一下当一个设备插入系统后的过程,产生热插拔,udev,NETLINK,中断? 思路很乱,谁能完整说一下流程啊?从插入设备到在/dev下创建设备结点!

比如都说热插拔是在插入设备时产生的,那么这个热插拔是在创建kobject时产生的还是...希望能说一下流程!

论坛徽章:
5
摩羯座
日期:2014-07-22 09:03:552015元宵节徽章
日期:2015-03-06 15:50:392015亚冠之大阪钢巴
日期:2015-06-12 16:01:352015年中国系统架构师大会
日期:2015-06-29 16:11:2815-16赛季CBA联赛之四川
日期:2018-12-17 14:10:21
2 [报告]
发表于 2011-11-15 14:01 |只看该作者
USB插入,中断,处理,uevent上报事件 kernel部分完毕(驱动版块有参考)

发现有uevent事件,多了个device设备,创建设备节点,使用者user部分完毕,继续等待其他uevent事件这(该程序在嵌入式版块有参考)

论坛徽章:
0
3 [报告]
发表于 2011-11-17 18:32 |只看该作者
本帖最后由 wangjianchangdx 于 2011-11-17 18:34 编辑

没有从源码上仔细看,仅凭“臆测”,来说一下个人的理解;
首先要分清角色,这里有:
① 可插拔外设;
② 总线,如usb;
③ sysfs;
④ netlink;
⑤ udev;
⑥ devfs(对应/dev目录);
分下类,
① 外设驱动、总线驱动、sysfs在内核空间;
② udev运行在用户空间,根据/sys目录的变化来在/dev目录下动态创建设备文件;
③ netlink是用户空间和内核空间通信的方式,其他通信方式还有system call, ioctl, proc filesystem;

至于流程,大致如下:
① 外设插入;
② 总线发现(中断?)新设备,并调用总线驱动查找驱动程序;[“Find a driver that can handle the device” =》 “Bind a driver to that device” =》 “Tell other subsystems to configure the new device.”(参见document/usb/hotplug.txt)]
③ 找到合适的驱动后,会调用device_add,添加新设备到设备管理系统;
④ device_add中会调用kobject_uevent(, KOBJ_ADD),向userspace广播新设备加入event通知;这里发出通知的方式,就是netlink;
⑤ 用户空间运行的daemon(udevd ?或者khubd等转发给udevd?)收到event事件广播;
⑥ udevd根据消息和环境变量,查询/sys的变化,在/dev目录下自动创建设备节点;


>比如都说热插拔是在插入设备时产生的,那么这个热插拔是在创建kobject时产生的还是...
热插拔事件有很多种:
  1. enum kobject_action {
  2.         KOBJ_ADD,
  3.         KOBJ_REMOVE,
  4.         KOBJ_CHANGE,
  5.         KOBJ_MOVE,
  6.         KOBJ_ONLINE,
  7.         KOBJ_OFFLINE,
  8.         KOBJ_MAX
  9. };
复制代码

论坛徽章:
0
4 [报告]
发表于 2011-11-17 20:24 |只看该作者
回复 3# wangjianchangdx

>⑤ 用户空间运行的daemon(udevd ?或者khubd等转发给udevd?)收到event事件广播;
根据udev(7) manpage:
The udev daemon udevd( receives device uevents directly from the kernel whenever a device is added or removed
       from the system, or it changes its state.


又khubd属于内核线程,运行在内核空间:
  1. wjcdx@lj:/etc/udev/rules.d$ ps aux | grep khubd
  2. root        29  0.0  0.0      0     0 ?        S    Nov16   0:00 [khubd]
  3. wjcdx     3779  0.0  0.3   4016   768 pts/6    S+   20:05   0:00 grep --color=auto khubd
  4. wjcdx@lj:/etc/udev/rules.d$
  5. wjcdx@lj:/etc/udev/rules.d$
  6. wjcdx@lj:/etc/udev/rules.d$
  7. wjcdx@lj:/etc/udev/rules.d$ ps aux | grep udev
  8. root       263  0.0  0.0   2396   172 ?        S    Nov16   0:00 upstart-udev-bridge --daemon
  9. root       268  0.0  0.0   2628   144 ?        S<s  Nov16   0:00 udevd --daemon
  10. root       390  0.0  0.0   2624   148 ?        S<   Nov16   0:00 udevd --daemon
  11. root       407  0.0  0.0   2624   152 ?        S<   Nov16   0:00 udevd --daemon
  12. wjcdx     3781  0.0  0.3   4012   768 pts/6    S+   20:05   0:00 grep --color=auto udev
复制代码
可以看出khubd的进程好是0,而udevd的进程号则不是0;

根据Linux下usb热插拔处理中说:
在系统初始化的时候在usb_init函数中调用usb_hub_init函数,就进入了hub的初始化。

  在usb_hub_init函数中完成了注册hub驱动,并且利用函数kthread_run创建一个内核线程。该线程用来管理监视hub的状态,所有的情况都通过该线程来报告。

可以猜测,khubd内核线程负责向udevd报告usb hub的所有状态改变;

证诸内核代码:
  1. int usb_hub_init(void)
  2. {
  3. ***
  4.         khubd_task = kthread_run(hub_thread, NULL, "khubd");
  5. ***       
  6. }
复制代码
hub_thread()->hub_events()->hub_port_connect_change()->usb_new_device()->device_add()->kobject_uevent();

论坛徽章:
0
5 [报告]
发表于 2011-11-17 22:47 |只看该作者
Usually, when you run ps -aux and look at the khubd process,
you see that it is sleeping, denoted by the letter S. When we plug a USB device
into the USB port, the hardware layer initiates an interrupt; we reach the hub_irq() method.
The hub data, represented by struct usb_hub, is passed to the hub_irq() method
as part of the URB, the context member of struct urb.

A global list of hub events, called hub_event_list, is available. If
this list is empty, we add an event to this list, so that the khubd thread
can handle it. We also call wake_up(&khubd_wait), as khubd is in waiting status.
Waking up causes us to call hub_events().

FromAn Overview of Linux USB

还剩下一个问题,就是如果设备的驱动是在设备插入时动态加载的,那这个加载过程,处在这一个过程的哪一个位置?

论坛徽章:
0
6 [报告]
发表于 2011-11-18 01:02 |只看该作者
本帖最后由 wangjianchangdx 于 2011-11-18 01:06 编辑

回复 5# wangjianchangdx

device_add():
  1. kobject_uevent(&dev->kobj, KOBJ_ADD);
  2.         bus_probe_device(dev);
复制代码
可以看出是先发出event事件,后为device probe driver;
细细想来,udev的功能与驱动没必然关系:udev可以probe driver,也可以不加载,看udev规则高兴;调用udev之前可以有driver,反之亦可;

udev的功能,引自udev(7) manpage:
      udev provides a dynamic device directory containing only the files for actually present devices. It creates or removes device node files in the /dev directory, or it renames network interfaces.

       Usually udev runs as udevd(8) and receives uevents directly from the kernel if a device is added or removed from the system.

       If udev receives a device event, it matches its configured rules against the available device attributes provided in sysfs to identify the device. Rules that match may provide additional device information or specify a device node name and multiple symlink names and instruct udev to run additional programs as part of the device event handling.

没有明显的说明是否probe driver,但它的主要功能如上面粗体部分,而不是probe driver;
没有找到驱动的设备,就不能创建设备文件了吗?答案当然是可以。

所以,上面所说的过程可以去除driver部分,简化如下:
① 外设插入;
② 总线发现(中断? usb有中断hub_irq,pci的中断没找到)新设备,调用device_add,添加新设备到设备管理系统;
③ device_add中调用kobject_uevent(, KOBJ_ADD),向userspace广播新设备加入event通知;这里发出通知的方式,就是netlink;
④ 用户空间运行的daemon(udevd)收到event事件广播;
⑤ udevd根据消息和环境变量,查询/sys的变化,按照规则(/etc/udev/rules.d/*),在/dev目录下自动创建设备节点;

以上,多所臆测,还望知者指教!

论坛徽章:
0
7 [报告]
发表于 2011-11-18 01:16 |只看该作者
同时可以总结,设备插入系统时,相应驱动的关联情况:
① 若直接编译进内核或在启动时加载,则无需在udev中加载驱动模块,在bus_probe_device()中会为其找到相应的驱动;
② 若驱动需要动态加载,则需要在udev(目前的情况是这样,以前也有其他方式如/sbin/hotplug,cardmgr等)中,动态加载其驱动,在驱动的register函数中,找到该device进行关联;

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
8 [报告]
发表于 2011-11-18 08:39 |只看该作者
现在的devtmpfs又变回去了,device_add的时只要有major number就会为其生成一个结点。不知道跟udev是怎么配合的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP