[英]Linux ioctl command is changing between userspace and kernel space
不知道這里是否有任何想法,我之前從未見過。 我正在編寫一個存根來測試我的內核模塊,當我在用戶空間中檢查命令的值時,我得到的值與查看內核空間中的命令時的值不同。
部分存根:
#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文件:
#define AIN_IOC_MAGIC 'e'
#define AIN_IOC_GET_AN0_CONF _IOR(AIN_IOC_MAGIC, 46, int)
內核中的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));
現在,我期望用戶空間打印中的輸出與內核中的輸出相同。 並在內核中將第一組打印輸出到第二組。 但是那不是我所看到的...
輸出:
mike@linux-4puc:~> ./a.out
Starting driver test
Doing the IOCTL now... cmd: -2147195602
mike@linux-4puc:~> 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命令將其傳遞給內核時的命令與為什么僅通過對值進行硬編碼進行檢查(就像我在打印中所做的操作)為何有不同的想法有任何想法嗎?
我在構建時看到的唯一警告似乎與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似乎是一個較舊的接口。
在模塊編譯期間是否收到任何警告? 注意他們!
艾倫·庫里(Alan Curry)的答案並不是完整的“正確”答案,但它使我找到了解決方案。 該命令的hex值相去甚遠,因此我看了內核中的其他ioctl調用。
我擁有的系統基於較舊的2.4X內核,並且我將其更新為3.1。 這里的問題是ioctl調用的參數列表。 將inode指針放在參數列表中會導致問題,因為它將文件指針作為命令。
正確的解決方案:
long ain_ioctl (struct file * filp, unsigned int cmd, unsigned long arg) {
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.