你的
MSG_GET_ADDRESS
ioctl请求代码定义为:
#define MSG_GET_ADDRESS _IOR(MSG_MAGIC_NUMBER, 4, unsigned long)
第三个参数的大小被编码到ioctl请求代码中。可以使用
_IOC_SIZE(req)
宏。
消息\u获取\u地址
与64位进程/内核相比,32位进程/内核将有所不同。特别是,编码的大小将不同。
在32位进程/内核上,
_IOC_SIZE(MSG_GET_ADDRESS)
四岁。在64位进程/内核上,
_IOC\大小(消息\获取\地址)
sizeof(unsigned long)
32位和64位系统上的值。
在支持32位兼容性的64位内核上运行32位进程时,32位进程将调用
ioctl()
消息\u获取\u地址
请求代码。但是,你的司机
device_compat_ioctl()
正在寻找64位版本的
消息\u获取\u地址
请求代码。
一个解决方案是在驱动程序中定义一个32位版本的ioctl请求代码来镜像“官方”
消息\u获取\u地址
#define MSG32_GET_ADDRESS _IOR(MSG_MAGIC_NUMBER, 4, compat_ulong_t)
请注意,此请求代码不需要位于用户模式标头中,因为它仅用于内核模式。但是,如果更方便的话,可以将其包含在用户模式标头中,但要包装在
#ifdef __KERNEL__
#endif
一对:
#ifdef __KERNEL__
#define MSG32_GET_ADDRESS _IOR(MSG_MAGIC_NUMBER, 4, compat_ulong_t)
#endif
现在,你的
device_compat_ioctl
函数应更改为处理
MSG32_GET_ADDRESS
消息\u获取\u地址
请求代码:
case MSG32_GET_ADDRESS:
put_user(0x12345678, (compat_ulong_t*)arg);
pr_info("MSG_GET_ADDRESS\n");
break;
注:
根据代码中的注释
消息\u获取\u地址
实际上应该获取内核缓冲区的地址。我不知道您的用户空间代码打算用它做什么,但是请注意,64位内核地址不适合32位
unsigned long
(或32位
compat_ulong_t
类型)。