考慮 x86 CPU / LINUX
我想了解cpu或dma如何存取硬碟?
答案1
硬碟上的資料不是實體位址空間的一部分。1 的數據不是記憶體映射的。
例如,SATA 控制器具有 CPU 需要寫入的 I/O 暫存器,並對其進行編程以進行n
從特定磁碟偏移到特定實體記憶體位址的磁區 DMA 傳輸。
這些 I/O 暫存器中的部分或全部可以透過 MMIO(正常載入和儲存到特殊位址)而不是in
/out
連接埠 IO 進行存取。但這仍然只是將所需的命令發送到 SATA 控制器的問題。 (有關詳細信息,請參見https://wiki.osdev.org/AHCI.) AHCI 是最廣泛使用的一種核心 <-> 硬體驅動程式接口,但也存在其他類型(例如,需要自己的驅動程式的高級 RAID 控制器)。
例如我主機板上的 AHCI SATA 控制器,根據lspci -v
:
00:17.0 SATA controller: Intel Corporation Q170/Q150/B150/H170/H110/Z170/CM236 Chipset SATA Controller [AHCI Mode] (rev 31) (prog-if 01 [AHCI 1.0])
Subsystem: ASUSTeK Computer Inc. Q170/Q150/B150/H170/H110/Z170/CM236 Chipset SATA Controller [AHCI Mode]
Flags: bus master, 66MHz, medium devsel, latency 0, IRQ 135
Memory at f7248000 (32-bit, non-prefetchable) [size=8K]
Memory at f724c000 (32-bit, non-prefetchable) [size=256]
I/O ports at f090 [size=8]
I/O ports at f080 [size=4]
I/O ports at f060 [size=32]
Memory at f724b000 (32-bit, non-prefetchable) [size=2K]
Capabilities: <access denied>
Kernel driver in use: ahci
Kernel modules: ahci
這兩個小「記憶體」區域(2k 和 8k)幾乎肯定是 MMIO 端口,但它在 I/O 位址空間中也有一些 I/O 端口。 「不可預取」是暗示;如果讀取有副作用,則必須停用預取。
請注意flags: bus master
.這意味著它可以與主記憶體進行 DMA 傳輸。
但我的 NVMe SSD僅有的有MMIO空間,沒有傳統的I/O埠。
03:00.0 Non-Volatile memory controller: Intel Corporation SSD 600P Series (rev 03) (prog-if 02 [NVM Express])
Subsystem: Intel Corporation SSD 600P Series
Flags: bus master, fast devsel, latency 0, IRQ 16, NUMA node 0
Memory at f7000000 (64-bit, non-prefetchable) [size=16K]
Capabilities: <access denied>
Kernel driver in use: nvme
現代硬碟控制器不會讓 CPU 透過「編程 I/O」一次複製 4 或 8 個位元組的資料。這是經典 IDE / ATA 控制器的選項,但僅作為在用於hdparm
設定 Linux 驅動程式以在預 SATA 上使用 DMA 傳輸時主機板或PCI HD 控制器上發生不良情況(例如鎖定或資料損壞)時的後備方案系統。
顯然,從技術上講,PIO 仍然是 AHCI SATA 控制器的選項。但它從來都不是預設的。與過去硬體很可能損壞的糟糕時代不同,現代作業系統可以放心地期望 DMA 能夠正常運作。
註腳1:除非你的「硬碟」其實是非揮發性 DIMM在記憶體插槽中,例如英特爾傲騰 DC PM,或電池供電的 DRAM)。將最近儲存的資料從回寫式 CPU 快取推送到非揮發性記憶體映射儲存是clflushopt
或等指令的用例之一clwb
。