日期:2014-05-16 浏览次数:20668 次
内核和用户空间之间存在如下交互手段:
1.内核启动参数 2.模块参数与 3.sysfs、4.sysctl、5.系统调用、6.netlink、7.procfs、8.seq_file、9.debugfs 10.relayfs
另外 call_usermodehelper 可以从内核发起用户态的应用程序运行
其中netlink作为一种进程之间的通讯手段 ,和其他内核与用户空间的通讯手段比较,有很大的优势:
1. 新增通讯通道的灵活性:
netlink提供了一套完善的机制,用户既可以静态的增加通讯通道,也可以动态的创建通讯通道,这样用户可以很灵活的根据自己的需要来定制和开发。
2. 丰富的特性支持:
netlink可以支持异步双工, 其他机制只支持用户到内核单向的通道,或者只支持内核到用户的单向通道,netlink支持对称的双向通道。
同时neilink支持单点传输和多点传输,这些优势都是其他通讯机制所不具备的。
3. 传输效率比较高:
和其他用户向内核通讯手段一样,netlink也是借助某些系统调用接口实现的,并且netlink的目标数据接收操作是直接在软中断里面执行的,比有些在内核开辟线程接收数据的方式要快。
4. 易于扩展:
内核已为netlink提供的动态机制扩展,新增一个应用通道非常方便,只需要修改少量代码。
netlink充分体现了linux开发的宗旨:“提供机制而不是策略”,“do one thing and do it well”, 从内核版本的演进历程看来,同一类型的机制,linux提供的功能越来越强大,给用户的选择空间也是越来越丰富。
从学习的角度出发,这里使用静态方式新增了一个netlink通道,并实现了一个用户态和内核态通讯的双向通讯的样例,设计如下:
user kernel
| |
send -> "hello from usr"-> receive and print
| |
receive and print < -"hello from usr " <-send
| |
exit
如上图所述,由用户首先发起一个问候消息给内核,内核收到这个消息以后返回一个问候消息给用户, 以下通过代码来分析netlink的实现:
一、内核部分代码:
1. 头文件和静态申明
这里包含了必要的头文件, 新增了一个 netlink协议号,这个协议号和内核自定义的NETLINK_GENERIC是同一类型,应该定义在<linux/netlink.h>中,为了方便显示放到了这里。
新增内核源码文件 eknetlink.c :
/*kernel example code of netlink*/ #include <linux/netlink.h> #include <linux/module.h> #include <linux/skbuff.h> #include <linux/init.h> #include <linux/netdevice.h> #include <linux/netfilter.h> #include <linux/spinlock.h> #include <linux/netlink.h> #include <net/sock.h> #include <net/flow.h> #define NETLINK_EXAMPLE 31 /*新增netlink协议号*/ /*本netlink过滤类型*/ enum nf_eknetlink_hooks { NF_EKNETLINK_IN, NF_EKNETLINK_OUT