210学习日记(17)_IIS驱动框架

来源:互联网 发布:mysql安全配置 编辑:程序博客网 时间:2024/05/22 23:31

210学习日记(16)

--原来我误会IIS总线驱动了

以前一直认为声卡的驱动程序的框架是多么的复杂,可是当我再次看完相关视频和自己分析了一下框架,发现和写裸板的差不多。

声卡驱动程序框架:(linux-2.6.22\sound\sound_core.c)

注意:sound_core.c在声卡驱动中扮演的角色和input.c在输入子系统中扮演的角色一样!!

static const struct file_operations soundcore_fops=

{

/* We must have an owner or the module locking fails */

.owner = THIS_MODULE,

.open = soundcore_open,

};

static int __init init_soundcore(void) //入口函数

{

if (register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops)==-1) //符合写字符驱动第3步 

sound_class = class_create(THIS_MODULE, "sound"); //创建类

}

=================================================================================

app:open (应用程序使用open函数,内核就创建一个struct file结构,并初始化f_op = input_fops,等)

-----------------------------------------------------------------------------------------------------------------------------------------

.open = soundcore_open (最终会调用到驱动程序sound_core.copen函数)

=================================================================================

问:当看上面的file_operations结构体的时候,发现里面只有一个open函数?那是怎么来实现                 一系列的其他的操作的呢(读,写...?

答:可以猜测出,一定是在这个open函数里面做了一些设置,然后在新的设置里面来进行相关的操作。

int soundcore_open(struct inode *inode, struct file *file)

{

int unit = iminor(inode); //以次设备号为下标

const struct file_operations *new_fops = NULL; //定义一个新的file_operations结构体指针

s = __look_for_unit(chain, unit); //从chains数组里得到一个声音单元,具体分析见下面!!

if (s)

new_fops = fops_get(s->unit_fops);//如果以上的声音单元存在,就构造一个新的                                                  //file_operations结构体

if (new_fops) {

file->f_op = new_fops; //重新初始化struct file结构中的成员f_op,让它指向新的file_operations

if(file->f_op->open) //如果新的file_operations结构体有open函数

err = file->f_op->open(inode,file); //则调用它的open函数

}

}

static struct sound_unit *__look_for_unit(int chain, int unit)

{

struct sound_unit *s; //定义一个声音单元指针

s=chains[chain]; //chains数组中得到一个声音单元

return s; //返回该声音单元

}

问:从分析以上open函数时,发现会从一个chains数组中来获取一个声音单元,进而获取他的成员fops(即新的file_operations结构体),从而构建出了一个新的file_operations结构体,那么上述chains数组是由谁来设置的呢?

答:发现chains是一个静态变量,所以它只能被本程序中的某一个函数来设置,经收索最终发现,它在驱动函数中的register_sound_dsp()函数和register_sound_mixer()函数中被设置!这两个函数的具体分析如下:

函数一:

int register_sound_dsp(const struct file_operations *fops, int dev)

{

/*把file_operations结构体放到数组chains[3]中去,即最终会创建一个设备节点/dev/dsp*/

return sound_insert_unit(&chains[3], fops, dev, 3, 131,"dsp", S_IWUSR | S_IRUSR, NULL);

}

static int sound_insert_unit(struct sound_unit **list, const struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode, struct device *dev)

{

device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor),s->name+6); //创建设备节点

}

函数二:

int register_sound_mixer(const struct file_operations *fops, int dev)

{

/*把file_operations结构体放到数组chains[0]中去,即最终会创建一个设备节点/dev/mixer*/

return sound_insert_unit(&chains[0], fops, dev, 0, 128,"mixer", S_IRUSR | S_IWUSR, NULL);

}

static int sound_insert_unit(struct sound_unit **list, const struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode, struct device *dev)

{

device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor),s->name+6); //创建设备节点

}

问:经过以上的分析,register_sound_dsp()register_sound_mixer()函数会去设置chains数组,那么这两个函数又由谁来调用呢?即它的参数由谁来传入?

答:register_sound_dsp()register_sound_mixer()函数会被我们自己写的声卡驱动来调用!!

注意:

/dev/dsp   :用于播放或者录音

/dev/mixer :用于调整音量

经过重重解析,最终发现,还是回到了写file_operations结构相关上面来了,因此,只要你会ioremap(),就可以像写裸板驱动那样讲声卡驱动给写出来。

注:

如有问题,请到韦东山LINUX视频讨论群里面,我们一起讨论学习,或者加我QQ317312379