Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1753501
  • 博文数量: 199
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 6186
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-30 11:01
个人简介

Linuxer.

文章存档

2015年(4)

2014年(28)

2013年(167)

分类: LINUX

2014-04-19 11:02:56

一、概述
通常情况下,应用程序通过内核接口访问驱动程序,因此,驱动程序需要和应用程序交换数据。Linux将存储器分为“内核空间”和“用户空间”。操作系统和驱动程序在内核空间运行,应用程序在用户空间运行,两者不能简单地使用指针传递数据。
因为Linux系统使用了虚拟内存机制,用户空间的内存可能被换出,当内核空间使用用户空间指针时,对应的数据可能不在内存中。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字节)的拷贝,它们相对较快,当要传递单个数据时,应当用这些宏,而不是copy_from_user()和copy_to_user()。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()相同,也不进行地址检查。
阅读(2371) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~