您的位置:首页 > 运维架构 > Linux

Linux 用户空间与内核空间数据交换方式

2016-11-22 20:57 295 查看
http://blog.sina.com.cn/s/blog_71fdf1f00102v5o8.html

引言

一般地,在使用虚拟内存技术的多任务系统上,内核和应用有不同的地址空间,因此,在内核和应用之间以及在应用与应用之间进行数据交换需要专门的机制来实现,众所周知,进程间通信(IPC)机制就是为实现应用与应用之间的数据交换而专门实现的,大部分读者可能对进程间通信比较了解,但对应用与内核之间的数据交换机制可能了解甚少

本文将详细介绍 Linux 系统下内核与应用进行数据交换的各种方式,包括内核启动参数、模块参数与 sysfs、sysctl、系统调用、netlink、procfs、seq_file、debugfs 和 relayfs。

系统调用

Linux内核提供了多个函数和宏用于内核空间和用户空间传递数据。

主要有:access_ok(),copy_to_user(),copy_from_user,put_user,get_user。

1.access_ok()

函数原型:int access_ok(int type,unsigned long addr,unsigned long size)

函数access_ok()用于检查指定地址是否可以访问。参数type为访问方式,可以为VERIFY_READ(可读),VERIFY_WRITE(可写)。addr为要操作的地址,size为要操作的空间大小(以字节计算)。函数返回1,表示可以访问,0表示不可以访问。

2.copy_to_user()和copy_from_user()

函数原型:unsigned long copy_to_user(void *to,const void *from,unsigned long len)

unsigned long copy_from_user(void *to,const void *from,unsigned long len)

这两个函数用于内核空间与用户空间的数据交换。copy_to_user()用于把数据从内核空间拷贝至用户空间,copy_from_user()用于把数据从用户空间拷贝至内核空间。第一个参数to为目标地址,第二个参数from为源地址,第三个参数len为要拷贝的数据个数,以字节计算。这两个函数在内部调用access_ok()进行地址检查。返回值为未能拷贝的字节数。

3.get_user()和put_user()

函数原型:int get_user(x,p)

int put_user(x,p)

这是两个宏,用于一个基本数据(1,2,4字节)的拷贝。get_user()用于把数据从用户空间拷贝至内核空间,put_user()用于把数据从内核空间拷贝至用户空间。x为内核空间的数据,p为用户空间的指针。这两个宏会调用access_ok()进行地址检查。拷贝成功,返回0,否则返回-EFAULT。

4.还有两个函数__copy_to_user()和__copy_from_user(),功能与copy_to_user()和copy_from_user()相同,只是不进行地址检查。还有两个宏__get_user()和__put_user(),功能与get_user()和put_user()相同,也不进行地址检查。

(通常情况下,应用程序通过内核接口访问驱动程序,因此,驱动程序需要和应用程序交换数据。Linux将存储器分为“内核空间”和“用户空间”。操作系统和驱动程序在内核空间运行,应用程序在用户空间运行,两者不能简单地使用指针传递数据。因为Linux系统使用了虚拟内存机制,用户空间的内存可能被换出,当内核空间使用用户空间指针时,对应的数据可能不在内存中。Linux内核提供了多个函数和宏用于内核空间和用户空间传递数据。)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