设备驱动程序实质上是提供一组供应用程序操作设备的接口函数。 各种设备由于功能不同,驱动程序提供的函数接口也不相同,但linux为了能够统一管理,规定了linux下设备驱动程序必须使用统一的接口函数 file_operations 。 所以,一种设备的驱动程序主要内容就是提供这样的一组file_operations接口函数。 那么,linux是如何管理种类繁多的设备驱动程序呢? linux下设备大体分为块设备和字符设备两类。 内核中用2个全局数组存放这2类驱动程序。 #define MAX_CHRDEV 255 #define MAX_BLKDEV 255 struct device_struct { const char * name; struct file_operations * fops; }; static struct device_struct chrdevs[MAX_CHRDEV]; static struct { const char *name; struct block_device_operations *bdops; } blkdevs[MAX_BLKDEV]; //此处说明一下,struct block_device_operations是块设备驱动程序内部的接口函数,上层文件系统还是通过struct file_operations访问的。 哈哈,现在明白了吧?你的驱动程序调用 int register_chrdev(unsigned int major, const char * name, struct file_operations *fops) 就是将你提供的接口函数fops存放到chrdevs[MAX_CHRDEV]这个数组中,数组下标就是你的驱动的主设备号,数组内容包括驱动名称和驱动接口函数,这样,内核就能看到你的驱动程序了。BTW,如果你将major设为0,系统会自动给你分配一个空闲的主设备号。 那么?次设备号呢?别急,马上就出现了:) 二、设备节点如何产生? 驱动程序运行在内核空间,应用程序访问驱动程序通常是通过系统调用文件系统接口函数的,也就是说,在linux下,和磁盘文件一样,设备也是文件,只是他们的文件属性不同而已,应用程序只能通过文件名来访问设备的驱动程序。 所以,文件系统中必须要有一个代表你的设备的文件,应用程序才能访问你的设备驱动程序。 为了便于理解,我们可以将设备文件换个名字,叫做设备节点。 设备节点在哪里?设备节点存在于你的文件系统中,通常在/dev目录下,当然,你也可以在其它地方创建。一般说来,我们在制作文件系统映像时就已经将可能用到的设备节点都创建好了。 你可以打开/dev目录看一下,它下面的设备节点的数量会让你吃惊的:) 如何创建设备节点?。 你可以用mknod命令。如使用以下命令可以创建一个mtd4的字符设备节点。 Mknod /dev/ mtd4 c MTD_CHAR_MAJOR 4 我们创建一个普通的磁盘文件,它的内容是我们写入的数据。 那么设备节点的内容是什么?设备节点文件没有数据,它的文件大小为0,它只有文件属性,包括设备类型、主设备号、次设备号。 没有别的了?对,就这些,没别的了。 那设备节点和设备驱动程序是怎么联系起来的啊? 别着急,休息,休息一会儿:)顺便加下我的QQ:754634522 三、应用程序是如何访问设备驱动程序的? 举个例子:我们要向nor flash的第四个分区的起始位置偏移512字节写入100字节的数据。 我们是如何做的?主要程序片断如下: fd = open(“/dev/mtd4”, O_RDWR); lseek (fd,512, SEEK_SET); write (fd , write_buffer, 100); close(fd); 上面的代码比较简单,但是似乎没有看到我们的应用程序是如何调用到驱动程序的。 没关系,接下来我将带领你们走通这条道路。 应用程序调用Open函数,这是个系统调用函数,程序会进入内核空间调用sys_open函数。 在sys_open,首先会根据文件路径“/dev/mtd4”找到这个文件节点,这部分工作是属于VFS(虚拟文件系统)的。 “/dev/mtd4”的文件属性是字符设备,于是sys_open会调用函数chrdev_open(),在这个函数里有一句话: filp- |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|