设为首页 加入收藏

TOP

Linux工作原理3设备(七)
2023-07-23 13:29:49 】 浏览:103
Tags:Linux 设备
能与磁盘和其他设备通信。通常情况下,计算机向主机适配器发送SCSI命令以转达给设备,而设备则通过主机适配器转达响应。
较新版本的SCSI,如串行连接SCSI(SAS),提供了卓越的性能,但你可能不会在大多数机器中找到真正的SCSI设备。你会更经常地遇到使用SCSI命令的USB存储设备。此外,支持ATAPI的设备(如CD/DVD-ROM驱动器)使用SCSI命令集的一个版本。
SATA磁盘也作为SCSI设备出现在你的系统上,但它们略有不同,因为它们中的大多数是通过libata库中的转换层进行通信的(见3.6.2节)。一些SATA控制器(特别是高性能的RAID控制器)在硬件中进行这种转换。
这一切是如何组成的?考虑一下下面系统中显示的设备:

$ lsscsi
[0:0:0:0]diskATAWDC WD3200AAJS-201.0/dev/sda
[1:0:0:0]cd/dvdSlimtypeDVD A DS8A5SHXA15/dev/sr0
[2:0:0:0]diskUSB2.0CardReader CF0100/dev/sdb
[2:0:0:1]diskUSB2.0CardReader SM XD0100/dev/sdc
[2:0:0:2]diskUSB2.0CardReader MS0100/dev/sdd
[2:0:0:3]diskUSB2.0CardReader SD0100/dev/sde
[3:0:0:0]diskFLASHDrive UT_USB200.00/dev/sdf

方括号内的数字从左到右分别是SCSI主机适配器号、SCSI总线号、设备SCSI ID和LUN(逻辑单元号,是设备的进一步细分)。在这个例子中,有四个连接的适配器(scsi0、scsi1、scsi2和scsi3),每个都有个总线(都是总线号0),每个总线上只有一个设备(都是目标0)。位于2:0:0的USB读卡器有四个逻辑单元,但每一种闪存卡都可以被插入。内核给每个逻辑单元分配了一个不同的设备文件。
尽管不是SCSI设备,NVMe设备有时会在lsscsi输出中显示出N作为适配器编号。
注意:如果你想自己尝试lsscsi,你可能需要把它作为一个额外的软件包来安装。
图3-2显示了这个特定系统配置的内核中的驱动和接口层次,从单个设备驱动到块驱动。它不包括SCSI通用(sg)驱动。
尽管这是一个庞大的结构,一开始可能会让人不知所措,但是图中的数据流是非常线性的。让我们从SCSI子系统和它的三层驱动开始剖析:
顶层处理一类设备的操作。例如,sd(SCSI磁盘)驱动程序就在这一层;它知道如何将来自内核块设备接口的请求翻译成SCSI协议中的磁盘特定命令,反之亦然。
中间层在顶层和底层之间调节和路由SCSI信息,并跟踪所有的SCSI总线和连接到系统的设备。
底层处理特定的硬件动作。这里的驱动程序向特定的主机适配器或硬件发送传出的SCSI协议信息,并从硬件提取传入的信息。与顶层分离的原因是,尽管SCSI消息对于一个设备类别(如磁盘类别)是统一的,但不同种类的主机适配器有不同的发送相同消息的程序。

图3-2: Linux SCSI子系统原理图
上层和下层包含许多不同的驱动,但是重要的是要记住,对于你系统上的任何一个设备文件,内核(几乎总是)使用一个上层驱动和一个下层驱动。在我们的例子中,对于位于/dev/sda的磁盘,内核使用sd顶层驱动和ATA桥层驱动。
有些时候,你可能会为一个硬件设备使用不止一个上层驱动(见第3.6.3节)。对于真正的硬件SCSI设备,比如连接到SCSI主机适配器或硬件RAID控制器的磁盘,下层驱动程序直接与下面的硬件对话。然而,对于你发现连接到SCSI子系统的大多数硬件来说,情况就不同了。

