如何从用户空间调用compat ioctl?任何人都可以提供一些例外吗?

deb*_*yay 5 linux kernel

假设我已经定义了以下内容.

#define MY_IOCTL_CMD1 _IOR(MAGIC_NUMBER, 0x01, arg1)
#define MY_IOCTL_CMD2 _IOW(MAGIC_NUMBER, 0x02, arg2)
#ifdef CONFIG_COMPAT
#define MY_COMPAT_IOCTL_CMD1 _IOR(MAGIC_NUMBER, 0x01, compat_arg1)
#define MY_COMPAT_IOCTL_CMD2 _IOW(MAGIC_NUMBER, 0x02, compat_arg2)
#endif
Run Code Online (Sandbox Code Playgroud)

现在,当我们从用户空间进行ioctl时,我们通常会这样做

ioctl(fd, MY_IOCTL_CMD1, &arg1)
Run Code Online (Sandbox Code Playgroud)

问:我们真的需要有ioctl MY_COMPAT_IOCTL_CMD1作为请求吗?

在devide代码中,我的处理程序定义如下.ioctl:device_ioctl

#ifdef CONFIG_COMPAT
compat_ioctl: device_compat_ioctl
#endif
Run Code Online (Sandbox Code Playgroud)

有人可以提供一些解释吗?

小智 6

这个compat用于在64位内核中运行32位程序.当您ioctl(fd, MY_IOCTL_CMD1, &arg1)在64位内核上调用32位程序时,内核会将ioctl转移到struct .compat_ioctl中的file_operations函数.此compat_ioctl函数负责复制用户参数,arg1就像compat_arg1使用32位布局一样.所述compat_arg1的typedef在内核定义,以便编译为64位时,该结构是完全相同的布局相同的arg1编译为32位.

创建cmd id时MY_IOCTL_CMD1将考虑定义sizeof arg1.编译32位计算机的程序时,其值MY_IOCTL_CMD1将与为64位计算机编译时的值不同.但是,32位MY_IOCTL_CMD1应该MY_COMPAT_IOCTL_CMD1与内核中的64 位具有相同的值.

无需使用compat_arg1MY_COMPAT_IOCTL_CMD1在用户空间应用程序中使用.这些仅适用于内核中编译的代码.