1

誰かがここで何かアイデアを持っているかどうかはわかりませんが、私はこれを前に見たことがありません。カーネルモジュールをテストするためのスタブを作成しています。ユーザースペースでコマンドの値を確認すると、カーネルスペースで確認した場合とは異なる値が得られます。

スタブの一部:

#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));

これで、カーネルの場合と同じ出力がユーザースペースの印刷で期待されていました。そして、カーネルの最初のプリントセットから2番目のプリントセットまで。しかし、それは私が見ているものではありません...

出力:

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" 

ありがとう。

4

2 に答える 2

4

-1078168112(これらを16進数で印刷しないのはなぜですか?)は、スタックポインタのように見えます。おそらく&ioctl_par。これは、ioctlメソッドが予想とは異なるパラメーターを受け取っていることを示しています。

現在のカーネルソースでは、ioctlメソッドが4つではなく3つのパラメーターを使用していることがわかります。4引数のioctlは古いインターフェースのようです。

モジュールのコンパイル中に警告が表示されますか?それらに注意してください!

于 2012-08-15T16:09:54.727 に答える
1

アランカリーの答えは完全な「正しい」答えではありませんでしたが、それは私を解決策に導きました。コマンドの16進値はかなり離れていたので、カーネル内の他のioctl呼び出しを調べました。

私が持っているシステムは古い2.4Xカーネルに基づいており、3.1用に更新しています。ここでの問題は、ioctl呼び出しのパラメーターリストです。パラメータリストにiノードポインタがあると、ファイルポインタがコマンドになるため、問題が発生していました。

適切な解決策:

long ain_ioctl (struct file * filp, unsigned int cmd, unsigned long arg) { 
    ...
于 2012-08-16T13:28:15.273 に答える