gzyueqian
13352868059

linux基础入门教程之字符设备驱动框架分析(以系统调用open为例)

更新时间: 2018-12-27 13:51:46来源: 粤嵌教育浏览量:5052

学习linux基础入门教程,Linux把设备纳入文件系统的范畴来管理。每个设备在Linux系统上看起来都像一个文件,它们存放在/dev目录中,称为"设备节点"或“设备文件”。

每当用户程序要访问某个设备时,通过系统调用,内核根据设备结点的信息调用相应的驱动程序。当驱动程序执行完后,又返回至用户进程。 


应用层与驱动层层次结构框图


每一个字符设备都有自己的底层操作函数;也就是说每一个设备都对应着自己的file_operations结构体;

那么打开的文件file->f_op指针应该指向那一个file_operations结构体呢?或者说 file->f_op怎样找到对应的file_operations呢?

这跟打开的设备文件里面的信息有关。

通过分析字符设备的代码来了解其核心过程

-字符设备的源码在文件 fs/char_dev.c中,包括设备号申请函数,cdev注册函数都在这个文件里面实现。

申请设备号的过程分析

-设备号的注册或自动分配函数是下面两个

alloc_chrdev_region()

register_chrdev_region()

-两个函数都会调用__register_chrdev_region()函数;这个函数完成如下操作:

如果是自动分配设备号

在全局数组chrdevs[ ]中找到一个空位,这个空位的数组下标就是主设备号;设置这个空位。

如果是直接注册设备号

以主设备号为下标,找到数组chrdevs[ ]中的成员,设置这个成员;

-全局数组chrdevs[]当前的成员数为255,下标从0-254,也就是说,当前内核的字符设备主设备号范围 0-254.

 

注册cdev分析

-cdev结构的注册分两步,步是初始化cdev结构;第二步是注册。cdev_add()函数分析如下:



内核使用一个数据结构cdev_map来记录系统中所有的字符设备(cdev;

设备号的维护是由全局chrdevs[]来完成的;

在驱动模块入口函数中:

-申请设备号:就是在数组chrdevs[]中找一个空位;

-注册字符设备:就是将cdev添加到cdev_map中;

 

字符设备注册过程如下图:



linux基础入门教程:open系统调用分析

-open系统调用的实现在fs/open.c文件中



do_filp_open()函数经过重重调用,会调用vfs_select_inode 和do_dentry_open

do_filp_open()

path_openat

do_last

vfs_open

inode = vfs_select_inode  //获取文件的inode信息

do_dentry_open

//inode->i_fop拷贝给f->f_op

f->f_op = fops_get(inode->i_fop);

 

//调用inode->i_fop->open

open = f->f_op->open;

open(inode, f);

 

inode对应一个文件;我们在创建一个设备文件时,就是创建一个inode;

在用户空间创建设备文件时,对应的inode->i_fop指向fs/char_dev.c中的def_chr_fopsdef_chr_fops的成员open指向chrdev_open()函数。

 

open系统调用的层次如下



chrdev_open函数分析



open系统调用的总体过程如下图:

 


从上面分析字符设备的框架我们可以得出以下结论:

编写字符设备驱动程序的流程如下:

编写底层操作函数

在全局数据结构chr_devs中找到一个空位;(申请设备号)

将底层操作函数的集合填到cdev_map结构中;(注册cdev)

以上就是粤嵌linux基础入门教程之字符设备驱动框架分析,欢迎大家来粤嵌一起学习交流。


免费预约试听课