0

カーネル空間にioctlを実装して、レジスタに日付を書き込もうとしていますが、ioctlのcmdでクラッシュが発生します。

以下は私のコードです:

カーネル側:

static struct file_operations fops = {
.compat_ioctl = device_ioctl
};

int device_ioctl(struct inode *inode, struct file *filep, 
                 unsigned int cmd, unsigned long arg)
{

    int len = 200;

    printk (KERN_INFO "In Device_ioctl !!\n");
    switch(cmd)
    {
    case IOCTL_WRITE_REG:
        write_ioctl((unsigned long *)arg);
        break;

    default:
        printk (KERN_INFO "default\n");
        return -ENOTTY;
    }
    printk (KERN_INFO "device_ioctl out\n");
    return len;
}

ユーザー側

#define IOCTL_WRITE_REG _IOW(MAJOR_NUM, 1, int *)
void write_to_device(int write_fd)
{

    int retval;
    unsigned int to_write1 = 1;

    retval = ioctl(write_fd, IOCTL_WRITE_REG, &to_write1);
    if(retval < 0)
    {
        printf("fd: %d, write error: %d\n", write_fd, errno);
        exit(-1);
    }
}

device_ioctl関数に入っていません。どこが間違っていますか?

4

1 に答える 1

3

私が気付くことがいくつかあります:

  • unlocked_ioctlの代わりに使用する必要がありますcompat_ioctlcompat_ioctl32ビットユーザースペースプログラムがioctl64ビットカーネルで呼び出しを呼び出せるようにすることです。
  • ioctlハンドラー関数のシグネチャが正しくありません(の場合unlocked_ioctl)。予想される署名は次のとおりです。

    long (*unlocked_ioctl) (struct file * filep, unsigned int, unsigned long);
    

私はこのコードを実際にコンパイルしようとはしていませんが、これはうまくいくはずだと思います:

static struct file_operations fops = {
    .unlocked_ioctl = device_ioctl
};

long device_ioctl(struct file *filep, 
                  unsigned int cmd,
                  unsigned long arg)
{

    int len = 200;

    printk (KERN_INFO "In Device_ioctl !!\n");
    switch(cmd)
    {
    case IOCTL_WRITE_REG:
        write_ioctl((unsigned long *)arg);
        break;

    default:
        printk (KERN_INFO "default\n");
        return -ENOTTY;
    }
    printk (KERN_INFO "device_ioctl out\n");
    return len;
}
于 2013-03-26T04:34:28.930 に答える