一、前情回顾
在这篇文章之前,本公众号有发表过一篇文章:
“如何对SSD固态硬盘下发SCSI command?”
对于SCSI含义以及SCSI命令的一些基础概念在本篇将不再赘述,麻烦各位看官先翻阅一下前面的文章,非常感谢~
二、SCSI/ATA以及SCSI/NVMe转换层
针对SATA和NVMe SSD下发SCSI命令,其实不是直接将SCSI命令下发到硬盘,而是要经过转换层。
- SCSI to ATA转换层结构如下:转换层全称是SCSI / ATA Translation Layer, 缩写SATL.
- 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的方式读出来的结果是一致的!