为什么IO数据需要在用户空间和内核空间之间进行复制

为什么IO数据需要在用户空间和内核空间之间进行复制,io,kernel,Io,Kernel,全部。 我正在学习基本的IO知识,但我对IO数据需要在用户空间和内核空间之间复制感到困惑,为什么? 例如,如果调用read方法从磁盘读取文件。数据首先存储在内核中,然后通知用户进程将数据复制到我的用户空间。为什么它不直接从磁盘读取到我的用户空间?你用什么来学习?硬件通常与对DMA操作进行编程的硬件驱动程序一起工作。SATA/SAS/NVMe驱动程序将通过物理内存地址向hdd/ssd队列发送描述符,描述应读取哪个块以及将其放置在何处。当hdd/ssd搜索数据并进行DMA访问时,这个(物理)内存应该

全部。 我正在学习基本的IO知识,但我对IO数据需要在用户空间和内核空间之间复制感到困惑,为什么?
例如,如果调用
read
方法从磁盘读取文件。数据首先存储在内核中,然后通知用户进程将数据复制到我的用户空间。为什么它不直接从磁盘读取到我的用户空间?

你用什么来学习?硬件通常与对DMA操作进行编程的硬件驱动程序一起工作。SATA/SAS/NVMe驱动程序将通过物理内存地址向hdd/ssd队列发送描述符,描述应读取哪个块以及将其放置在何处。当hdd/ssd搜索数据并进行DMA访问时,这个(物理)内存应该保留在适当的位置,因此它在内核中分配并由内核控制。当数据被复制到物理内存时,内核(VFS)将把它复制到用户空间的virt mem(使用
read
syscall;或者使用
mmap
splice
将它提供给用户)。不信任用户。如何理解“不信任用户”这句话?驱动程序不能要求设备直接从/到用户控制的内存进行DMA。恶意用户(或不正确的程序)可能会在DMA完成之前尝试取消映射这部分内存;或者他可以在设备读取数据之前更改数据。进行DMA的另一个问题是,像PCI这样的老总线是32位的,不能访问机器的所有物理内存:它们只能对phys内存的第一个GB(ISA-16MB)进行DMA,而这部分由内核以不同的方式进行管理(DMA zone-
zone\u DMA
-“能够进行DMA的页面”)@osgx驱动程序不能要求设备直接从/到用户控制的内存进行DMA。一般来说是这样的。然而,为了(过于?)迂腐,直接IO可以直接与映射为用户可寻址页的内存进行DMA,并消除内核和用户空间之间的复制。直接IO通常由自己进行缓存管理的数据库使用(比如Oracle…)。它在流式数据传输中也很有用,因为流式数据处理的数据量太大,无法从页面缓存中重新读取数据。@AndrewHenle,嗯,这个O_DIRECT有时被描述为DMA到用户缓冲区(-)“文件I/O直接到/从用户空间缓冲区进行…注意O_DIRECT标志可能会对用户空间缓冲区的长度和地址以及I/O的文件偏移量施加对齐限制。”)。但直接到用户空间进行DMA时,需要允许硬件访问物理页(它将位于DMA可访问区域,或者需要IOMMU),因此仍然需要锁定用户页面,甚至重新映射它们。