内核空间与用户空间的通信方式

摘要:
总结了内核空间和用户空间之间的以下七种通信方式。它们主要以以前不熟悉的方式进行编程和实施,以加深印象。这必须与用于在用户空间中创建套接字的第三个参数一致,然后才能完成通信。事实上,除了重写Structfile _对于操作中的mmap函数,我们还可以重写其他方法,例如ioctl,以驱动内核空间和用户空间之间的通信。

内核空间与用户空间的通信方式

  下面总结了7种方式,主要对以前不是很熟悉的方式做了编程实现,以便加深印象

 

1.使用API这是最常使用的一种方式了

A.get_user(xptr):在内核中被调用,获取用户空间指定地址的数值并保存到内核变量x中。

B.put_user(xptr):在内核中被调用,将内核空间的变量x的数值保存到到用户空间指定地址处。

C.Copy_from_user()/copy_to_user():主要应用于设备驱动读写函数中,通过系统调用触发。

 

2.使用proc文件系统:sysfs文件系统类似,也可以作为内核空间和用户空间交互的手段。

/proc 文件系统是一种虚拟文件系统,通过他可以作为一种linux内核空间和用户空间的。与普通文件不同,这里的虚拟文件的内容都是动态创建的。

使用/proc文件系统的方式很简单。调用create_proc_entry,返回一个proc_dir_entry指针,然后去填充这个指针指向的结构就好了,我下面的这个测试用例只是填充了其中的read_proc属性。

   下面是一个简单的测试用例,通过读虚拟出的文件可以得到内核空间传递过来的“proc ! test by qiankun!”字符串。

内核空间与用户空间的通信方式第1张

 

 

3.使用sysfs文件系统+kobject其实这个以前是编程实现过得,但是那天太紧张忘记了,T_T。每个在内核中注册的kobject都对应着sysfs系统中的一个目录。可以通过读取根目录下的sys目录中的文件来获得相应的信息。除了sysfs文件系统和proc文件系统之外,一些其他的虚拟文件系统也能同样达到这个效果。

 

4.netlinknetlink 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.

内核空间与用户空间的通信方式第2张

 

 

5.文件:应该说这是一种比较笨拙的做法,不过确实可以这样用。当处于内核空间的时候,直接操作文件,将想要传递的信息写入文件,然后用户空间可以读取这个文件便可以得到想要的数据了。下面是一个简单的测试程序,在内核态中,程序会向“/home/melody/str_from_kernel”文件中写入一条字符串,然后我们在用户态读取这个文件,就可以得到内核态传输过来的数据了。

内核空间与用户空间的通信方式第3张

 

 

6.使用mmap系统调用:可以将内核空间的地址映射到用户空间。在以前做嵌入式的时候用到几次。一方面可以在driver中修改Struct file_operations结构中的mmap函数指针来重新实现一个文件对应的映射操作。另一方面,也可以直接打开/dev/mem文件,把物理内存中的某一页映射到进程空间中的地址上。

其实,除了重写Struct file_operationsmmap函数,我们还可以重写其他的方法如ioctl等,来达到驱动内核空间和用户空间通信的方式。

 

7.信号:从内核空间向进程发送信号。这个倒是经常遇到,用户程序出现重大错误,内核发送信号杀死相应进程。

 


代码如下:

内核空间与用户空间的通信方式第4张





来自为知笔记(Wiz)


附件列表

    免责声明:文章转载自《内核空间与用户空间的通信方式》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

    上篇Innosetup 脚本写注册表实现自定义协议(Url Protocol)文件随机或顺序读写原理深入浅出下篇

    宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

    随便看看

    MySQL 字段类型占用空间

    MySQL支持多种列类型:数值类型、日期/时间类型和字符串(字符)类型。)1或2个字节,取决于枚举值的个数SET(‘value1’,’value2’,…)1、2、3、4或者8个字节,取决于set成员的数目上表的M只是为了说明占用空间大小,在实际创建表中char、varchar,20指的是字符而不是字节;那么字符和字节的转换要看字符集,utf-8下,1字符=3...

    Revit导入lumion渲染

    利用Revit导出DAE文件格式插件,可以将Revit模型导入到lumion中进行图片渲染和漫游动画的制作。lumion强大的漫游功能,丰富的附加组件,绚丽的视频特效。lumion没有建模功能,但是Revit建模的没有统一的标准,导致一些不该同样的材质的地方,无法更改;如果有统一的标准,那么Revit结合lumion能做出任何想要的效果。Revit13版本能...

    页面加载时自动执行(加载)js的几种方法

    Js调用onload方法window.onload=function(){func1();func2();func3();}二、JQ方法1.整个页面的document全部加载完成以后执行。不幸的这种方式不仅要求页面的DOMtree全部加载完成,而且要求所有的外部图片和资源全部加载完成。更不幸的是,如果外部资源,例如图片需要很长时间来加载,那么这个js方法执行...

    dBFs和dBm

    dBFs和dBmdBFs是用来表征数字域功率值的大小,一般情况下我们定义0dBFs为数字域满刻度功率值,即数字域中功率的最大值;因此看到的dBFs的值都是负的。...

    SQL Server 查看版本信息

    SQLServer查看版本信息3种方法:1)使用命令行查看[Win+R]键-˃打开cmd2)使用SSMS查看打开并连接SSMS后查看3)通过服务器属性查看使用SSMS打开并连接指定数据库后,查看服务器属性...

    CentOS7上使用history删除部分历史记录

    使用history命令删除登录后创建的历史记录,但保留原始记录。如果未执行history命令,则直接使用history-r命令将文件中的历史刷新到此处的缓存中,并且不会保存以前操作的记录。修改后,执行:history-c以清除当前会话历史中的历史缓存-r以读取~/。bash_您可以看到历史文件中的历史记录已在缓存中更新。...