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

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

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

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

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

B.put_user(x,ptr):在内核中被调用,将内核空间的变量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!”字符串。

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

代码如下:

来自为知笔记(Wiz)

附件列表

时间: 2024-12-18 10:27:26

内核空间与用户空间的通信方式的相关文章

内核空间和用户空间的分界 PAGE_OFFSET

PAGE_OFFSET 首先看看PAGE_OFFSET的功能 内存映射 |            用户空间                  |   内核空间   | |——————+——————+——————+———————| 物理 A:0        1G                         B:3G          C:4G B: 定义为    PAGE_OFFSET 0-1G: 和内核空间又有丰富的内容,我还没有整理,以后再说. ---------------------

Linux内核工程导论——用户空间设备管理

用户空间设备管理 用户空间所能见到的所有设备都放在/dev目录下(当然,只是一个目录,是可以变化的),文件系统所在的分区被当成一个单独的设备也放在该目录下.以前的2.4版本的曾经出现过devfs,这个思路非常好,在内核态实现对磁盘设备的动态管理.可以做到当用户访问一个设备的设备的时候,devfs驱动才会去加载该设备的驱动.甚至每个节点的设备号都是动态获得的.但是该机制的作者不再维护他的代码,linux成员经过讨论,使用用户态的udev代替内核态的devfs,所以现在的devfs已经废弃了.用户态

内核空间、用户空间和虚拟地址(转)

原文:http://www.cnblogs.com/yanhaidong/archive/2011/02/11/2339050.html IO是基于缓存区来做的,所谓的输入和输出就是从缓存区中移入和移出数据.以IO输入为例,首先是用户空间进程向内核请求某个磁盘空间数据,然后内核将磁盘数据读取到内核 空间的buffer中,然后用户空间的进程再将内核空间buffer中的数据读取到自身的buffer中,然后进程就可以访问使用这些数据. 内核空间是指操作系统内核运行的空间,是为了保证操作系统内核的能够安

内核空间与用户空间

首先,这个概念的由来,我认为跟CPU的发展有很大关系,在目前CPU的保护模式下,系统需要对其赖以运行的资料进行保护,为了保证操作系统内核资料,我们把内存空间进行划分,一部分为操作系统内核运行的空间,另一部分是应用程序运行的空间,所谓空间就是内存的地址.因此内核空间和用户空间的概念就出现了.在386以前的CPU实模式下,操作系统内核与用户程序的内存空间是不做区分的,也就不存在内核空间和用户空间的说法了.其次,CPU的保护模式的一个重大特点,也就是硬件直接支持的内存访问模式,虚拟地址空间到物理地址空

AndroidM 内核空间到用户空间接口类型

Android系统中, 驱动程序因商业需求分为运行在用户空间的hardware层以及运行在内核空间的驱动程序, 大多情况下内核驱动都需要提供用户空间访问的接口. Linux内核空间到用户空间的接口有主要有以下几种类型1.系统调用    系统调用是指系统实现的所有系统调用所构成的集合,即程序接口.    linux系统调用分为:进程控制,文件系统控制,系统控制,内存管理,网络管理,用户管理,进程管理等类型    linux操作系统中,系统调用的ID通常在arch/{体系结构}/include/as

Linux 内核空间与用户空间

本文以 32 位系统为例介绍内核空间(kernel space)和用户空间(user space). 内核空间和用户空间 对 32 位操作系统而言,它的寻址空间(虚拟地址空间,或叫线性地址空间)为 4G(2的32次方).也就是说一个进程的最大地址空间为 4G.操作系统的核心是内核(kernel),它独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限.为了保证内核的安全,现在的操作系统一般都强制用户进程不能直接操作内核.具体的实现方式基本都是由操作系统将虚拟地址空间划分

内核态和用户态,内核空间和用户空间

内核态与用户态是操作系统的两种运行级别,intel cpu提供Ring0-Ring3三种级别的运行模式.Ring0级别最高,Ring3最低 内核态可以拥有比用户态更大的权限 处于内核态的进程,可以访问用户进程空间(是虚拟地址空间),就是通过进程的页表(进程本身就是一个4G虚拟地址空间.其中用户空间的3G是独立的,内核空间是共享的)来访问用户地址空间对应的物理地址,从而访问用户空间 相反用户态的进程,只能访问用户地址空间(虚拟地址空间) 在内核态下,利用内核地址空间中的高端内存地址空间,来映射高端

Linux内核工程导论——用户空间进程使用内核资源

本文大部分转载和组装,只是觉得这些知识应该放到一起比较好. 进程系统资源的使用原理 大部分进程通过glibc申请使用内存,但是glibc也是一个应用程序库,它最终也是要调用操作系统的内存管理接口来使用内存.大部分情况下,glibc对用户和操作系统是透明的,所以直接观察操作系统记录的进程对内存的使用情况有很大的帮助.但是glibc自己的实现也是有问题的,所以太特殊情况下追究进程的内存使用也要考虑glibc的因素.其他操作系统资源使用情况则可以直接通过proc文件系统查看. 进程所需要的系统资源种类

虚拟内存_内核空间_用户空间

转自:http://blog.sina.com.cn/s/blog_65373f1401019f49.html 转载自解惑-Linux内核空间 Linux虚拟内存的大小为2^32(在32位的x86机器上),内核将这4G字节的空间分为两部分.最高的1G字节(从虚地址0xC0000000到0xFFFFFFFF)供内核使用,称为“内核空间”.而较低的3G字节(从虚地址0x00000000到0xBFFFFFFF),供各个进程使用,称为“用户空间”.因为每个进程可以通过系统调用进入内核,因此,Linux内