Linux如何知道要调用哪个ioctl函数?

以下是用户空间中的ioctl调用:

 int ioctl(int fd, int cmd, ...); 

据我所知,当我们想要执行IO操作时,我们用一组请求(命令)来定义我们自己的ioctl函数,把我们的ioctl分配给一个file_operations结构,如下所示:

 struct file_operations fops = { .read = device_read, .write = device_write, .ioctl = device_ioctl, // device_ioctl is our function .open = device_open, .release = device_release, }; 

与用户空间接口相比, device_ioctl函数的定义不同:

 static long device_ioctl(struct file *f, unsigned int cmd, unsigned long arg) 

我认为基于文件描述符,内核可以得到适当的文件结构并调用设备的ioctl

这只是一个猜测,因为我找不到通用函数定义,内核根据传入通用ioctl接口的文件描述符fdselect适当的ioctl函数? 我能find的只有3个ioctl定义,但显然那些只是设备的定义,而不是内核: ioctl

查看Linux源代码,fs / ioctl.c( http://lxr.free-electrons.com/source/fs/ioctl.c
在那里你会看到ioctl的系统调用:

 SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) 

这又调用了do_vfs_ioctl(),它调用vfs_ioctl(),然后调用在file_operations结构中为该文件系统定义的unlocked_ioctl函数。
这将是您注册的device_ioctl功能。

device_ioctl是一个函数指针。 内核只需将fd作为struct file_operations数组的索引,并调用相应元素的.ioctl 。 内核永远不需要知道函数本身是指哪个设备。

这是“一切都是文件”的基础,这是Unix的moto。

当你调用ioctl你传递一个文件描述符。 你从文件描述符打开一个设备文件,如/dev/tty0

 $ ls -l /dev/tty0 crw--w---- 1 root tty 4, 0 Mar 6 10:47 /dev/tty0 $ 

这里的数字4是编码到内核必须使用的驱动模块中的设备主编号。

内核将知道由于文件描述符而调用哪个ioctl函数。 为了能够从用户空间调用ioctl(),您将不得不打开一个文件来获取fd ,最后是一个/ dev / [some_device],其驱动程序将实现file_operations结构,正如您所指出的那样。