Linux中的进程间通信机制源自于Unix平台上的进程通信机制。Unix的两大分支AT&T Unix和BSD Unix在进程通信实现机制上的各有所不同,前者形成了运行在单个计算机上的System V IPC,后者则实现了基于socket的进程间通信机制。同时Linux也遵循IEEE制定的Posix IPC标准,在三者的基础之上实现了以下几种主要的IPC机制:管道(Pipe)及命名管道(Named Pipe),信号(Signal),消息队列(Message queue),共享内存(Shared Memory),信号量(Semaphore),套接字(Socket)。通过这些IPC机制,用户空间进程之间可以完成互相通信。为了完成内核空间与用户空间通信,Linux提供了基于socket的Netlink通信机制,可以实现内核与用户空间数据的及时交换。 本文第2节概述相关研究工作,第3节与其他IPC机制对比,详细介绍Netlink机制及其关键技术,第4节使用KGDB+GDB组合调试,通过一个示例程序演示Netlink通信过程。第5节做总结并指出Netlink通信机制的不足之处。 2 相关研究 到目前Linux提供了9种机制完成内核与用户空间的数据交换,分别是内核启动参数、模块参数与 sysfs、sysctl、系统调用、netlink、procfs、seq_file、debugfs和relayfs,其中模块参数与sysfs、procfs、debugfs、relayfs是基于文件系统的通信机制,用于内核空间向用户控件输出信息;sysctl、系统调用是由用户空间发起的通信机制。由此可见,以上均为单工通信机制,在内核空间与用户空间的双向互动数据交换上略显不足。Netlink是基于socket的通信机制,由于socket本身的双共性、突发性、不阻塞特点,因此能够很好的满足内核与用户空间小量数据的及时交互,因此在Linux 2.6内核中广泛使用,例如SELinux,Linux系统的防火墙分为内核态的netfilter和用户态的iptables,netfilter与iptables的数据交换就是通过Netlink机制完成。 3 Netlink机制及其关键技术 3.1 Netlink机制
在调试驱动,或驱动涉及一些参数的输入输出时,难免需要对驱动里的某些变量或内核参数进行读写,或函数调用。此时sysfs接口就很有用了,它可以使得可以在用户空间直接对驱动的这些变量读写或调用驱动的某些函数。sysfs接口与proc文件系统很相似,有人将proc文件系统形容为Windows XP,而将sysfs接口形容为Windows 7。 而在Android系统中,振动器、背光、电源系统等往往使用sysfs接口作为内核空间和用户空间的接口,驱动程序需要提供这些接口内容。
proc文件系统是一种无存储的文件系统,当读其中的文件时,其内容动态生成,当写文件时,文件所关联的写函数被调用。每个proc文件都关联的字节特定的读写函数,因而它提供了另外的一种和内核通信的机制:内核部件可以通过该文件系统向用户空间提供接口来提供查询信息、修改软件行为,因而它是一种比较重要的特殊文件系统。 由于proc文件系统以文件的形式向用户空间提供了访问接口,这些接口可以用于在运行时获取相关部件的信息或者修改部件的行为,因而它是非常方便的一个接口。内核中大量使用了该文件系统。proc文件系统就是一个文件系统,它可以挂载在目录树的任意位置,不过通常挂载在/proc下,它大致包含了如下信息: 内存管理 每个进程的相关信息 文件系统 设备驱动程序 系统总线 电源管理 终端 系统控制参数 网络 使用proc文件系统之前必须将其初始化并且挂载到系统中。proc文件系统的的初始化主要完成: 调用proc_init_inodecache创建proc文件系统所使用的专用缓冲区 调用register_filesystem注册proc文件系统,这里会提供proc文件系统自己的file_system_type,其中包括了用于mount的函数指针。在执行mount的时候会用到这些信息,并最终找到mount函数进行挂载操作 调用proc_mkdir创建一些proc文件目录 在sys文件系统下注册proc文件系统的相关信息 在proc的mount函数中会调用proc_fill_super,它会给出proc文件系统超级块所需要的信息(比如文件系统的超级块操作函数指针,超级块大小等),并且会创建proc文件系统的根目录,在创建根目录时也会指定与之对应的inode_operations和file_operations,有了这些信息后,VFS就可以在该文件系统上进行各种操作了(创建、删除、查找文件)。
Netfilter是Linux 2.4.x引入的一个子系统,它作为一个通用的、抽象的框架,提供一整套的hook函数的管理机制,使得诸如数据包过滤、网络地址转换(NAT)和基于协议类型的连接跟踪成为了可能。 netfilter的架构就是在整个网络流程的若干位置放置了一些检测点HOOK),而在每个检测点上登记了一些处理函数进行处理。