Linux驱动层应用层数据传递
- Fang XS.
- 1452512966@qq.com
- 如果有错误,希望被指出
前言
- Linux中,内核空间的地址和用户空间的地址是隔绝的,必须使用专门的拷贝函数。
- 对于大数据的拷贝,通常使用
copy_to_user
函数和copy_from_user
函数。 - 对于单个数据拷贝,通常使用
get_user
宏和put_user
宏。
头文件
#include <linux/uaccess.h>
对于大数据拷贝
copy_to_user
函数
unsigned long copy_to_user(void *to, const void __user *from, usigned long n);
函数名 | copy_to_user |
---|
功能 | 将内核空间的数据拷贝到用户空间 |
形参 | to 用户空间的数据目标指针 |
形参 | from 内核空间的数据源指针 |
形参 | n 数据的长度 |
返回值 | 数据拷贝成功,则返回零;否则,返回没有拷贝成功的数据字节数 |
copy_from_user
函数
unsigned long copy_from_user(void __user *to, const void *from, usigned long n);
函数名 | copy_from_user |
---|
功能 | 将用户空间的数据拷贝到内核空间 |
形参 | to 内核空间的数据目标指针 |
形参 | from 用户空间的数据源指针 |
形参 | n 数据的长度 |
返回值 | 数据拷贝成功,则返回零;否则,返回没有拷贝成功的数据字节数 |
对于单个数据拷贝
get_user
宏
#define __get_user(x, ptr) \
({ \
int __gu_err = 0; \
__get_user_error((x), (ptr), __gu_err); \
__gu_err; \
})
#define get_user __get_user
宏名 | get_user |
---|
功能 | 将用户空间的数据拷贝到内核空间 |
形参 | x 驱动程序中的变量 |
形参 | ptr 用户空间的地址 |
返回值 | 数据传递成功,返回 0,否则返回-EFAULT。 |
描述 | 从驱动程序中的x 变量地址处,拷贝sizeof(*ptr) 个字节数据到ptr 用户空间地址处 |
注 | 拷贝的数据大小由指针类型决定 |
put_user
宏
#define __put_user(x, ptr) \
({ \
int __pu_err = 0; \
__put_user_error((x), (ptr), __pu_err); \
__pu_err; \
})
#define put_user __put_user
宏名 | put_user |
---|
功能 | 将内核空间的数据拷贝到用户空间 |
形参 | x 驱动程序中的变量 |
形参 | ptr 用户空间的地址 |
返回值 | 数据传递成功,返回 0,否则返回-EFAULT。 |
描述 | 从用户空间ptr 处读取sizeof(*ptr) 个字节数据方法赋值给驱动程序的x 变量 |
注 | 拷贝的数据大小由指针类型决定 |
总结
copy_to_user
函数和copy_from_user
函数通常用于read
和write
函数,来拷贝较大数据;get_user
宏和put_user
宏通常用于ioctl
函数,来拷贝单个数据,相较于较大数据的拷贝而言,get_user
宏和put_user
宏拷贝速度较快。