- 在用户空间,ioctl原型
- int ioctl(int fd, unsigned long cmd,...)
- 驱动ioctl方法
- int (*ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
- 实现ioctl方法
- 1.定义命令
- 4个位段:Type Number Direction(_IOC_NONE没有数据传输,_IOC_READ,_IOC_WRITE) Size
- 内核提供的宏
- _IO(type, nr)
- 没有参数的命令
- _IOR(type, nr, datatype)
- 从驱动中读数据
- _IOW(type, nr, datatype)
- 写数据到驱动
- _IOWR(type, nr, datatype)
- 双向传送,type和number成员作为参数被传送
- 定义的示范
- #define MEM_IOC_MAGIC 'm'//定义幻数
- #define MEM_IOCEST _IOW(MEM_IOC_MAGIC, 0, int)
- #define MEM_IOCGQSET _IOR(MEM_IOC_MAGIC, 1, int)
- 2.实现命令
- 参数:整数可以直接使用,指针使用前需进行正确的检查;
- 不需要检测:
- copy_from_user
- copy_to_uesr
- get_user
- put_user
- 需要检测:
- __get_user
- __put_user
- 参数检测:
- int access_ok(int type, const void *addr, unsigned long size)
- 第一个参数是VERIFY_READ或者VERIFY_WRITE(对用户空间的读和写的检测)
- 例:
- if(_IOC_DIR(cmd)&_IOC_READ)
- err=!access_ok(VERIFY_WRITE, (void __user*)arg, _IOC_SIZE(cmd),_IOC_SIZE(cmd));
- else if(_IOC_DIR(cmd)&_IOC_WRITE)
- err=!access_ok(VERIFY_READ, (void __user*)arg, _IOC_SIZE(cmd));
- if(err)
- return -EINVAL;
- 命令的实现:
- switch(cmd)
- {
- case MEM_IOCSQUABTUM;
- break;
- case MEM_IOCGQUANTUM:
- break;
- default:
- return -EINVAL;
- }