Skip to content

第一百四十七章:SCSI

合道期

涉及内核源码:

林小源走出调度广场,面前出现了一条宽阔的大道。大道两侧竖着巨大的路标,路标上统一标注着 "SCSI" 的字样——无论是 SATA 硬盘、SAS 阵列还是 USB 闪存,所有的存储设备都在这条大道上通行。

一个穿着蓝色制服的中年人站在大道中央,手中拿着一本厚厚的登记册。他的制服左臂上绣着三层纹路——上层、中层、下层。

"我是 SCSI 核心。"中年人翻开登记册,"你看到的 /dev/sda、/dev/sdb,都是从我这里登记出去的。"

林小源注意到大道上方悬浮着一块巨大的牌匾,上面写着各种命令:READ(10)、WRITE(10)、INQUIRY、TEST UNIT READY。

"这些命令——所有存储设备都用同一套?"林小源问。

SCSI 核心点了点头:"不管是 SATA 硬盘还是 USB 闪存,到了我这里都说同一种语言。上层的驱动——sd、sr、st——通过我下发命令;下层的适配器驱动通过我接收命令。我就是翻译。"

一个穿着白色长袍的年轻人从大道左侧走来,胸口绣着 "sd" 两个字母。他身后跟着一队排着整齐队列的 SCSI 命令。

"sd 是磁盘驱动,"SCSI 核心介绍道,"你每次读写 /dev/sda,都是 sd 在和我打交道。"

年轻人朝林小源点了点头,然后翻开一本小册子,上面记录着每条 READ(10) 命令的 LBA 地址和传输长度。

"还有 sr——光驱驱动。"SCSI 核心指向大道右侧一个背着圆盘的矮个子,"以及 st——磁带驱动。"远处一个扛着卷轴的老人正在缓慢地走来。

林小源仰头望向大道尽头,那里的路标分成了两条岔路:一条继续通往传统的 SCSI 通道,另一条通往一条更宽、更快的新路,路标上写着 "NVMe"。

"NVMe 不走你这条路?"林小源问。

SCSI 核心的表情有些复杂:"NVMe 有自己的路——专门为闪存设计,延迟更低,并行度更高。但在 Linux 里,很多存储设备还是通过我访问。我老了,但还没退休。"

林小源暗自感叹,搞了半天,SCSI 就是存储世界的通用语言。


c
/*
 * SCSI 子系统:
 *
 *   SCSI 上层: sd (磁盘), sr (光驱), st (磁带)
 *   SCSI 中层: SCSI 核心
 *   SCSI 下层: host adapter 驱动
 *
 * SCSI 命令:
 *   READ(10) — 读取数据
 *   WRITE(10) — 写入数据
 *   INQUIRY — 查询设备信息
 *   TEST UNIT READY — 测试设备就绪
 *
 * SCSI 的意义:
 *   统一的存储接口
 *   支持多种设备
 *   支持多种传输方式
 */

printf("=== SCSI — 存储的通用框架 ===\n\n");

printf("SCSI 子系统:\n\n");
printf("  SCSI 上层:\n");
printf("    sd — 磁盘\n");
printf("    sr — 光驱\n");
printf("    st — 磁带\n\n");
printf("  SCSI 中层:\n");
printf("    SCSI 核心\n\n");
printf("  SCSI 下层:\n");
printf("    host adapter 驱动\n\n");

printf("--- SCSI 命令 ---\n");
printf("READ(10): 读取数据\n");
printf("WRITE(10): 写入数据\n");
printf("INQUIRY: 查询设备信息\n");
printf("TEST UNIT READY: 测试就绪\n\n");

printf("--- SCSI 的意义 ---\n");
printf("统一的存储接口:\n");
printf("  不管底层是什么\n");
printf("  上层都看到 SCSI 设备\n\n");
printf("支持多种设备:\n");
printf("  SATA 硬盘\n");
printf("  SAS 硬盘\n");
printf("  USB 存储\n");
printf("  NVMe (部分)\n\n");

