我有一个问题让我困惑了一个星期。我希望有人能帮助我。
我在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
世界。
你能帮我发现我的错误吗?
答案 0 :(得分:1)
使用此:
fprintf(stderr, "fopen() failed: %s\n", strerror(errno));
包含文件<errno.h>
。
它会为您提供有关错误的详细信息。我认为它的权威问题。尝试使用sudo运行用户空间二进制文件。