--
谁能说一下当一个设备插入系统后的过程,产生热插拔,udev,NETLINK,中断? 思路很乱,谁能完整说一下流程啊?从插入设备到在/dev下创建设备结点!
比如都说热插拔是在插入设备时产生的,那么这个热插拔是在创建kobject时产生的还是...希望能说一下流程!
比如都说热插拔是在插入设备时产生的,那么这个热插拔是在创建kobject时产生的还是...希望能说一下流程!
--
USB插入,中断,处理,uevent上报事件 kernel部分完毕(驱动版块有参考)
发现有uevent事件,多了个device设备,创建设备节点,使用者user部分完毕,继续等待其他uevent事件这(该程序在嵌入式版块有参考)
发现有uevent事件,多了个device设备,创建设备节点,使用者user部分完毕,继续等待其他uevent事件这(该程序在嵌入式版块有参考)
--
没有从源码上仔细看,仅凭“臆测”,来说一下个人的理解;
首先要分清角色,这里有:
① 可插拔外设;
② 总线,如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时产生的还是...
热插拔事件有很多种:
首先要分清角色,这里有:
① 可插拔外设;
② 总线,如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时产生的还是...
热插拔事件有很多种:
- enum kobject_action {
- KOBJ_ADD,
- KOBJ_REMOVE,
- KOBJ_CHANGE,
- KOBJ_MOVE,
- KOBJ_ONLINE,
- KOBJ_OFFLINE,
- KOBJ_MAX
- };
--
>⑤ 用户空间运行的daemon(udevd ?或者khubd等转发给udevd?)收到event事件广播;
根据udev(7) manpage:
又khubd属于内核线程,运行在内核空间:可以看出khubd的进程好是0,而udevd的进程号则不是0;
根据中说:
可以猜测,khubd内核线程负责向udevd报告usb hub的所有状态改变;
证诸内核代码:hub_thread()->hub_events()->hub_port_connect_change()->usb_new_device()->device_add()->kobject_uevent();
根据udev(7) manpage:
又khubd属于内核线程,运行在内核空间:可以看出khubd的进程好是0,而udevd的进程号则不是0;
根据中说:
可以猜测,khubd内核线程负责向udevd报告usb hub的所有状态改变;
证诸内核代码:hub_thread()->hub_events()->hub_port_connect_change()->usb_new_device()->device_add()->kobject_uevent();
--
From
还剩下一个问题,就是如果设备的驱动是在设备插入时动态加载的,那这个加载过程,处在这一个过程的哪一个位置?
--
回复 wangjianchangdx
device_add():可以看出是先发出event事件,后为device probe driver;
细细想来,udev的功能与驱动没必然关系:udev可以probe driver,也可以不加载,看udev规则高兴;调用udev之前可以有driver,反之亦可;
udev的功能,引自udev(7) manpage:
没有明显的说明是否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目录下自动创建设备节点;
以上,多所臆测,还望知者指教!
device_add():可以看出是先发出event事件,后为device probe driver;
细细想来,udev的功能与驱动没必然关系:udev可以probe driver,也可以不加载,看udev规则高兴;调用udev之前可以有driver,反之亦可;
udev的功能,引自udev(7) manpage:
没有明显的说明是否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目录下自动创建设备节点;
以上,多所臆测,还望知者指教!
--
同时可以总结,设备插入系统时,相应驱动的关联情况:
① 若直接编译进内核或在启动时加载,则无需在udev中加载驱动模块,在bus_probe_device()中会为其找到相应的驱动;
② 若驱动需要动态加载,则需要在udev(目前的情况是这样,以前也有其他方式如/sbin/hotplug,cardmgr等)中,动态加载其驱动,在驱动的register函数中,找到该device进行关联;
① 若直接编译进内核或在启动时加载,则无需在udev中加载驱动模块,在bus_probe_device()中会为其找到相应的驱动;
② 若驱动需要动态加载,则需要在udev(目前的情况是这样,以前也有其他方式如/sbin/hotplug,cardmgr等)中,动态加载其驱动,在驱动的register函数中,找到该device进行关联;
--
现在的devtmpfs又变回去了,device_add的时只要有major number就会为其生成一个结点。不知道跟udev是怎么配合的。