Linux ioctl命令在用户空间和内核空间之间变化
问题描述:
不确定是否有人在这里有任何想法,我以前没有看到过。我正在编写一个存根来测试我的内核模块,当我在用户空间中检查命令的值时,我得到了一个与我在内核空间中查看时不同的值。存根的Linux ioctl命令在用户空间和内核空间之间变化
部分:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "ain.h"
#include "ain_ioctl.h"
#define AI_DEVICE "/dev/ain"
void main()
{
int fd, error, ioctl_par = 0;
char* dev;
long ret;
dev = AI_DEVICE;
printf("Starting driver test\n");
fd = open(dev, O_RDWR);
if (fd < 0) {
/* Failed to open -> Print error-message and exit */
printf("%s failed to open, error: %s\n", dev, strerror(errno));
}
printf("Doing the IOCTL now... cmd: %d\n", AIN_IOC_GET_AN0_CONF);
fflush(stdout);
ret = ioctl(fd, AIN_IOC_GET_AN0_CONF, &ioctl_par);
的ain_ioctl.h文件:
内核中的ioctl例程:
int ain_ioctl (struct inode * inodep, struct file * filp, unsigned int cmd, unsigned long arg)
{
printk("In the ain_ioctl function, cmd: %d. type: %d, dir: %d, nr: %d, size: %d\n",
cmd, _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
printk("Testing against command: %d. type: %d, dir: %d, nr: %d, size: %d\n",
AIN_IOC_GET_AN0_CONF, _IOC_TYPE(AIN_IOC_GET_AN0_CONF), _IOC_DIR(AIN_IOC_GET_AN0_CONF),
_IOC_NR(AIN_IOC_GET_AN0_CONF), _IOC_SIZE(AIN_IOC_GET_AN0_CONF));
现在我本来期望相同的输出在用户空间打印和内核一样。在第一组内核中打印到第二组。然而,这不是我所看到的...
输出:
[email protected]:~> ./a.out
Starting driver test
Doing the IOCTL now... cmd: -2147195602
[email protected]:~> dmesg | tail
[75253.205136] In the ain_ioctl function, cmd: -1078168112. type: 117, dir: 2, nr: 208, size: 16316
[75253.205140] Testing against cmd: -2147195602. type: 101, dir: 2, nr: 46, size: 4
任何人有,为什么我的命令行事不同的任何想法,当我通过ioctl命令将其传递给内核VS时,我只是通过对它们进行硬编码来检查这些值(正如我在打印中所做的那样)?
当我建立我看到的唯一的警告似乎无关的ioctl调用:
makedepend: warning: ignoring option -Wall
makedepend: warning: ignoring option -Wall
makedepend: warning: ain.c (reading /usr/src/linux/include/linux/compiler-gcc.h), line 94: incomplete include == "#include gcc_header(__GNUC__)"
makedepend: warning: ain.c (reading /usr/src/linux/include/linux/string.h, line 13): cannot find include file "stdarg.h"
感谢。
答
-1078168112(你为什么不用十六进制打印这些东西?)看起来像一个堆栈指针。可能&ioctl_par
。这表明您的ioctl方法正在接收不同于您预期的参数。
在当前的内核源代码中,我看到ioctl方法接受3个参数,而不是4个参数.4参数ioctl似乎是一个较老的接口。
模块编译过程中是否收到任何警告?注意它们!
答
艾伦库里的答案并不是完整的“正确”答案,但它将我引向解决方案。该命令的十六进制值是关闭的,所以我查看了内核中的其他ioctl调用。
我拥有的系统基于较旧的2.4X内核,而我正在更新它为3.1。这里的问题是ioctl调用的参数列表。在参数列表中具有inode指针会导致问题,因为它将文件指针作为命令。
妥善解决:
long ain_ioctl (struct file * filp, unsigned int cmd, unsigned long arg) {
...
我不知道ioctl的警告。关于构建选项,我会在原始问题中包含这些选项。 十六进制值为: 0x8004652e = -2147195602 0xbf9c28e0 = -1078168112 – Mike 2012-08-16 12:56:31