关于执行ioctl函数,在32位模式下编译和在64位os上编译64位模式有什么不同?
我有一个64位的企业单位的SuSE 11 我有打开HIDRAW设备并在其上运行的ioctl函数来得到这种设备的原始信息象下面这样的应用程序:关于执行ioctl函数,在32位模式下编译和在64位os上编译64位模式有什么不同?
struct hidraw_devinfo devinfo;
int fd = open("/dev/hidraw0", 0);
int ret = ioctl(fd, HIDIOCGRAWINFO, &devinfo);
...
如果我编译这个程序中64位模式没有错误,没有问题,当我执行应用程序时,ioctl函数可以正常工作。
g++ main.cpp
如果我在32位模式下编译这个程序,也没有错误,也没有问题。但是当我执行应用程序的ioctl函数返回EINVAL错误(错误= 22,参数无效)
g++ -m32 main.cpp
什么问题?
注:
struct hidraw_devinfo
{
__u32 bustype;
__s16 vendor;
__s16 product;
}
Linux ioctl
定义和兼容性层是一个引人入胜的话题,我刚刚撞见了我的头。
通常ioctl
定义使用一个系列的宏_IOW/_IOR等人即把你的参数类型名字作为参考,有一个神奇的数字和顺序值是被改写的,给你你的IOCTL参数值一起(如HIDIOCGRAWINFO
) 。类型名称用于将sizeof(arg_type)
编码到定义中。这意味着在用户空间中使用的类型决定了由ioctl
宏生成的值 - 即HIDIOCGRAWINFO可能会因包含条件而异。
这里是第一点,其中32位和64位不同,sizeof
可能会有所不同,取决于打包,使用模糊的数据大小(如长),但特别是(和不可避免的),如果您使用指针参数。因此,在这种情况下,需要支持32位客户端的64位内核模块需要定义兼容性参数类型以匹配参数类型的32位等效版本的布局,从而与32位兼容的ioctl匹配。这些32位等效定义使用称为compat
的内核设施/层。
在你的情况下,sizeof()
是相同的,所以这不是你正在采取的路径 - 但它是重要的了解可能发生的一切。
此外,内核配置可能会定义CONFIG_COMPAT
,它会更改sys-call包装器(特别是围绕用户/内核接口的代码)以减轻支持32位和64位的负担。其中一部分包括兼容性ioctl
的回调称为ioctl_compat
。
我所看到的是CONFIG_COMPAT
定义的32位程序将生成代码,提供ioctl
S到ioctl_compat
回调,即使64位确实可以产生相同的ioctl
值(例如,在你的案件)。所以驱动程序编写者需要确保ioctl_compat
处理两个特殊(不同)32位兼容ioctl
类型和正常的“64位或不变的32位”类型。
因此,仅在32位和64位系统(无CONFIG_COMPAT)上设计和测试的内核模块可能适用于32位和64位程序,但不适用于支持这两种方法的程序。
所以在寻找HID我看到这是在2.6.38补充说:
http://lxr.linux.no/#linux+v2.6.38/drivers/hid/hidraw.c#L347
的问题可能是devinfo
结构程序传递给ioctl
功能之间的不匹配。
我猜你在64位系统上的工作。因此,您的内核以64位运行,而您与之通话的内核模块(与ioctl
)也是64位。
当您以64位编译用户程序时,内核模块和用户程序中的devinfo
定义是相同的。
当您以32位编译用户程序时,内核模块中的devinfo
定义与您在用户程序中的定义不同。事实上,在32位中,某些类型的大小发生了变化:主要是long
和指针。因此,您的程序会创建一定大小的结构,并且内核模块会以不同的方式解释它所接收的数据。内核模块可能不理解你给它的值,因为它不会在你放置它的位置上查找它。
解决的方法是注意devinfo
结构的定义,以便在编译32位和64位时具有相同的二进制表示形式。
我无法理解你的答案。 __u32在32位和64位都是4个字节。 以及__s16在32位和64位都是2个字节。 和sizeof(hidraw_devinfo)的长度是8个字节(考虑操作系统打包)。 – 2012-02-13 12:54:11
另一种解释是内核模块不希望32位用户程序调用它。 (必须有一些特殊的东西来接受它们。)但是,如果是这种情况,我会惊讶于'-EINVAL'错误。 – 2012-02-13 16:20:25
和:http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=commit;h=ae5e49c79c051ea1d5ca91cbd4a0d22189067ba3 – Greg 2012-03-27 04:36:49