3.6.1 USB存储和SCSI

为了让SCSI子系统与普通的USB存储硬件对话,如图3-2所示,内核需要的不仅仅是一个低层的SCSI驱动。一个由/dev/sdf代表的U盘可以理解SCSI命令,但是为了和驱动器进行实际的通信,内核需要知道如何通过USB系统进行对话。
从抽象的角度来看,USB与SCSI非常相似--它有设备类别、总线和主机控制器。因此,Linux内核包括一个与SCSI子系统非常相似的三层USB子系统也就不足为奇了,它的顶端是设备类驱动程序,中间是总线管理核心,底部是主机控制器驱动程序。与SCSI子系统在其组件之间传递SCSI命令一样,USB子系统在其组件之间传递USB信息。甚至还有一个lsusb命令,与lsscsi相似。
我们在这里真正感兴趣的部分是顶部的USB存储驱动器。这个驱动充当了翻译者的角色。在一端,驱动程序说的是SCSI,而在另一端,它说的是USB。因为存储硬件在其USB信息中包含SCSI命令,所以驱动程序的工作相对容易:它主要是重新包装数据。
有了SCSI和USB子系统,你几乎拥有了与闪存盘对话所需的一切。最后缺失的环节是SCSI子系统中的下层驱动,因为USB存储驱动是USB子系统的一部分,而不是SCSI子系统。(由于组织上的原因,这两个子系统不应该共享一个驱动。)为了使子系统能够相互交谈,一个简单的、低层的SCSI桥接驱动连接到USB子系统的存储驱动。

3.6.2 SCSI和ATA

图3-2中的SATA硬盘和光驱都使用相同的SATA接口。为了将内核的SATA驱动连接到SCSI子系统,内核采用了一个桥接驱动,就像对待USB驱动器一样,但是有不同的机制和额外的复杂情况。光驱说的是ATAPI,这是ATA协议中编码的SCSI命令的一个版本。然而,硬盘不使用ATAPI,也不对任何SCSI命令进行编码!
Linux内核使用一个叫做libata的库的一部分来调和SATA(和ATA)驱动器与SCSI子系统。对于讲ATAPI的光驱来说,这是一个相对简单的任务,即把SCSI命令打包并提取到ATA协议中去。但对硬盘来说,这项任务要复杂得多,因为库必须做一个完整的命令转换。
光驱的工作类似于将一本英文书打入电脑。你不需要为了完成这项工作而理解书的内容,甚至也不需要理解英语。但硬盘的任务更像是阅读一本德语书,并将其作为英文翻译输入电脑。在这种情况下,你需要理解两种语言以及书中的内容。
尽管有这样的困难,libata还是执行了这项任务,并使将ATA/SATA接口和设备连接到SCSI子系统成为可能。(除了图3-2中所示的一个SATA主机驱动程序外,通常还涉及更多的驱动程序,但为了简单起见,我们没有显示出来)。

3.6.3 通用SCSI设备

当用户空间进程与SCSI子系统通信时,它通常是通过块设备层和/或其他位于SCSI设备类驱动(如sd或sr)之上的内核服务进行的。换句话说,大多数用户进程不需要知道任何关于SCSI设备或它们的命令。
然而,用户进程可以绕过设备类驱动程序,通过其通用设备直接向设备发出SCSI协议命令。例如,考虑第3.6节中描述的系统,但这次,看看当你为lsscsi添加-g选项以显示通用设备时会发生什么:

$ lsscsi -g
[0:0:0:0]   disk    ATA       WDC WD3200AAJS-2  01.0  /dev/sda 1/dev/sg0
[1:0:0:0]   cd/dvd  Slimtype  DVD A DS8A5SH     XA15  /dev/sr0   /dev/sg1
[2:0:0:0]   disk    USB2
首页 上一页 4 5 6 7 下一页 尾页 7/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇INFINI Labs 产品更新 | Console .. 下一篇shell 常用命令3

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目