如果不了解相关知识,我通常会认为 SATA、SCSI 和 USB 大容量存储由不同的驱动程序驱动。然而在 Linux 中,SCSI 子系统驱动所有这些设备。
为什么 Linux 使用 SCSI 子系统来驱动甚至与 SCSI 不明确相关的东西?为什么 NVMe 和(历史上)PATA 支持不是 SCSI 子系统的一部分?
答案1
如果不了解相关知识,我通常会认为 SATA、SCSI 和 USB 大容量存储由不同的驱动程序驱动。然而在 Linux 中,SCSI 子系统驱动所有这些设备。
嗯,USB 大容量存储实际上是 SCSI在引擎盖下;它使用实际的 SCSI 命令集,只是通过另一种传输。(如果您的磁盘支持 UAS,则更是如此,UAS 代表“USB 连接 SCSI”,但它同样适用于基本的 BOT 存储设备。)这意味着,是的,您的外部 USB-SATA 磁盘外壳正在 ATA 和 SCSI 之间转换命令(对于诸如 SMART 访问之类的东西,使用特殊的“ATA 直通”命令)。
(如果您曾经拥有过 FireWire HDD 或 iPod,那么它们就是 SBP-2 设备,也就是 SCSI。这是一组用途非常广泛的命令。)
SATA 支持通过 SCSI 实现,因为在 SATA 推出时,现有的 Linux PATA 子系统(可追溯到 Linux 的早期)垃圾与强大的 SCSI 子系统相比,SATA 在功能方面已经更接近 SCSI(排队、标记命令等),因此将 AHCI 视为一种奇怪的 SCSI 控制器(带有 SCSI-ATA 转换层“libata”)可能比将其视为一种奇怪的 PATA 控制器提供更好的性能。
(事实上,在 Windows 获得原生 AHCI 支持之前,当时甚至许多 Windows 系统都拥有供应商 SATA 驱动程序,这些驱动程序将 SATA AHCI 控制器呈现为 SCSI 控制器 - 例如,Windows XP 知道 SCSI 但不知道 AHCI。)
此支持使用官方SCSI 到 ATA 的转换这是由负责 SCSI 的 T10 工作组编写的文档,显然大多数(如果不是全部)内容都有 1:1 的转换,所以我认为这并不像看起来那么简单。不过,当时似乎这被认为是一个临时解决方案,计划为 SATA 设备制作一个新的 Linux 子系统,但这从未发生过;我猜“libata”(翻译层)的效果比预期的要好。
(最后需要注意的是,所有 ATA CD/DVD 驱动器都使用“ATAPI”协议 - 即 ATA 数据包内的 SCSI。同样,即使在 Windows 上,您也会看到几乎所有 CD/DVD 刻录软件都将 CD/DVD 驱动器列为 SCSI 设备,因为从某种意义上说它们确实是 SCSI 设备。)
为什么 NVMe 和 PATA 支持不是 SCSI 子系统的一部分?
太平洋亚洲旅游协会支持是部分原因。多年来,即使是 PATA 磁盘也/dev/sd*
通过“libata”SCSI-ATA 转换显示为设备,而不是实际的 PATA/dev/hd*
设备。“传统”PATA 驱动程序在最近几个月已从 Linux 中完全删除,但它们已经很长时间没有使用了。
至于 NVMe,我认为它与 T10 邮件列表消息中提到的有关 SATA 的内容相同,其中一个单独的子系统曾是最终目标……鉴于 NVMe 的设计初衷是作为 ATA 和 SCSI 的后继者几十年后,可能存在太多差异而无法实用,例如与 SCSI 的设计相比,NVMe 允许的极深队列。
也就是说,libata 运行良好是因为 PATA/SATA 是 SCSI 功能的一个子集,而 NVMe 更像是一个超集。
(NVMe 子系统最初确实有类似的 SCSI 转换但最终被删除;提交消息声称部分原因是两者之间存在显著差异。)
答案2
这在 SCSI 接口指南:
尽管旧的并行(快速/宽/超) SCSI 总线已基本不再使用,但 SCSI 命令集比以往更加广泛地用于通过多种不同的总线与设备进行通信。
SCSI 命令可通过几乎任何类型的总线传输,并且是连接到 USB、SATA、SAS、光纤通道、FireWire 和 ATAPI 设备的存储设备的默认协议。SCSI 数据包也通常通过 Infiniband、I20、TCP/IP (iSCSI) 甚至并行端口进行交换。
原因是,SCSI 子系统用于掌握所有类型总线上的通用 SCSI 协议,因此主要不是用于控制 SCSI 设备。
有关 SCSI 接口的更多详细信息,请参见上述文章。一般系统结构描述如下:
SCSI 子系统采用三层设计,即上层、中层和下层。涉及 SCSI 子系统的每个操作(例如从磁盘读取扇区)都使用这三个层级中的一个驱动程序:一个上层驱动程序、一个下层驱动程序和 SCSI 中间层。
SCSI 上层以块和字符设备节点的形式提供用户空间和内核之间的接口,用于 I/O 和 ioctl()。SCSI 下层包含特定硬件设备的驱动程序。
中间层是 SCSI 中间层,类似于 IPv4 堆栈等网络路由层。SCSI 中间层在上层的 /dev 节点和下层的相应设备之间路由基于数据包的数据协议。它管理命令队列、提供错误处理和电源管理功能,并响应 ioctl() 请求。
正是较低层驱动程序使得 SCSI 子系统能够与多种类型的总线和设备连接。
PATA 现已过时,SATA 是大多数消费级存储设备的标准。NVMe 用于提高性能,尤其是 SSD。SCSI 仍用于专门的企业环境,以实现兼容性和其高级功能。
答案3
“SCSI” 是相关分层协议和定义系统的总称。SCSI 指定了从连接器和电缆的物理尺寸、线路上的电压和电流、时钟机制、线路上的协议到设备可以理解的命令等所有内容。
显然,连接器、电缆、电气规格和线路协议如今已经过时了,而且已经过时很长时间了。
然而,命令仍然存在。操作系统不关心插头的大小、电线上的电压或数据在电线上的编码方式,它仅有的关心它发送给设备的命令。因此,只要设备“理解” SCSI 命令,从操作系统的角度来看,它就是 SCSI 设备。操作系统不知道设备如何连接到系统,它只知道设备使用的“语言”。
与其竞争对手(最著名的是 ATA)相比,SCSI 一直是“更专业”、“更强大”、“更成熟”的替代方案,因此许多新技术直接采用 SCSI 命令而不是费力创建自己的命令是有道理的。
最早推出的 CD 驱动器价格高得离谱,而且是为 Unix 工作站设计的,所以自然是 SCSI 驱动器。当第一台 ATA CD 驱动器问世时,ATA 人员并没有重新发明 SCSI 人员所做的一切,而是发明了异步串行接口, 这ATA 数据包接口,这只不过是一种通过 ATA 传输 SCSI 命令的方式。
当 ATA 硬盘获得更多“专业”功能(如自我监控、加密、命令排队)时,ATA 人员并没有孤军奋战,而是从 SCSI 功能中汲取了大量灵感。
当 Firewire 推出时,他们选择对外部驱动器使用 SCSI 命令。当 USB 推出时,他们也做了同样的事情。
有趣的是,另一个方向也存在技术转移:SAS 协议以及电气和物理接线主要基于 SATA。
当 CD-ROM 被引入 Linux 时,它们是基于 SCSI 子系统的,这导致了一种有趣的情况:连接到同一根电缆的硬盘和 CD-ROM 会出现在两个不同的子系统中。
当 USB 和 Firewire 推出时,它们自然使用了 SCSI 子系统。
因此,当 SATA 被引入 Linux 内核时,决定以更清晰、实现更好的 SCSI 子系统为基础,而不是老旧、笨拙的 ATA 子系统。
并且在某个时候,决定将 PATA 硬盘也移至 SCSI 子系统。
为什么Linux SCSI子系统驱动硬件与SCSI没有明显的关系?
窃取问题下的评论:因为它们与 SCSI 相关,就在不明显的方式。
它们都使用 SCSI 命令,从操作系统的角度来看,这是唯一相关的。
为什么 NVMe 和(历史上) PATA 支持不是 SCSI 子系统的一部分?
NVMe 专门设计用于不像传统存储命令 API,因为闪存与传统旋转硬盘或磁带非常不同。
对于 PATA 来说,这是历史原因。如果真正的原因仅仅是 Linus 1991 年的计算机没有 SCSI 磁盘,所以 PATA 子系统首先出现,我不会感到惊讶。在引入 SATA 支持后,PATA曾是确实转移到了 SCSI 子系统。