ioctl-无效参数

ioctl-无效参数,c,linux,driver,C,Linux,Driver,我有 #define IOCTL_ALLOC_MSG _IO(MAJOR_NUM, 0) #define IOCTL_DEALLOC_MSG _IO(MAJOR_NUM, 1) 在头文件中 在驱动程序文件中,我写道: struct file_operations memory_fops = { unlocked_ioctl: device_ioctl, open: memory_open, release: memory_release }; int memory_init(

我有

#define IOCTL_ALLOC_MSG _IO(MAJOR_NUM, 0) 
#define IOCTL_DEALLOC_MSG _IO(MAJOR_NUM, 1)
在头文件中

在驱动程序文件中,我写道:

struct file_operations memory_fops = {
  unlocked_ioctl: device_ioctl,
  open: memory_open,
  release: memory_release
};


int memory_init(void) {
  int result;

  /* Registering device */
  result = register_chrdev(MAJOR_NUM, "memory", &memory_fops);
  if (result < 0) {
    printk("<1>memory: cannot obtain major number %d\n", MAJOR_NUM);
    return result;
  }

  allocfunc();

  printk("<1>Inserting memory module\n");
  return 0;

}

int device_ioctl(struct inode *inode,   /* see include/linux/fs.h */
         struct file *file, /* ditto */
         unsigned int ioctl_num,    /* number and param for ioctl */
         unsigned long ioctl_param)
{
    /* 
     * Switch according to the ioctl called 
     */
    printk ( "<l> inside ioctl \n" );
    switch (ioctl_num) {
    case IOCTL_ALLOC_MSG:
        allocfunc();
        break;
    case IOCTL_DEALLOC_MSG:
        deallocfunc();
        break;
    }

    return 0;
}
应用程序调用失败

int main(int argc, char *argv[]) {
    FILE * memfile;

    /* Opening the device parlelport */
    memfile=fopen("memory","r+");
    if ( memfile <0) {
        printf ( " cant open file \n");
        return -1;
    }

    /* We remove the buffer from the file i/o */
    int ret_val;
    if ( argc > 1 ) {
        if ( strcmp (argv[1], "mem" ) ==0 ) {


            ret_val = ioctl(memfile, IOCTL_ALLOC_MSG);

            if (ret_val < 0) {
                printf("ioctl failed. Return code: %d, meaning: %s\n", ret_val, strerror(errno));
                return -1;
            }
        }

仅供参考,我尝试了“/dev/memory”“memory”不同的名称和主要数字组合,但徒劳无功。

我假设将
fopen(“内存”)
更改为
fopen(/dev/memory1”)
将解决代码的初始问题


@SunEric在对您的问题的评论中还指出,您在驱动程序的初始化函数(
memory\u init()
)中调用了
allocFunc()
),但这似乎是您希望
IOCTL\u ALLOC\u MSG
执行的操作。这很可能是您需要解决的下一个问题。

我假设将
fopen(“内存”)
更改为
fopen(“/dev/memory1”)
将修复代码的初始问题


@SunEric在对您的问题的评论中还指出,您在驱动程序的初始化函数(
memory\u init()
)中调用了
allocFunc()
),但这似乎是您希望
IOCTL\u ALLOC\u MSG
执行的操作。这可能是您需要解决的下一个问题。

您正在将一个
文件*
传递给
ioctl()
函数,而它需要一个文件描述符,即
int

它至少应该生成一个大警告,说明您正在将指针转换为不带强制转换的整数,不是吗

