1.Netlink通信机制
- Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口。
Netlink 是一种特殊的 socket,它是 Linux 所特有的,类似于 BSD 中的AF_ROUTE 但又远比它的功能强大,目前在Linux 内核中使用netlink 进行应用与内核通信的应用很多; - 包括:
路由 daemon(NETLINK_ROUTE), 用户态 socket 协议(NETLINK_USERSOCK), 防火墙(NETLINK_FIREWALL), netfilter 子系统(NETLINK_NETFILTER), 内核事件向用户态通知(NETLINK_KOBJECT_UEVENT), 通用 netlink(NETLINK_GENERIC)等。 - Netlink 是一种在内核与用户应用间进行双向数据传输的非常好的方式,用户态应用使用标准的 socket API 就可以使用 netlink 提供的强大功能,
内核态需要使用专门的内核 API 来使用 netlink。
2. Linux设备文件系统
-
设备文件系统就是给我们解决这一问题的关键,他能够在系统设备初始化时动态的在/dev目录下创建好各种设备的设备文件节点(也就是说,系统启动后/dev目录下就有了各种设备的设备文件,直接就可使用了)。除此之外,他还可以在设备卸载后自动的删除/dev下对应的设备文件节点(这对于一些热插拔设备很有用,插上的时候自动创建,拔掉的时候又自动删除)。还有一个好处就是,在我们编写设备驱动的时候,不必再去为设备指定主设备号,在设备注册时用0来动态的获取可用的主设备号,然后在驱动中来实现创建和销毁设备文件(一般在驱动模块加载和卸载函数中来实现)。 -
devfs文件系统 devfs的出现使得设备驱动程序能够自主的管理自己的设备文件。比如,可以通过程序在设备初始化的时候在 /dev 目录下创建设备文件,卸载时将他删除 -
udev文件系统 udev 运行在用户模式,而非内核中。 udev 的初始化脚本在系统启动时创建设备节点,并且当插入新设备——加入驱动模块——在sysfs上注册新的数据后,udev会创新新的设备节点。 udev 是一个工作在用户空间的工具,它能根据系统中硬件设备的状态动态的更新设备文件,包括设备文件的创建,删除,权限等。 这些文件通常都定义在/dev 目录下,但也可以在配置文件中指定。 udev 必须得到内核中的sysfs和tmpfs支持,sysfs 为udev 提供设备入口和uevent 通道,tmpfs 为udev 设备文件提供存放空间。 udev是一个通用的内核设备管理器。它以守护进程的方式运行于Linux系统,并监听在新设备初始化或设备从系统中移除时,内核(通过netlink socket)所发出的uevent
3. sysfs 文件系统
- sysfs是一个基于内存的文件系统,它的作用是将内核信息以文件的方式提供给用户程序使用。
- sysfs可以看成与proc,devfs和devpty同类别的文件系统,该文件系统是虚拟的文件系统,可以更方便对系统设备进行管理。它可以产生一个包含所有系统硬件层次视图,与提供进程和状态信息的proc文件系统十分类似。
- sysfs把连接在系统上的设备和总线组织成为一个分级的文件,它们可以由用户空间存取,向用户空间导出内核的数据结构以及它们的属性。sysfs的一个目的就是展示设备驱动模型中各组件的层次关系,其顶级目录包括block,bus,drivers,class,power和firmware等。
- sysfs提供一种机制,使得可以显式的描述内核对象、对象属性及对象间关系。sysfs有两组接口,一组针对内核,用于将设备映射到文件系统中,另一组针对用户程序,用于读取或操作这些设备。
- 如下表含义是:内核中的sysfs要素及其在用户空间的表现:
| |
---|
sysfs在内核中的组成要素 | 在用户空间的显示 | 内核对象(kobject) | 目录 | 对象属性(attribute) | 文件 | 对象关系(relationship) | 链接(Symbolic Link) | | |
- sysfs目录结构
4.Uevent
-
Uevent是Kobject的一部分,用于在Kobject状态发生改变时,例如增加、移除等,通知用户空间程序。用户空间程序收到这样的事件后,会做相应的处理。 -
该机制通常是用来支持热拔插设备的 -
由此可知,设备模型中任何设备有事件需要上报时,会触发 uevent提供的接口,uevent模块准备好上报事件的格式后,可以通过两个途径上报到用户空间: 通过 kmod 模块,直接调动用户空间的可执行文件 通过 netlink 通信机制,将事件从内核空间传递给用户空间 -
PS: 目前多采用 netlink 通信机制,ueventd 也是采用 netlink机制创建 socket 与 kernel 进行通信。 用户空间程序接收到上报的uevent之后就可以根据其event类型进行相应操作了。 -
Uevent的内部逻辑解析 据结构描述,kobject.h定义了uevent相关的常量和数据结构:kobject_action
1:
2: enum kobject_action {
3: KOBJ_ADD,
4: KOBJ_REMOVE,
5: KOBJ_CHANGE,
6: KOBJ_MOVE,
7: KOBJ_ONLINE,
8: KOBJ_OFFLINE,
9: KOBJ_MAX
10: };
- kobject_action定义了event的类型,包括:
ADD/REMOVE,Kobject(或上层数据结构)的添加/移除事件。
ONLINE/OFFLINE,Kobject(或上层数据结构)的上线/下线事件,其实是是否使能。
CHANGE,Kobject(或上层数据结构)的状态或者内容发生改变。
MOVE,Kobject(或上层数据结构)更改名称或者更改Parent(意味着在sysfs中更改了目录结构)。
CHANGE,如果设备驱动需要上报的事件不再上面事件的范围内,或者是自定义的事件,可以使用该event,并携带相应的参数。
- udevadm monitor命令即可观察uevent事件,链接
udevadm monitor --property
|