编写简单的字符设备的驱动由于用户进程是通过设备文件同硬件打交道,对设备文件的操作方式不外乎就是一些系统调用,如open,read,write,close....而这些系统调用通过定义structfile_operations结构体和设备驱动程序相关联。所以,编写设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域。具体步骤如下:①随便在一个目录下,新建一个目录叫mydev,再在此目录下新建三个文件分别叫Makefilemydev.cmain.c。其中Makefile是编译文件,mydev.c是我们编写的字符设备驱动程序,main.c则是用于测试字符设备驱动的测试程序。三个文件的源程序代码详见附录2.②打开终端使用su命令,切换到superuser身份,然后写位到mydev目录下。③输入make命令,编译驱动程序chardev.c。④输入gccmain.c命令,编译测试程序。⑤输入insmodmydev.ko加载驱动模块。⑥输入gedit/proc/devices查看mydev驱动模块的主设备号。⑦输入mknod/dev/mydevc2500在/dev/目录下,创建设备mydev。其中,c代码字符驱动,250是驱动主设备号,0是次设备号。次设备号一般都为0。⑧输入./a.out运行测试程序。⑨测试程序退出后,输入rmmodmydev卸载驱动模块,并输入rm-rf/dev/mydev删除/dev/目录下的mydev设备。其安装过程和运行结果如图3-1~图3-3所示。图3-1查看驱动模块主设备号图3-2创建mydev源代码:Makefileobj-m:=mydev.oKDIR:=/lib/modules/$(shelluname-r)/buildSRCPWD:=$(shellpwd)all:make-C$(KDIR)M=$(SRCPWD)modulesclean:rm-rfchardev.omydev.c#includelinux/kernel.h#includelinux/fs.h#includelinux/module.h#includeasm/uaccess.h#includelinux/cdev.hstaticintmydevread(structfile*filp,char__user*buffer,size_t,loff_t*);staticintmydevopen(structinode*,structfile*);staticintmydevwrite(structfile*filp,constchar__user*buffer,size_t,loff_t*);staticintmydevrelease(structinode*,structfile*);staticintmajor;staticcharbuf[100]=Mydevisworking!;staticconststructfile_operationsfile_ops={.read=mydevread,.write=mydevwrite,.open=mydevopen,.release=mydevrelease};staticint__initmydev_init(void){intresult;major=0;result=register_chrdev(major,mydev,&file_ops);if(result0){printk(registermydevfailed!\n);returnresult;}if(major==0)major=result;return0;}staticintmydevopen(structinode*inode,structfile*file){try_module_get(THIS_MODULE);printk(mydevopencalled!\n);return0;}staticintmydevrelease(structinode*inode,structfile*file){module_put(THIS_MODULE);printk(mydevcleancalled!\n);return0;}staticintmydevread(structfile*filp,char__user*buffer,size_tlength,loff_t*offset){intrd;rd=copy_to_user(buffer,&buf,length);if(rd)returnlength;return-1;}staticintmydevwrite(structfile*filp,constchar__user*buffer,size_tlength,loff_t*offset){intwt;wt=copy_from_user(&buf,buffer,length);if(wt)returnlength;return-1;}staticvoid__exitmydev_close(void){unregister_chrdev(major,mydev);}module_init(mydev_init);module_exit(mydev_close);