在上一篇中,我们介绍了有关简单字符设备驱动中那些简单但又必须要掌握的结构体和一些源码中核心的操作函数,这一节我们继续介绍有关源码部分的后续相关内容及测试使用的方法(在本文中同时也会给出完整的Makefile文件,方便大家调试)。
static const struct file_operations globalmem_fops = { //这些就是上篇中所实现的所有操作该字符设备的函数接口,这些最终都会被用户程序中的open(),read()所调用 .owner= THIS_MODULE, .llseek = globalmem_llseek, .read = globalmem_read, .write = globalmem_write, .ioctl = globalmem_ioctl, .open = globalmem_open, .release = globalmem_release, }; //初始化并添加cdev结构 static void globalmem_setup_cdev(struct globalmem_dev *dev, int index) { int err,devno=MKDEV(globalmem_major,index); cdev_init(&dev->cdev,&globalmem_fops); dev->cdev.owner = THIS_MODULE; dev->cdev.ops=&globalmem_fops; err=cdev_add(&dev->cdev,devno,1); if(err) printk(KERN_NOTICE "Error %d adding LED%d",err, index); } //globalmem设备驱动模块加载函数 int globalmem_init(void) { int result; dev_t devno=MKDEV(globalmem_major,0); //申请设备驱动区域 if(globalmem_major) { result=register_chrdev_region(devno,1,"globalmem"); } else {//动态获得主设备号 result=alloc_chrdev_region(&devno,0,1,"globalmem"); globalmem_major=MAJOR(devno); } if(result<0) return result; printk(KERN_ALERT "T1\n"); globalmem_devp = kmalloc(sizeof(struct globalmem_dev),GFP_KERNEL); printk(KERN_ALERT "T0\n"); if(!globalmem_devp) { result = -ENOMEM; goto fail_malloc; } memset(globalmem_devp , 0,sizeof(struct globalmem_dev)); globalmem_setup_cdev(globalmem_devp,0); return 0; fail_malloc:unregister_chrdev_region(devno, 1); return result; } //global设备驱动卸载模块 void globalmem_exit(void) { cdev_del(&globalmem_devp->cdev); //删除cdev结构 kfree(globalmem_devp); unregister_chrdev_region(MKDEV(globalmem_major,0),1); //注销设备驱动区域 } MODULE_AUTHOR("hanyan225"); MODULE_LICENSE("Dual BSD/GPL"); module_param(globalmem_major, int, S_IRUGO); module_init(globalmem_init); module_exit(globalmem_exit);
呵呵,不要迷恋哥,哥其实挺差劲的,过去是,现在还是,希望悲剧的我以后能为一个人人迷恋的传说呵呵..
源码部分算是完了,,下边咱们聊天看MM吧,哦忘了,还有源码部分的讲解没说,唉,为啥一提到这个就心里烦躁呢..哈哈
1)static const struct file_operations globalmem_fops在这个中定义了整个驱动程序的核心操作,以后的应用程序最终都会调用这个结构中定义的操作。
2)在globalmem_init(void)中主要实现了定义和分配字符设备编号
a)当设备编号是手动分配时就调用register_chrdev_region进行字符设备的注册
b)当设备编号不是手动分配时,这时就用调用alloc_chrdev_region动态获得设备编号
3)调用kmalloc(sizeof(struct globalmem_dev),GFP_KERNEL); 向内核申请字符设备结构,并初始化。
4)当上边的一切都完成了,QQ斗地主的家伙们说了N篇:花都谢了,不过没关系不是,我们的工作也完成了,只要再次调用globalmem_setup_cdev向内核注册我们的设备驱动就可以了,现在终于可以放心都地主了..
5)突然老王说,我想玩拖拉机,不是吧,一局那么长,还是等哥把最后一点收拾残局的globalmem_exit写完再说,在这里看着其实挺简单的不是,就是删除设备,释放空间,注销设备驱动编号区域,ok..
老李说,大哥呀,你都在写什么鬼东西,哥怎么一个都看不懂…
哦,不好意思哈,写的有点乱(心里盘算着:这么清晰都看不懂,还哥呀哥的,你倒找我钱让我做哥,我都不好意思),要不我给你实际操作一下吧:
1)cat /proc/devices看看有哪些编号已经被使用,我们选一个没有使用的150,将代码头文件处的
#define GLOBALMEM_MAJOR 254 /*预设的globalmem的主设备号*/中的254换成150
2)make
3)insmod ./globalmem.ko
4)通过"mknod /dev/globalmem c 150 0"命令创建"/dev/globalmem"设备节点。
5)输入echo 'Hello bitch'>/dev/globalmem命令。
6)输入"cat /dev/globalmem"看看终端是否显示Hello bitch,如果是,哈哈,你成功了。
谁是bitch,我咋知道,老李瞪着死鱼眼睛看着我,不知道是程序惊呆了它,还是一句bitch吓蒙了他,不管了,哥的拖拉机火着呢..掀桌子了都..哈哈