为什么我的 IOCTL 调用适用于 copy_from_user 但不适用于 get_user?

Why my IOCTL call work with copy_from_user but not with get_user?

我正在编写一个简单的驱动程序。

这里我正在学习 ioctl 调用,它们在 copy_to_usercopy_from_user 部分工作完美,但在 get_userput_user 部分不工作。如果我通过这些功能发送一些数据,它就会工作;问题是当我必须传递一个整数或字符值时:

long ioctl_funcs(struct file *filp,unsigned int cmd, unsigned long arg)
{

int ret=0;
int len=10;
char val='d';
char valplusone='d';

switch(cmd) {

case IOCTL_HELLO: 
 printk(KERN_INFO "Hello ioctl world");

case READ_IOCTL:    
        copy_to_user((char *)arg, buf, 200);
     //works fine
        break;

case WRITE_IOCTL:
        copy_from_user(buf, (char *)arg, len);
      //works fine
        buf[6]=' ';
        buf[7]='t';
        buf[8]='o';
        buf[9]='o';
        buf[10]='\n';       
        break;

case READ_ONE:  
        printk(KERN_ALERT "valplusone (put user)is %c \n",valplusone);
        put_user(valplusone,(char __user *) arg);

    //problem       
break;

case WRITE_ONE:  
        if(access_ok(VERIFY_WRITE,(void*)arg,sizeof(char))!=1)
{
printk(KERN_ALERT "access not ok\n");
return -EFAULT;
}
else{

        printk(KERN_ALERT "****arg %l",arg);
        get_user(val,(char __user *)arg);
valplusone='t';
printk(KERN_ALERT "val (get user)is %c\n",val);
break;
}

 } 

return ret;

}

在上面的部分中它适用于 从用户复制到用户但不是 get_user put_user 现在用户端代码是:

char sent,received;
if(retval=ioctl(fd, WRITE_ONE, sent) < 0)
        perror("third ioctl");
printf("you sent %c\nretval is %d\n",sent,retval);

if(ioctl(fd, READ_ONE, received) < 0)
        perror("fourth ioctl");
printf("you got %c",received);
-----------------------------------

您必须传递地址,而不是值。示例:

if (ioctl(fd, READ_ONE, &received) < 0)
…