/*Linux字符设备驱动源代码scdd.c*/#include <linux/init.h> /*模块头文件*/#include <linux/module.h>#include <linux/types.h> /*dev_t头文件*/#include <linux/kdev_t.h> /*MAJOR和MINOR宏头文件*/#include <linux/fs.h> /*register_chrdev_region等函数 file_operations结构体*/#include <linux/cdev.h> /*struct cdev结构体*/#include <asm/uaccess.h> /*copy_to_user函数*/ #define DEVICE_NAME "scdd" /*定义设备名*/#define DEVICE_MAJOR 250 struct cdev my_cdev; int scdd_open(struct inode *inode,structfile *filp){ return0; }int scdd_close(struct inode *inode,structfile *filp){ return0; }ssize_t scdd_read(struct file *filp,char__user *buff,size_t size,loff_t *offp){ intleft; chardata=1; for(left=size;left>0;left--) { /*拷贝数据到用户空间*/ copy_to_user(buff,&data,1); buff++; } returnsize;}ssize_t scdd_write(struct file *filp,char__user *buff,size_t size,loff_t *offp){ return0;}/*file_operations结构体*/struct file_operations scdd_fops={ .owner=THIS_MODULE, .read=scdd_read, .write=scdd_write, .open=scdd_open, .release=scdd_close,};static int __init scdd_init(void){ /*模块初始化函数*/ intsmajor; smajor=DEVICE_MAJOR; dev_tdev_n=MKDEV(smajor,0); /*申请设备号*/ if(!register_chrdev_region(dev_n,1,DEVICE_NAME)) { /*静态申请*/ printk("registersuccess
"); }else { gotoregister_error; } /*else { /*动态申请*/ /*alloc_chrdev_region(&dev_n,0,1,DEVICE_NAME); smajor=MAJOR(dev_n); }*/ /*初始化cdev结构体*/ cdev_init(&my_cdev,&scdd_fops); my_cdev.owner=THIS_MODULE; my_cdev.ops=&scdd_fops; /*注册字符设备*/ cdev_add(&my_cdev,dev_n,1); return0; register_error: unregister_chrdev_region(MKDEV(DEVICE_MAJOR,0),1); return0;}static void __exit scdd_exit(void){ /*模块卸载函数*/ cdev_del(&my_cdev); unregister_chrdev_region(MKDEV(DEVICE_MAJOR,0),1);} module_init(scdd_init);module_exit(scdd_exit);MODULE_LICENSE("Dual BSD/GPL");
这个程序只是简单演示字符注册的一个完整过程,并不带有复杂的操作,调用read时向用户空间写全1