我正在写一个简单的驱动程序。
在这里,我正在学习ioctl
调用,它们在copy_to_user
和copy_from_user
部分完美工作,但不在get_user
和put_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) …