linux系统中读写流程

来源:互联网 发布:安徽航信网络发票2.0 编辑:程序博客网 时间:2024/06/06 01:50

下面根据我自己的理解,以读过程为例,简要的描述一下应用程序和硬件块设备之间进行数据交换的流程。
首先,应用程序调用库函数fread或者直接调用read系统调用产生读请求,在这里读请求可以理解成需要从文件的某个偏移处读取多长的数据到用户的缓冲区中。上面的两个函数会调用sys_read进入到内核中,从这里开始进程在系统空间中运行。sys_read又会调用具体的文件系统注册的函数对请求进行处理,首先查看请求对应的数据是否在该文件的PAGE CACHE中存在,如果请求的数据已经在PAGE CACHE中,则直接将数据返回给用户空间的缓冲区中,这次请求结束。如果不再PAGE CACHE中,文件系统将经过处理后的请求封装成bio请求格式,发送到块层。bio请求包括读请求的逻辑扇区地址(LBA),读到内存的地址和长度(可能包含多个内存片段)。块层首先查看该bio请求是否能合并到请求队列的某个请求中,若能则合并请求,若不能则为该bio生成一个新的request请求经过重排序后加入到请求队列中。到这里,请求已经到了请求队列中,等待进一步的处理。操作系统的后台线程会定期(还有其他可能触发的条件)的从请求队列中取下请求交给SCSI子系统进行处理,包括调用SCSI上层的块设备驱动准备SCSI命令、准备用于DMA的聚散列表等,最后通过SCSI底层也就是底层驱动将命令发送到设备端。底层驱动往往是通过PIO的方式写设备端的寄存器将命令发送下去,或者将命令的地址写到设备的某个寄存器中,设备再通过DMA的方式从该地址把命令读下去。最终的结果是命令在设备端被解析、执行,然后设备将读取的数据通过DMA的方式写到主机端内核缓冲区或者直接到用户空间缓存(聚散DMA方式),并通过中断的方式通知主机请求执行完成。在中断服务程序中会唤醒之前在该数据上等待的进程继续执行。这样整个请求处理结束,fread或者read函数执行完成,应用程序继续往下执行。
写过程与上门的流程基本类似,不太多说。

0 0