我非常清楚地理解 CPU 指示 DMA 从硬盘获取数据并将其加载到 RAM 中。
尽管我是一名.Net 开发人员,并且在日常工作中不需要这些,但我仍然不愿意使用一些我不了解(但不是太深)的东西来达到我自己可以实现的程度。
DMA 的具体输入是什么?
但是CPU如何知道要读取硬盘上的哪个内存地址以及读取多长的长度呢?
是否有任何 CPU 指令可以读取“气缸盖扇区 ID”,例如 readhdd“sector_id”?
如果文件有分区或者有错误扇区,DMA 如何知道这一切?
硬盘中是否有一个单独的嵌入式程序来解决这个问题?
在这张图片中,OS Filesystem 位于哪里?
请提供 CPU 从磁盘读取文件的工作流程。
答案1
我回答这个问题是因为当我刚开始学习计算机的时候,我就想知道磁盘地址是否会被加载到 CPU 寄存器中以读取磁盘扇区?如果是这样,因为寄存器是 32 位的,我们如何读取大于 4GB 的磁盘?我一直没有得到答案,然后我就忘了,直到我看到这个问题。当时磁盘读写过程对我来说太神秘了。
我理解的程度还没有达到(但也不是太深)可以自己实现的程度。
你永远无法实现它,因为它太复杂了。如果你无法实现它,你为什么不感觉良好呢?如果你无法实现 Linux/Windows,你会感觉糟糕吗?
DMA 的具体输入是什么?
命令通知 DMA 执行某些操作,主要是 IO 读/写操作。在高层,命令由内核中的某些函数发送;在低层,命令是写入 DMA 控制器寄存器的数据,这些寄存器通常包含指向包含实际命令的某些内存的指针。
但是CPU如何知道要读取硬盘上的哪个内存地址以及读取多长的长度呢?
是否有任何 CPU 指令可以读取“气缸盖扇区 ID”,例如 readhdd“sector_id”?
这里的“内存地址”令人困惑,应该是“磁盘地址”。而且执行磁盘读取任务的是软件,而不是 CPU,CPU 只执行软件中的指令。因此,没有 CPU 指令,因为 CPU 不执行此操作。CPU 只能读取/写入内存位置,包括上述 DMA 控制器寄存器和内存中的命令。
如果文件有分区或者有错误扇区,DMA 如何知道这一切?
DMA 不知道也不关心这一点。CPU 读写内存,DMA 执行 CPU 提供的命令。这些命令只是从某处读取内存并将其写入另一个地方。高级软件——文件系统代码处理文件的分区。如果有错误的扇区,硬盘会将此情况报告给系统,不再有针对该错误数据的 DMA 传输。
硬盘中是否有一个单独的嵌入式程序来解决这个问题?
硬盘中有非常复杂的嵌入式程序。实际上可能会有 DMA 操作将磁盘数据从磁盘磁头传输到硬盘上的内存(例如 64MB 缓存),其命令由硬盘上的 CPU 发送到硬盘上的 DMA 控制器,这两个控制器都位于磁盘控制器芯片(Agere 等)中。然后该 CPU 进行一些处理,例如 IO 队列管理/错误检查,然后主机 CPU/南桥中的 DMA 将处理后的扇区数据从磁盘缓存传输到主机上的主内存。
在这张图片中,OS Filesystem 位于哪里?
文件系统与此图无关。文件系统是关于在磁盘的哪个位置进行读写的,而此图是关于读写的过程的。
请提供 CPU 从磁盘读取文件的工作流程。
再次强调,CPU 不会读取文件,软件会读取。基本上,文件系统软件将文件读取操作(例如从 d:\1.txt 开头偏移 10000 字节处读取 100 字节)转换为硬盘扇区读取命令(例如读取从第 20 柱面第 2 扇区第 200 扇区开始的 10 个扇区),这些扇区读取命令被发送到硬盘的控制芯片,然后控制芯片上的 CPU 根据命令读取扇区,然后将扇区数据发送回主机系统并报告操作过程中的任何错误。实际过程将复杂得多,以获得高性能(低 CPU 利用率/高读取带宽/低延迟等)。
实际上 DMA 与磁盘读取无关,您可以在没有 DMA 的情况下读取磁盘,并且可以使用 DMA 执行大多数内存块读写任务。DMA 只是将重复的块内存读写任务从 CPU 卸载,这些任务最好由硬件来完成,而不是 CPU,因为 CPU 的周期对于更复杂的任务来说非常宝贵。