对于进程来说,它既有内核空间(与其他进程共享),也有用户空间(进程私有私有)。不

管是内核空间还是用户空间,它们都处于虚拟地址空间。

        内核空间和用户空间交换数据的方式有很多。用户空间发起的有系统调用、proc、虚拟文

件系统等。内核空间主动发起的有get_user/put_user、信号、netlink等。

        Linux应用程序与内核程序交互主要有以下几种通信方式:

(1)系统调用

         Linux系统下,设备即文件,也因此大部分设备驱动程序都实现了标准的系统接口,如:

        ● open(),read(),write(), ioctl(), mmap()

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

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

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

(2)虚拟文件系统 

        ● proc文件系统 

        ● sysfs文件系统 

        ● debugfs文件系统

        很多内核程序细节,如中断等,都在proc/目录下有所体现,虚拟文件系统提供了一种便捷的

用户空间和内核空间的交互方式;

(3)netlink

(4)内存映像

        mmap共享内存。Linux通过mmap的把内核中特定部分的内存空间映射到用户级程序的内存

空间去,从而提供了用户程序对内存直接访问的能力。该方式尤其适合在那些内核和用户空间需要

快速大量交互数据的情况下

(5)内核程序使用信号通知应用程序

        信号在内核里的用途主要集中在通知用户程序出现重大错误,强行杀死当前进程,这时内核

通过发送SIGKILL信号通知进程终止。

        信号发送必须要事先知道进程序号(pid),所以要想从内核中通过发信号的方式异步通

知用户进程执行某项任务,那么必须事先知道用户进程的进程号才可以(可以让应用程序通过oictl

函数,把自己的PID主动告诉驱动程序)。而一般内核运行时搜索特定进程的进程号是个费事的工

作,可能要遍历整个进程控制块链表。所以用信号通知特定用户进程的方法很糟糕,一般在内核不

会使用。内核中使用信号的情形只出现在通知当前进程(可以从current变量中方便获得pid)做某

些通用操作,如终止操作等。因此对内核开发者该方法用处不大。类似情况还有消息操作。

(6)从内核空间回调用户程序。

(7)自定义系统调用

(8)文件

Logo

华为云1024程序员节送福利,参与活动赢单人4000元礼包,更有热门技术干货免费学习

更多推荐