现在的位置: 首页 > 综合 > 正文

linux read调用说明

2017年12月22日 ⁄ 综合 ⁄ 共 1464字 ⁄ 字号 评论关闭

 

大部分程序员可能会有这样的疑问:当在程序中调用库函数 read 时,这个请求是经过哪些

处理最终到达磁盘的呢,数据又是怎么被拷贝到用户缓存区的呢?本文介绍了从 read
系统调用发出到结束处理的全过程。该过程包括两个部分:用户空间的处理、核心空间的处理。用户空间处理部分是系统调用从用户态切到核心态的过程。核心空间处理部分则是
read 系统调用在 linux 内核中处理的整个过程。

 

系统调用在用户空间中的处理过程

Linux
系统调用(SCI,system call
interface)的实现机制实际上是一个多路汇聚以及分解的过程,该汇聚点就是 0x80 中断这个入口点(X86
系统结构)。也就是说,所有系统调用都从用户空间中汇聚到 0x80 中断点,同时保存具体的系统调用号。当 0x80
中断处理程序运行时,将根据系统调用号对不同的系统调用分别处理(调用不同的内核函数处理)。系统调用的更多内容,请参见参考资料。

Read
系统调用也不例外,当调用发生时,库函数在保存 read 系统调用号以及参数后,陷入
0x80 中断。这时库函数工作结束。Read 系统调用在用户空间中的处理也就完成了。

 

系统调用在核心空间中的处理过程

0x80
中断处理程序接管执行后,先检察其系统调用号,然后根据系统调用号查找系统调用表,并从系统调用表中得到处理 read
系统调用的内核函数 sys_read ,最后传递参数并运行 sys_read 函数。至此,内核真正开始处理 read 系统调用(sys_read 是 read
系统调用的内核入口)。

在讲解 read
系统调用在核心空间中的处理部分中,首先介绍了内核处理磁盘请求的层次模型,然后再按该层次模型从上到下的顺序依次介绍磁盘读请求在各层的处理过程。

系统调用在核心空间中处理的层次模型

:对于磁盘的一次读请求,首先经过虚拟文件系统层(vfs layer),其次是具体的文件系统层(例如
ext2),接下来是 cache 层(page cache 层)、通用块层(generic block layer)、IO 调度层(I/O scheduler
layer)、块设备驱动层(block device driver layer),最后是物理块设备层(block device
layer)

  • 虚拟文件系统层的作用:屏蔽下层具体文件系统操作的差异,为上层的操作提供一个统一的接口。正是因为有了这个层次,所以可以把设备抽象成文件,使得操作设备就像操作文件一样简单。
  • 在具体的文件系统层中,不同的文件系统(例如
    ext2 和 NTFS)具体的操作过程也是不同的。每种文件系统定义了自己的操作集合。关于文件系统的更多内容,请参见参考资料。
  • 引入 cache
    层的目的是为了提高 linux 操作系统对磁盘访问的性能。 Cache 层在内存中缓存了磁盘上的部分数据。当数据的请求到达时,如果在
    cache
    中存在该数据且是最新的,则直接将数据传递给用户程序,免除了对底层磁盘的操作,提高了性能。
  • 通用块层的主要工作是:接收上层发出的磁盘请求,并最终发出 IO
    请求。该层隐藏了底层硬件块设备的特性,为块设备提供了一个通用的抽象视图。
  • IO 调度层的功能:接收通用块层发出的 IO
    请求,缓存请求并试图合并相邻的请求(如果这两个请求的数据在磁盘上是相邻的)。并根据设置好的调度算法,回调驱动层提供的请求处理函数,以处理具体的 IO
    请求。
  • 驱动层中的驱动程序对应具体的物理块设备。它从上层中取出 IO 请求,并根据该 IO
    请求中指定的信息,通过向具体块设备的设备控制器发送命令的方式,来操纵设备传输数据。
  • 设备层中都是具体的物理设备。定义了操作具体设备的规范。

 



 

抱歉!评论已关闭.