分类: 嵌入式
2009-11-20 14:41:09
编写驱动程序中ioctl的步骤:
| 31-30 | 29-16 | 15-8 | 7-0 |
| direction(2bits) | size(14bits) | type(8bits) | number(8bits) |
新的符号都定义在linux/ioctl.h : 中。
_IO(type,nr)/*没有参数的命令*/_IOR(type, nr, datatype)/*从驱动中读数据*/_IOW(type,nr,datatype)/*写数据*/_IOWR(type,nr,datatype)/*双向传送*//*type 和 number 成员作为参数被传递, 并且 size 成员通过应用 sizeof 到 datatype 参数而得到*/
在使用switch之前,对cmd进行有效检验,如果检验无效返回:-ENOTTY
以及通过函数access_ok验证指向用户空间的地址是否合法,不合法返回:-EINVAL
int err = 0, tmp;
int retval = 0;
/*
* extract the type and number bitfields, and don't decode
* wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
*/
if (_IOC_TYPE(cmd) != SCULL_IOC_MAGIC) return -ENOTTY;
if (_IOC_NR(cmd) > SCULL_IOC_MAXNR) return -ENOTTY;
/*
* the direction is a bitmask, and VERIFY_WRITE catches R/W
* transfers. `Type' is user-oriented, while
* access_ok is kernel-oriented, so the concept of "read" and
* "write" is reversed
*/
if (_IOC_DIR(cmd) & _IOC_READ)
err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) & _IOC_WRITE)
err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
if (err) return -EFAULT;
接下来就要根据不同的设备对各种命令进行实现.
*******************************************************
文件头有:
// get_user __get_user copy_from_user