Linux应用程序访问驱动程序过程

当应用程序有访问字符设备或者说有访问字符设备驱动程序需求的时候,主要是通过系统调用达到这一目的的。例如,应用程序读取设备,应用程序使用read函数,read函数通过系统调用通过内核,使得驱动程序中的设备方法xx_read被调用。然后xx_read取数据通过相反路径将数据返回给read系统调用。那么内核中到底做了什么样的处理的呢?

         首先,read位于用户空间,read的实现代码位于内核中,read函数是如何找到内核中的实现代码的呢?静态链接编译read.c,然后反汇编,查看反汇编,发现其调用_libc_read,分析_ibc_read,主要关注两行代码,把3传到r7中去,然后调用SVC指令。SVC称为系统调用指令,当使用这个指令之后,pc指针会从用户空间进入内核空间,而且入口是固定的。然后内核会去取num=3的read的系统调用编号,然后根据num=3查表,查出内核中对应read系统调用的sysread,也就是sysread就是read系统调用再内核中的代码,然后sysread就被调用。可以通过查看内核代码entry-common.S\arch\arm\kernel来验证。

          ENTRY(vector_swi)就是对应的入口函数,然后注释中的Get the system call number就是获取系统调用的编号,接下来查表,继续往下浏览代码,找到sys_call_table,搜索一下,ENTRY(sys_call_table),由于发现其包含call.S文件,打开这个文件,查看表,通过3这个编号,找到了CALL(sys_read)函数。

          其次,分析sys_read函数是如何实现的。直接查找此函数,不好找,它隐藏在read_write.c中,打开后,宏SYSCALL_DEFINE3(read,unsigned int fd,char _user*,buf,size_t,count)   加上()中的这些参数其实就变成了一般的函数。这也就是sys_read的实现代码。sys_read中调用vfs_read函数,此函数又会根据设备的file结构,取到file结构中的struct file operation(struct file operation是编写驱动程序的时候赋值给我们的设备文件的),struct file operation中调用xx_read,调用的代码就是ret=file->f_op->read(file,buf,count,pos)

          总结,应用层read--->入口--->取num--->查表。查表-->sys_read--->vfs_read--->file-->struct file operation--->xx_read.

你可能感兴趣的:(★Linux系统及应用开发)