ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

linux – 在64位操作系统上编译32位模式和64位操作系统有关ioctl函数的执行有什么不同?

2019-08-26 15:02:53  阅读:453  来源: 互联网

标签:32bit-64bit ioctl linux gcc g


我有64位Enterprice SuSE 11
我有一个应用程序打开一个HIDRAW设备并在其上运行ioctl功能,以获取此设备的原始信息,如下所示:

struct hidraw_devinfo devinfo;
int fd = open("/dev/hidraw0", 0);
int ret = ioctl(fd, HIDIOCGRAWINFO, &devinfo);
...

如果我在64位模式下编译该程序没有错误也没有问题,当我执行应用程序时,ioctl功能正常工作.

g++ main.cpp

如果我在32位模式下编译该程序,也没有错误也没有问题.但是当我执行应用程序时,ioctl函数返回EINVAL错误(errno = 22,无效参数)

g++ -m32 main.cpp

有什么问题?

注意:

struct hidraw_devinfo 
{
     __u32 bustype;
     __s16 vendor;
     __s16 product;
}

解决方法:

Linux ioctl定义和兼容性层是一个引人入胜的话题.

通常,ioctl定义使用一系列宏_IOW / _IOR等,它们将您的参数类型名称作为引用,以及为您提供ioctl参数值(例如HIDIOCGRAWINFO)的幻数和序数值. type-name用于将sizeof(arg_type)编码到定义中.这意味着用户空间中使用的类型决定了ioctl宏生成的值 – 即HIDIOCGRAWINFO可能会根据包含条件而有所不同.

这是32位和64位不同的第一点,sizeof可能会有所不同,具体取决于打包,使用模糊数据大小(例如long),但如果使用指针参数,则尤其(并且不可避免地).因此,在这种情况下,需要支持32位客户端需要的64位内核模块需要定义兼容性参数类型以匹配参数类型的32位等效的布局,从而匹配32位兼容的ioctl.这些32位等效定义使用名为compat的内核工具/层.

在你的情况下,sizeof()是相同的,所以这不是你正在采取的路径 – 但重要的是要了解可能发生的全部事情.

此外,内核配置可以定义CONFIG_COMPAT,它可以更改sys-call包装器(尤其是围绕用户/内核接口的代码),以减轻支持32位和64位的负担.其中一部分包括名为ioctl_compat的兼容性ioctl回调.

我所看到的是,CONFIG_COMPAT定义了32位程序将生成将ioctl传递给ioctl_compat回调的代码,即使它可以生成与64位相同的ioctl值(例如在您的情况下).因此驱动程序编写者需要确保ioctl_compat处理特殊(不同)32位兼容的ioctl TYPE和普通的“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

标签:32bit-64bit,ioctl,linux,gcc,g
来源: https://codeday.me/bug/20190826/1730905.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有