12.【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字节)的拷贝。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()相同,也不进行地址检查。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章