有两个显而易见的解决方案:

  • 使用
    fileno()
    函数从
    文件*
    获取文件描述符。它应该类似于
    ioctl(fileno(memfile),ioctl\u ALLOC\u MSG)
  • 使用
    open()
    而不是
    fopen()
    。如果您正在编写低级代码,这是首选的解决方案,因为您避免了
    FILE*
    强加的额外抽象层(所有缓冲内容等等)

  • 您正在将一个
    文件*
    传递给
    ioctl()
    函数,而它需要一个文件描述符,即
    int

    它至少应该生成一个大警告,说明您正在将指针转换为不带强制转换的整数,不是吗

    有两个显而易见的解决方案:

  • 使用
    fileno()
    函数从
    文件*
    获取文件描述符。它应该类似于
    ioctl(fileno(memfile),ioctl\u ALLOC\u MSG)
  • 使用
    open()
    而不是
    fopen()
    。如果您正在编写低级代码,这是首选的解决方案,因为您避免了
    FILE*
    强加的额外抽象层(所有缓冲内容等等)

  • MAJOR\u NUM
    的值是多少?您确定60尚未被其他驱动程序使用吗?i、 e.init_module()函数是什么样子的,如果它调用
    register_chrdev()
    ,结果如何?另外,您甚至没有显示对
    strerror()
    …MAJOR\u NUM是60,并且没有被另一个driverrint memory\u init(void){int result;/*registing device*/result=register\u chrdev(MAJOR\u NUM,“memory”,&memory\u fops)使用;if(result<0){printk(“内存:无法获取主数字%d\n”,MAJOR\u NUM);return result;}allocfunc();printk(“插入内存模块”);return 0;}----app------ret\u val=ioctl(memfile,ioctl\u ALLOC\u MSG);如果(ret_val<0){printf(“ioctl失败。返回代码:%d,意思是:%s\n”),ret_val,strerror(errno));返回-1;}好的,那么也许您可以将其编辑到上面的代码中?另外,请在调用
    strerror()
    之前(包括调用
    strerror()
    )的
    fopen()
    之间添加所有代码(特别是如果您检查了
    fopen()
    的结果),并显示从模块加载到调用
    ioctl()
    之前的所有控制台输出(即,我想查看
    printk())
    以及任何其他相关输出。我用init、app和printk更新了原始帖子。为什么要调用子程序
    allocFunc()
    在初始化模块时?不应该调用该函数,当进程在设备上执行ioctl时。由于您正在分配的不是宏
    ioctl\u ALLOC\u MSG
    是用读/写权限定义的。
    MAJOR\u NUM
    的值是多少?您确定60没有被其他驱动程序使用吗?即,您的初始化模块()函数看起来像,如果它调用了
    register\u chrdev()
    ,结果是什么?另外,您甚至没有显示对
    strerror()
    …MAJOR\u NUM是60,并且没有被另一个driverrint memory\u init(void){int result;/*registing device*/result=register\u chrdev(MAJOR\u NUM,“memory”、&memory\u fops)使用;if(result<0){printk(“内存:无法获取主数字%d\n”,major\u NUM);返回结果;}allocfunc();printk(“插入内存模块”);返回0;}----app------ret\u val=ioctl(memfile,ioctl\u ALLOC\MSG);if(ret\u val<0){printf(“ioctl失败。返回代码:%d,意思是:%s\n”,ret_val,strerror(errno));return-1;}好的,那么也许您可以将其编辑到上面的代码中?并且还请添加
    fopen()
    到调用
    strerror()
    之间的所有代码(特别是如果您检查了
    fopen()
    ),并显示从模块加载到调用
    ioctl()
    期间的任何控制台输出(即,我希望看到其中的
    printk()
    和任何其他相关输出。我用init、app和printk更新了原始帖子。为什么要调用子程序
    allocFunc()
    在初始化模块时?不应该是,当进程在设备上执行ioctl时调用函数。因为您正在分配的不是宏
    ioctl\u ALLOC\u MSGint main(int argc, char *argv[]) {
        FILE * memfile;
    
        /* Opening the device parlelport */
        memfile=fopen("memory","r+");
        if ( memfile <0) {
            printf ( " cant open file \n");
            return -1;
        }
    
        /* We remove the buffer from the file i/o */
        int ret_val;
        if ( argc > 1 ) {
            if ( strcmp (argv[1], "mem" ) ==0 ) {
    
    
                ret_val = ioctl(memfile, IOCTL_ALLOC_MSG);
    
                if (ret_val < 0) {
                    printf("ioctl failed. Return code: %d, meaning: %s\n", ret_val, strerror(errno));
                    return -1;
                }
            }
    
    Inserting memory module