printf("--- /dev/sd* ---\n");
printf("/dev/sda — 第一块 SCSI 磁盘\n");
printf("/dev/sdb — 第二块 SCSI 磁盘\n");
printf("/dev/sda1 — 第一块磁盘的第一个分区\n\n");

printf("--- SCSI vs NVMe ---\n");
printf("SCSI:\n");
printf("  通用存储框架\n");
printf("  支持多种设备\n\n");
printf("NVMe:\n");
printf("  专门为闪存设计\n");
printf("  更低延迟\n");
printf("  更高并行度\n");

林小源跟着 SCSI 核心走进了大道旁的一座三层建筑。建筑内部的结构清晰地分为三层——底层是适配器驱动的工作间,中层是 SCSI 核心的调度大厅,上层是设备驱动的办公区。

"分层是我的立身之本。"SCSI 核心站在中层大厅里,指着脚下的地板和头顶的天花板,"底下的人只管和硬件打交道,上面的人只管和文件系统打交道。两边都不需要知道对方是谁——只要把命令交给我就行。"

林小源走到一个窗口前,看到下层的一个适配器驱动正在把一批 SCSI 命令翻译成 SATA 协议的帧格式,然后通过一条细长的通道发送出去。通道的另一端是一块真正的硬盘。

"如果换了 SAS 硬盘呢?"林小源问。

"换一个适配器驱动就行,"SCSI 核心说,"上层的 sd 驱动什么都不用改。它只看到 SCSI 命令,不关心底层是 SATA 还是 SAS。"

一个穿着灰色工装的适配器驱动从楼下走上来,手里拿着一张新的协议卡:"新到了一批 USB 存储设备,我刚把 USB Mass Storage 的翻译规则配好。"

SCSI 核心接过协议卡看了一眼,点了点头,然后在登记册上添了几行。整个过程行云流水——上层的 sd 驱动甚至没有抬头看一眼。

林小源站在三层建筑的窗口前,若有所思——分层才是通用的根基。

林小源离开 SCSI 大道,走向 NVMe 的新路。新路的路面更加平整,车道也更宽——至少有六十四车道并排。

NVMe 的路标旁站着一个年轻的管理员,穿着银灰色的制服,脸上带着自信的微笑。

"NVMe 是为闪存设计的全新协议,"年轻人说,"SCSI 是为机械盘时代设计的——它的命令队列深度有限,协议开销也大。NVMe 直接走 PCIe 总线,队列深度可以到几万,延迟是 SCSI 的几分之一。"

林小源回头望了望 SCSI 大道。那条路上依然车水马龙——SATA 硬盘、SAS 阵列、USB 闪存,各种设备排着队通过 SCSI 核心的检查站。

"SCSI 会被淘汰吗?"林小源问。

NVMe 年轻人摇了摇头:"在 Linux 里,SG(通用 SCSI 层)仍然覆盖着大量设备。NVMe 很快,但 SCSI 的通用性是它比不了的。两条路会共存很久。"

林小源站在两条路的交叉口,看着新旧两代协议各司其职。SCSI 大道沉稳而包容,NVMe 新路迅捷而专精——它们不是替代关系,而是互补。

新旧两代协议不是替代关系,而是各有所长、长期共存。


道藏笔记

内核启示

SCSI 在 Linux 存储世界里的地位,大概相当于普通话在中国的地位——不管你底层是 SATA 硬盘、SAS 阵列还是 USB 闪存,到了 SCSI 这一层都说同一种语言。它分三层:上层是具体的设备驱动,sd 管磁盘、sr 管光驱、st 管磁带;中层是 SCSI 核心,负责翻译和调度;下层是适配器驱动,跟具体的硬件打交道。分层的好处是换硬件只需换下层驱动,上层代码一行不用改。NVMe 虽然更快更专精,但 SCSI 的通用性短期内没人能替代——两条路会共存很久。


破关试炼

SCSI 之试

磁盘、光驱等块设备常通过哪套分层存储协议进入 Linux 块层?

答对后才能继续滑动和进入下一章。

以修仙之名,悟内核之道