我的char设备无法打开

时间:2012-05-20 10:47:08

标签: c linux char device linux-device-driver

我有一个问题让我困惑了一个星期。我希望有人能帮助我。 我在insmod下写了一个简单的char设备模块,mknod到内核,/dev一个char文件。我可以insmod之后通过cat /proc/devices看到它。但是当我打开这个char设备文件时出错。

我的char设备代码是:

#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#define CALL_DEV_NAME  "mn2"
#define CALL_DEV_MAJOR 230
struct cdev cdev;
MODULE_LICENSE("GPL");

int call_open(struct inode *inode,struct file *filp){
    int num=MINOR(inode->i_rdev);
    printk("call open minor is:%d \n",num);
    return 0;
}


static struct file_operations call_fops={
    .owner=THIS_MODULE,
    .open=call_open,
};

int call_init(void){
    int result;
    printk("call call_init \n");
    result=register_chrdev_region(MKDEV(CALL_DEV_MAJOR,0),
        1,CALL_DEV_NAME);
    if(result<0){
        printk("registerfail \n");
        return result;
    }
    cdev_init(&cdev,&call_fops);
    cdev.ops=&call_fops;
    cdev.owner=THIS_MODULE;
    cdev_add(&cdev,MKDEV(CALL_DEV_MAJOR,0),1);
    return 0;
}

void call_exit(void){
    printk("call call_exit \n");
    unregister_chrdev(CALL_DEV_MAJOR,CALL_DEV_NAME);
}

module_init(call_init);
module_exit(call_exit);

测试代码是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
 #include <fcntl.h>

int main(){
    FILE *fd;
    fd=fopen("/dev/mn2","r+");

    if(fd==NULL)
    printf("fail\n");
    }

我的Makefile是:

ifneq ($(KERNELRELEASE),)
obj-m := mn2.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

all:
    $(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
    rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order
endif

我使用的命令是:

make
insmod mn2.ko

然后我可以在mn2

中看到/proc/devices
mknod mn2 c 230 0

并且mn2

下还有一个/dev文件

但是在我通过gcc test.c -o test编译test.c并运行测试之后,我总是得到一个fail世界。

你能帮我发现我的错误吗?

1 个答案:

答案 0 :(得分:1)

使用此:

fprintf(stderr, "fopen() failed: %s\n", strerror(errno));

包含文件<errno.h>。 它会为您提供有关错误的详细信息。我认为它的权威问题。尝试使用sudo运行用户空间二进制文件。