在低级别上,如何处理C文件I/O操作?

3

为了拓展题目,我想知道操作系统如何处理fwrite、fread、fopen和fclose等函数。

实际上,什么是流?

如果我表述不够清晰,请原谅。

顺便说一句,我正在使用GNU/Linux Ubuntu 11.04。

更好地解释一下我的问题。

我想知道文件如何被写入硬盘,如何被读入内存,并且后来如何创建对它们的处理。BIOS通过驱动程序完成这个过程吗?


操作系统将会把此调用传递给一个实现文件系统驱动的程序,该程序再将其传递给底层存储设备的驱动程序。 - Santa
1
你能提供更多关于你所寻找的内容的细节吗?你试图解决什么问题?你想知道在哪里可以找到fwrite和相关函数的Linux源代码吗?你对fwrite的实现有具体的问题吗?你是在嵌入式系统上吗? - Rian Sanderson
@Santa。底层存储设备的驱动程序是什么? - user744186
2个回答

8
C库接收像fopen这样的函数,并将其转换为适当的操作系统系统调用。在Linux上,这是POSIX的open函数。您可以在Linux终端中使用man 2 open查看其定义。在Windows上,调用将是CreateFile,您可以在MSDN文档中看到它。在Windows NT上,该函数又是实际NT内核函数NtCreateFile的另一个翻译。
C库中的流是存储在FILE结构中的信息集合。这通常是操作系统文件的“句柄”,分配为“缓冲区”的一块内存区域和当前读写位置。
我刚才注意到您标记了这个问题为“汇编语言”。那么您可能想了解更低层次的细节。这篇文章似乎不错。 现在您已经将问题更改为询问“甚至更低的层次”。好吧,一旦操作系统得到打开文件的命令,它就将该命令传递给VFS(虚拟文件系统)。操作系统的这一部分查找包括所需目录的文件名,并执行必要的访问检查。如果这在RAM缓存中,则不需要磁盘访问。如果不是,则VFS会向特定的文件系统发送读取请求,该文件系统可能是EXT4。然后,EXT4文件系统驱动程序将确定该目录位于哪个磁盘块中。然后,它将向磁盘设备驱动程序发送读取命令。
假设磁盘驱动程序是AHCI,则它将将读取块的请求转换为一系列寄存器写入,以设置DMA(直接内存访问)请求。这似乎是一些细节的好来源。 此时,主板上的AHCI控制器接管了。它将与硬盘控制器通信,协作读取数据并将其写入DMA内存位置。
在此过程中,操作系统将进程暂停,以便可以继续进行其他工作。硬件正在处理事情,CPU不需要关注。磁盘请求将花费许多毫秒,在此期间CPU可以运行数百万条指令。
当请求完成时,AHCI控制器将发送中断。系统CPU之一将接收中断,查看其IDT(中断描述符表),并跳转到该位置的机器代码:中断处理程序。
操作系统中断处理程序将读取一些数据,发现它被AHCI控制器中断,然后跳转到AHCI驱动程序代码。AHCI驱动程序将读取控制器上的寄存器,确定读取已完成,在其操作队列中放置一个标记,告诉操作系统调度程序需要运行,然后返回。此时不会发生其他任何事情。
操作系统会注意到需要运行AHCI驱动程序的队列。当它决定这样做时(可能正在运行实时任务或正在读取网络数据包),它将从标记为DMA的内存块中读取数据,并将该数据复制到EXT4文件系统驱动程序中。然后,该EXT4驱动程序将数据返回给VFS,VFS将把数据放入缓存中。VFS将向操作系统文件句柄返回open系统调用,该调用将返回给fopen库调用,该调用将将其放入FILE结构并将指针返回给程序。

操作系统中的文件概念是什么?操作系统如何处理文件。普通用户将其视为文件,而我则将其视为字符串。 - user744186
谢谢。刚刚添加这个以适应15个字符的限制。 - user744186
很好的答案,我只是想知道,当CPU接收到中断时,操作系统运行的IDT(中断描述符表)条目是否取决于设备?还是只会解除其阻塞以便驱动程序执行其工作? - fredcrs
1
@fredcrs:设备可以共享中断,这使得系统必须检查该中断上的每个设备。更现代化的系统摆脱了这种情况,从而节省时间。实际运行的代码取决于驱动程序。 - Zan Lynx

0

fopen等通常是基于特定操作系统的系统调用实现的。在Unix上,这意味着使用文件描述符的API:open、read、write、close和其他一些API。在Windows上,则是CreateFile、ReadFile等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接