|
详解Linux操作系统设备驱动兼容性(5) unsigned long copy_to_user(unsigned long to, unsigned long from, unsigned long len); unsigned long __copy_to_user(unsigned long to, unsigned long from, unsigned long len); copy_to_user(to, from, len, retval);
这些函数被用来将数据复制到用户空间,它们的行为非常类似于它们的copy_from的对应者。2.1版核心还定义了其它访问用户空间的函数:clear_user,strncpy_from_user,和strlen_user。我不打算讨论它们了,因为Linux2.0中没有这些函数,并且驱动程序的代码也很少用到它们。有兴趣的读者可以看看。
使用新的接口 访问用户空间的新的函数集初看起来可能有点令人失望,但它们的确使程序员的日子好过的多了。在Linux2.1上,不再需要显式地检查用户空间;access_ok一般不需要调用。使用新接口的代码可以直接进行数据传送。_ret函数在实现系统调用时证明是相当有用的,因为一个用户空间的失败通常导致系统调用的一个返回-EFAULT的失败。因此,一个典型的read实现,看起来如下:
long new_read(struct inode *inode, struct file *filp, char *buf, unsigned long count); { /* identify your data (device-specific code) */ if (__copy_to_user(buf, new_data, count)) return -EFAULT; return count; }
注意使用不进行检查的__copy_to_user是因为调用者在把数据传输分派到文件操作之前已经检查了用户空间。这就象2.0,read和write不需要调用verify_area。类似地,典型的ioctl实现看起来如下:
int new_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); { /* device-specific checks, if needed */ switch(cmd){ case NEW_GETVALUE: put_user_ret(new_value, (int *)arg, -EFAULT); break; case NEW_SETVALUE: get_user_ret(new_value, (int *)arg, -EFAULT); default:
return –EINVAL;
|