目录
1. ioctl概念
ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。
大部分驱动除了读写设备的能里,还需要通过设备驱动对硬件进行各种控制操作。例如,设备上锁,改变波特率,调整转速等等。所有这些命令都是通过ioctl来支持的。
- 用户空间原型:
int ioctl(int fd, unsigned long cmd, ...);
fd: 文件描述符,用户程序使用open函数打开时代表文件的控制符
cmd: 用户程序对设备的控制命令
…: 表示一个单个可选的参数,传统上标识为char *argp,使用…只是为了组织在编译时的类型检查
- 内核空间原型:
long (*unlocked_ioctl) (struct file *file, unsigned int cmd, unsigned long arg);
long (*compat_ioctl) (struct file *file, unsigned int cmd, unsigned long arg);
file: struct file结构体,代表一个打开的文件
cmd: IO操作指令,与用户空间的ioctl中的cmd相同
arg: 传递参数的指针地址,就是用户空间的ioctl的第三个参数地址。使用的话强制转__user指针,使用copy_from_user/copy_to_user操作。
2. 具体实现
通过ioctl, 用户空间只需要通过命令码(cmd)告诉设备驱动程序想要实现的功能,具体功能由设备驱动程序实现,故所有支持的命令码,都需要在设备驱动程序中实现。
在驱动程序中实现的ioctl函数内(file_operations属性),会实现一个switch_case结构,每一个case对应一个cmd所实现的功能。
命令码(cmd)是用户空间和内核空间(驱动程序)唯一的沟通途径。为了让命令能正确的发到相应的设备,Linux内核中对命令码有相应的定义:
type |
number |