下面总结了7种方式,主要对之前不是很熟悉的方式作了编程实现,以便加深印象。html
1.使用API:这是最常使用的一种方式了linux
A.get_user(x,ptr):在内核中被调用,获取用户空间指定地址的数值并保存到内核变量x中。编程
B.put_user(x,ptr):在内核中被调用,将内核空间的变量x的数值保存到到用户空间指定地址处。缓存
C.Copy_from_user()/copy_to_user():主要应用于设备驱动读写函数中,经过系统调用触发。异步
2.使用proc文件系统:和sysfs文件系统相似,也能够做为内核空间和用户空间交互的手段。socket
/proc 文件系统是一种虚拟文件系统,经过他能够做为一种linux内核空间和用户空间的。与普通文件不一样,这里的虚拟文件的内容都是动态建立的。函数
使用/proc文件系统的方式很简单。调用create_proc_entry,返回一个proc_dir_entry指针,而后去填充这个指针指向的结构就行了,我下面的这个测试用例只是填充了其中的read_proc属性。测试
下面是一个简单的测试用例,经过读虚拟出的文件能够获得内核空间传递过来的“proc ! test by qiankun!”字符串。spa
3.使用sysfs文件系统+kobject:其实这个之前是编程实现过得,可是那天太紧张忘记了,T_T。每一个在内核中注册的kobject都对应着sysfs系统中的一个目录。能够经过读取根目录下的sys目录中的文件来得到相应的信息。除了sysfs文件系统和proc文件系统以外,一些其余的虚拟文件系统也能一样达到这个效果。指针
4.netlink:netlink socket提供了一组相似于BSD风格的API,用于用户态和内核态的IPC。相比于其余的用户态和内核态IPC机制,netlink有几个好处:1.使用自定义一种协议完成数据交换,不须要添加一个文件等。2.能够支持多点传送。3.支持内核先发起会话。4.异步通讯,支持缓存机制。
对于用户空间,使用netlink比较简单,由于和使用socket很是的相似,下面说一下内核空间对netlink的使用,主要说一下最重要的create函数,函数原型以下:
extern struct sock *netlink_kernel_create(struct net *net,
int unit,unsigned int groups,
void (*input)(struct sk_buff *skb),
struct mutex *cb_mutex,
struct module *module);
第一个参数通常传入&init_net。
第二个参数指的是netlink的类型,系统定义了16个,咱们若是使用的话最好本身定义。这个需和用户空间所使用的建立socket的第三个参数一致,才能够完成通讯。
第四个参数指的是一个回调函数,当接受到一个消息的时候会调用这个函数。回调函数的参数为struct sk_buff类型的结构体。经过分析其结构成员能够获得传递过来的数据
第六个参数通常传入的是THIS_MODULE。指当前模块。
下面是对netlink的一个简单测试,将字符串“netlink test by qiankun”经过netlink输出到内核,内核再把字符串返回。Netlink类型使用的是22.
5.文件:应该说这是一种比较笨拙的作法,不过确实能够这样用。当处于内核空间的时候,直接操做文件,将想要传递的信息写入文件,而后用户空间能够读取这个文件即可以获得想要的数据了。下面是一个简单的测试程序,在内核态中,程序会向“/home/melody/str_from_kernel”文件中写入一条字符串,而后咱们在用户态读取这个文件,就能够获得内核态传输过来的数据了。
6.使用mmap系统调用:能够将内核空间的地址映射到用户空间。在之前作嵌入式的时候用到几回。一方面能够在driver中修改Struct file_operations结构中的mmap函数指针来从新实现一个文件对应的映射操做。另外一方面,也能够直接打开/dev/mem文件,把物理内存中的某一页映射到进程空间中的地址上。
其实,除了重写Struct file_operations中mmap函数,咱们还能够重写其余的方法如ioctl等,来达到驱动内核空间和用户空间通讯的方式。
7.信号:从内核空间向进程发送信号。这个却是常常遇到,用户程序出现重大错误,内核发送信号杀死相应进程。
转自:http://www.cnblogs.com/dchipnau/p/5043591.html