读书人

字符设备驱动懂得

发布时间: 2012-11-26 11:48:50 作者: rapoo

字符设备驱动理解
设备驱动的含义 C库中通过open/read/write/seek等来操作文件,所谓字符设备驱动,简单来说就是实现这几个函数的具体内容,linux能把设备抽象为文件,用户调用open/read/write/seek对抽象的文件进行操作就可以操作实际硬件设备(或抽象的设备)。所以字符设备驱动的重点,在于编写内核空间的open/read/write/seek等函数。 可见,字符设备并不是一个完整的main函数,其框架更像是一个支持fileOperations的lib。用户空间通过系统调用(int 80,软中断)来使用这个lib,lib之间的调用通过内核符号表来完成解析。
内核编程与驱动开发的关系 驱动开发是内核编程的一种,内核编程包括的范围很大(文件系统,内存管理,源码修改)。
字符设备驱动框架(1)init、exit函数,供模块加载(初始化)、卸载(扫尾工作)使用;(2)file operations: open/read/write/seek/ioctl等;


框架加载流程

(1)动态分配主设备号(标识驱动),从设备号(标识设备);(2)字符设备(struct cdev)空间分配(cdev_alloc);(3)字符设备cdev_init,与file operation关联;(4)添加字符设备(cdev_add)。
通过insmod具体过程理解字符设备(1)分配内存空间,加载字符设备驱动正文;(2)通过内核符号表解析正文;(3)调用module_init宏指定的init函数(init完成后就将init函数扔掉,释放部分内存)。
重要结构:(1)struct file_operations: open/read/write/seek/ioctl等(2)struct file(文件描述符):*f_op(即file_operations), *private_data(各file_operations间交互中介)(3)struct inode(表示文件节点):节点号,uid,gid,引用计数(4)struct cdev(表示字符设备):设备号,file operation
示例代码1:字符设备驱动模块程序(c语言)
ybde @ubuntu:~/Test/Driver/ch3/chardd$ sudo insmod chardd.ko ybde @ubuntu:~/Test/Driver/ch3/chardd$ mknod /dev/chardd c 250 5ybde: "/dev/chardd": 权限不够ybde @ubuntu:~/Test/Driver/ch3/chardd$ sudo mknod /dev/chardd c 250 5ybde @ubuntu:~/Test/Driver/ch3/chardd$ cd main/(main中为测试代码)ybde @ubuntu:~/Test/Driver/ch3/chardd/main$ gcc main.c ybde @ubuntu:~/Test/Driver/ch3/chardd/main$ ./a.out fp is -1write return : -1read return : -1read data:ybde @ubuntu:~/Test/Driver/ch3/chardd/main$ sudo ./a.out fp is 3write return : 0read return : 0read data:hello kernel device driver!ybde @ubuntu:~/Test/Driver/ch3/chardd/main$ 

注意:1、insmod后的驱动模块,可以cat /proc/devices查看到,但只有/dev/中出现,用户程序才好open这个设备,怎么让/dev/中也出现设备呢?【解答】 $ mknode /dev/mydev c majorDeviceNum minorDeviceNum
2、应用程序中不能使用字符设备,比如open出错,【解答】可能是权限问题,sudo ./a.out就能正确
3、可以通过strace来查看程序执行所调用过的所有系统调用,以及它们的返回值等执行状态【例如】$ strace ./a.out...open("/dev/chardd", O_RDONLY) = 3
...write(3, "hello kernel device driver!\0", 28) = -1 EBADF (Bad file descriptor)...可发现write报错Bad file descriptor,再往上看,open返回的文件描述符是3,也没错啊。但是,open的文件模式是readonly,肯定不能write的,改成O_RDWR就好了。
4、多个字符设备重名怎么办(cat /proc/devices下的名字)【解答】只要设备号不同就没关系,用户空间要打开的都是mknode到/dev/中的,mknode就指定了设备号
5、需考虑并发,一般在write中做内存管理

参考:[1] LINUX设备驱动程序,第三版[2] http://tieba.baidu.com/f?kz=820619489,提纲挈领的讲述了dirver与os间的联系[3] 本文源码包,含makefile,已编译通过 http://download.csdn.net/detail/ybdesire/4808652

读书人网 >其他相关

热点推荐