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