这是一个字符驱动的框架,使用固定分配主设备号和次设备号,功能只是读取内核 中的一段字符串“hello world!”但是麻雀随小无脏俱全! 模块代码 /*chardev.c*/ #include #include /*for file-f_op*/ #include #include /*for copy_to_user()*/ #include /*for cdev ,cdev_init,cdev_add....*/
MODULE_LICENSE("GPL"); MODULE_AUTHOR("Helight");
#define DP_MAJOR 250 /*the major number of the chardev*/ #define DP_MINOR 0 /*the minor number of the chardev*/ static int char_read(struct file *filp,char __user *buffer,size_t,loff_t *); /*the read operation of the chardev----read the data from kernel*/ static int char_open(struct inode *,struct file *); /*open the chardev*/ static int char_write(struct file *filp,const char __user *buffer,size_t ,loff_t*); /*write data to kernel*/ static int char_release(struct inode *,struct file *); /*release the chardev*/ static char *arr,*p; static int chropen; /*the chardev open or not*/ struct cdev *chardev; /*define a char device*/ static int len;
struct file_operations char_ops = { .read = char_read, .write = char_write, .open = char_open, .release = char_release,
};
static int __init char_init(void) { dev_t dev; printk(KERN_ALERT"Initing......\n"); dev=MKDEV(DP_MAJOR,DP_MINOR); chardev = cdev_alloc( );
if(chardev==NULL){ return -1; }
if(register_chrdev_region(dev,10,"chardev")<0){ printk(KERN_ALERT"Register char dev error\n"); return -1; }
chropen=0; len=0; //chardev->ops = &char_ops; cdev_init(chardev,&char_ops); if(cdev_add(chardev,dev,1)<0) { printk(KERN_ALERT"Add char dev error\n");
}
return 0;
}
static int char_open(struct inode *inode,struct file *file) { if(chropen==0) chropen++; else{ printk(KERN_ALERT"Another process open the char device\n"); return -1; }
try_module_get(THIS_MODULE); return 0;
}
static int char_release(struct inode *inode,struct file *file) { chropen--; module_put(THIS_MODULE); return 0;
}
static int char_read(struct file *filp,char __user *buffer,size_t length,loff_t *offset) { int i=0; if(length if(copy_to_user(buffer,"hello world!",length)) { return 0; } }else{ if(copy_to_user(buffer,"hello world!",12)) { return 0; } }
return i;
}
static int char_write(struct file *filp,const char __user *buffer,size_t length,loff_t *offset) {
int i=0; return i;
}
static void __exit module_close(void) { len=0; printk(KERN_ALERT"Unloading..........\n"); kfree(arr); unregister_chrdev_region(MKDEV(DP_MAJOR,DP_MINOR),10); cdev_del(chardev);
}
module_init(char_init); module_exit(module_close);
用户程序 /*main.c*/ #include #include #include #include #include #include #include
int main(void) { int testdev; int i; char buf[15];
testdev = open("/dev/chardev0",O_RDWR); if ( testdev == -1 ) { printf("Cann't open file \n"); exit(0); }
memset(buf, 0, sizeof(buf)); if(i=read(testdev,buf,12)<0) perror("read error\n");
printf("Re:%d %s\n",i,buf); close(testdev);
return 0;
}
Makefile文件:
obj-m:=chardev.o KERNELDIR=/usr/src/linux-headers-2.6.22-14-generic/ all: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules gcc -o main main.c
使用步骤: 1。make模块 2。insmod模块 3。mknod结点,具体命令如下: mknod /dev/chardev0 c 250 0 命令解释: mknod是建立节点的命令; /dev/chardev0:在/dev/目录下建立chardev0这样一个节点, c:这个节点是指向一个字符设备的节点 250:这个设备的主设备号; 0:次设备号 4。chmod 666 /dev/chardev0 使其他用户也可以对这个设备进行读写操作,否则 只有root用户可以对他进行读写 5。编译用户程序 6,运行用户程序./main 7.如果没有什么问题的话应该要输出 Re:12 hello world! 这几个字符。 | |