SCSI命令下发方式<续>:对NVMe硬盘如何实现SCSI命令转换?

简介: 我们前面有对SATA硬盘下发SCSI命令,其实对NVMe硬盘下发SCSI的方式大同小异。下面我们就来试一下,这里我们用到的SCSI命令是READ CAPACITY。

一、前情回顾

在这篇文章之前,本公众号有发表过一篇文章:


“如何对SSD固态硬盘下发SCSI command?”                          


对于SCSI含义以及SCSI命令的一些基础概念在本篇将不再赘述,麻烦各位看官先翻阅一下前面的文章,非常感谢~



二、SCSI/ATA以及SCSI/NVMe转换层

针对SATA和NVMe SSD下发SCSI命令,其实不是直接将SCSI命令下发到硬盘,而是要经过转换层。

  1. SCSI to ATA转换层结构如下:转换层全称是SCSI / ATA Translation Layer,  缩写SATL.
  2. SCSI to NVMe转换层结构如下:同样, SCSI to NVMe转换层全称SCSI to NVMe Translation Layer,简称SNTL。这个转换层会嵌入到NVMe driver里面。


三、实例: 如何对NVMe硬盘下发SCSI命令?

我们前面有对SATA硬盘下发SCSI命令,其实对NVMe硬盘下发SCSI的方式大同小异。下面我们就来试一下,这里我们用到的SCSI命令是READ CAPACITY。


SCSI Spec对READ CAPACITY的定义:


首先,我们先看一下NVMe SSD的状态:

如上图,这里显示的是SCSI device, 符合我们的预期。


本篇继续用sg3这个工具下发SCSI CMD,详细的解释请见:

“如何对SSD固态硬盘下发SCSI command?”                          

用sg_scan找盘,并用sg_raw下发 Read Capacity,

如上图,我们看到有8字节返回结果, 3b f4 54 7f 00 00 02 00,

这个怎么解析呢?我还是先看SCSI SPEC,

从SPEC来看, byte0-3代表最后一个逻辑Block地址,byte4-7代表逻辑block的长度。


那么,我们可以解析上面的结果如下:

byte0-3:最后一个逻辑Block地址=0x3bf4547f=1005868159, 那么,

逻辑block的数目=逻辑Block地址+1=1005868159+1=1005868160,


byte4-7:逻辑block的长度=0x200=512 bytes,


所以硬盘的容量= 逻辑block的数目 * 逻辑block的长度 = 1005868160 * 512 bytes = 515004497920 bytes = 515004497920/(1024*1024*1024) = 479.635GB,


我们从两个方面确认一下读出的结果是否正确:

a, 直接用电脑的资源管理器查看:

资源管理器里看到的容量是479.64GB,跟我们读出来的一致!


b,在之前的文章中有提到sg3其实有很多集成好的SCSI cmd, 详细请见:

“如何对SSD固态硬盘下发SCSI command?”                          




我们这里用的read capacity其实也集成好了,我们直接用集成SCSI CMD再读一下:

从上面的结果来看,跟我们前面手动填写CDB的方式读出来的结果是一致的!

相关文章
|
固态存储 IDE 开发工具
【实战经验分享】如何对SSD固态硬盘下发SCSI command?
目前可以供用来下发SCSI/ATA Command的工具有很多,比如BusHound, Hdparm, Sg3, Msecli等。其中Msecli是Micron自己的专门用来管理Micron SSD的命令行接口, 对于其他家的SSD是无效的。我们这里主要用的Sg3这个工具
|
机器学习/深度学习 Shell 内存技术