Linux的文件系统(1)——硬盘、接口与设备文件

在文件系统的底层,操作系统根据不同的硬盘接口识别硬盘(盘符),之后不断抽象(设备文件、分区、LVM、挂载),逐渐过渡到软件系统当中

磁盘与闪存

如今说到硬盘,一般都会说到 机械硬盘(HDD)固态硬盘(SSD)。其实在固态硬盘还没有如今这样普及的时候,常用的两种概念是 磁盘(Magnetic Storage) 和 闪存(Flash Storage)

磁盘与机械硬盘

打开维基的“磁盘”页面其实指向的就是 HDD(Hard disk drive),也就是硬盘。目前最普遍使用的硬盘依然是磁盘——一种磁性存储器。现在为了与的固态硬盘(SDD)相区分,又被称为传统硬盘或机械硬盘

磁盘的构造原理为:将磁性材料覆盖在圆形碟片(或者说盘片)上,通过一个读写头(磁头)悬浮在碟片表面来感知存储的数据。通过碟片的旋转和磁头的径向移动来读写碟片上任意位置的数据。碟片被划分为多个环形的轨道(称为磁道,Track)来保存数据,每个磁道又被分为多个等密度(等密度数据)的弧形扇区(Sector)作为存储的基本单元,内部结构如下图:

硬盘在工作时,盘片是一直旋转的,当想要读取某个扇区的数据时,首先要将读写头移动到该扇区所在的磁道上,当想要读写的扇区旋转到读写头下时,读写头开始读写数据

闪存与固态硬盘

闪存(Flash Storage)是一种半导体存储器,它和磁盘一样是非易失性的存储器,但是它的访问延迟只有磁盘的千分之一到百分之一,而且尺寸小、功耗低,抗震性更好

闪存的构造原理为:利用FGMOS(一种半导体场效应晶体管)可以存储电荷的特点,组成基础的记忆单元;再利用特定电压值控制栅极,实现电荷的注入、抹除,即信息的存储

NOR型闪存的写入电路与晶体管结构

最早出现的闪存被称为NOR型闪存,它使用 NOR闸(或称“或非门”) 的电路结构,通过热电子注入的技术写入电荷,借由量子穿隧效应来抹除电荷。NOR型闪存的抹除只能以这些区块为单位进行,其优势是随机访问和读取时间快,劣势在于频繁的写入和擦除,所以常见于物联网与单片机

为了降低单元成本、也更易于写入和擦除,NAND型闪存采用了另一种电路结构—— NAND闸(或称“与非门”) ,利用穿隧注入写入电荷,利用穿隧释放抹除电荷。NAND型闪存更适合移动存储,不断发展成为了SD卡、U盘和SSD固态硬盘

NAND型闪存的写入电路与晶体管结构

闪存的存储单元随着擦写次数的增多存在损坏的风险,为了解决这个问题,大多数NAND型闪存产品内部的控制器采用地址块重映射的方式来分布写操作,目的是将写次数多的地址转移到写次数少的块中。该技术被称为磨损均衡(Wear Leveling)

总结:

常有人问机械硬盘和固态硬盘到底有哪些区别,其实本质上就是映射了“磁盘”与“闪存”两种不同的存储技术

总的来说闪存,也就是固态硬盘肯定是更先进的:速度更快、体积更小、功耗更低、抗震性能更好、温度适应性更高。唯一的缺点可能是多次擦写下数据有丢块的风险。不过通过技术补足(比如ECC),或技术提升(比如让这个多次的数值趋于无穷大),这个缺点终将会被克服的

常见硬盘的数据接口

对于计算机系统来说,硬盘的区别主要在数据接口的不同,传统上常见可分为 ATA(IDE)、SATA、SCSI 三种

ATA(IDE、PATA)

全称为Advanced Technology Attachment,是一种相对传统的存储设备接口标准,IDE(Integrated Drive Electronics)是与之相匹配的磁盘驱动器技术。这两个术语经常可以互用,应用于早期的计算机中,适用于硬盘和CD-ROM

SATA标准于2003年推出后,传统的ATA这时也被更具体的称为PATA(Parallel ATA),即并口式ATA

ATA使用传统的40-pin并口数据线连接主板与硬盘,接口速度最大为133MB/s。ATA的优点是价格低廉,缺点是并口线的抗干扰性太差,且排线占用空间较大,不利电脑内部散热,已逐渐被SATA所取代

发展至今的ATA标准可细分为ATA-1(IDE)、ATA-2(EIDE Enhanced IDE/Fast ATA)、ATA-3(FastATA-2)、Ultra ATA、Ultra ATA/33、Ultra ATA/66、Ultra ATA/100及Serial ATA

模式代号别称最大传输速度 (MB/s)最小时钟周期版本定义
Ultra DMA016.7120 ns
125.080 nsATA-4
2Ultra ATA/3333.360 nsATA-4
344.445 nsATA-5
4Ultra ATA/6666.730 nsATA-5
5Ultra ATA/10010020 nsATA-6
6Ultra ATA/13313315 nsATA-7
7Ultra ATA/16716712 nsCompactFlash 6.0

Ultra DMA是目前计算机与ATA设备之间传输数据的最快模式

SATA

全称为Serial ATA,即串口式ATA,特点是抗干扰性强,对数据线的要求比ATA低很多,驱动电压更低,支持排线更长,且支持热插拔等功能

SATA使用新的磁盘驱动技术——AHCI,读取速度更快,不过也向前兼容IDE驱动(读写速度慢)

SATA-II的接口速度为300MB/s,而SATA-III标准可达到600MB/s,2013年推出的SATA Express则可达到更快速度

版本名称 原始频宽 传输速度 需外接电源
SATA revision 1.0 1.5Gbit/s 150MB/s No
SATA revision 2.0 3Gbit/s 300MB/s No
SATA revision 3.0 6Gbit/s 600MB/s No
eSATA 6Gbit/s 600MB/s 需要外接变压器与电源
eSATAp 6Gbit/s 600MB/s 通过一条USB线提供5V或12V电压
SATA Express 16Gbit/s 1.97GB/s No

eSATA 是 External Serial ATA的简称,为面向外接驱动器定制的的SATA扩展(主要是提高了插拔耐用度,相对于SATA线缆大概只能插拔几十次,eSATA支持2000次以上的插拔)。它的最大缺点是没有电力供应,需要单独的外接电源(额外的电源线或者额外的USB线供电)

为解决电源问题,SATA-IO(国际ATA组织)又在2008年推出了eSATAp,它结合了eSATA的七个针脚及USB 2.0的四个针脚,利用其中的USB针脚为硬盘提供5V或12V电压

SCSI

全称为Small Computer System Interface,即小型计算机系统接口,是为计算机与外接存储设备(外接硬盘、软驱、光驱、打印机、扫描仪等)之间设计的数据接口标准

SCSI并不是专为硬盘设计的接口标准,具备更广泛的适用范围。同时SCSI控制器独立于系统总线工作,这意味着更快的传输速度、更大的数据吞吐量和更小的系统CPU占用(相比ATA与SATA)

SCSI使用一种叫做“命令队列”的技术来优化数据的存储,允许控制器根据最佳的命令来执行和驱动器内数据相关的请求。对于一台服务器来说,在同一时刻会有很多不同的用户发出请求,如果磁盘驱动器不具有类似这种底层的能够处理很多并发需求的设计,那么磁盘驱动器就会变成系统性能的瓶颈。而SATA在这方面就不如SCSI,所以SCSI被广泛用于企业级的服务器

版本名称别称原始频宽传输速度规范文件
SCSI-1 Narrow SCSI 40 Mbit/s 5 MB/s SCSI-1 (1986)
Fast SCSI 80 Mbit/s 10 MB/s SCSI-2 (1994)
Fast-Wide SCSI 160 Mbit/s 20 MB/s SCSI-2;SCSI-3 SPI (1996)
Ultra SCSI Fast-20 160 Mbit/s 20 MB/s SCSI-3 SPI
Ultra Wide SCSI 320 Mbit/s 40 MB/s SCSI-3 SPI
Ultra2 SCSI Fast-40 320 Mbit/s 40 MB/s SCSI-3 SPI-2 (1997)
Ultra2 Wide SCSI 640 Mbit/s 80 MB/s SCSI-3 SPI-2
Ultra3 SCSI Ultra-160;
Fast-80 wide
1280 Mbit/s 160 MB/s SCSI-3 SPI-3 (1999)
Ultra-320 SCSI Ultra-4 SCSI;
Fast-160 SCSI
2560 Mbit/s 320 MB/s SCSI-3(2002)
Ultra-640 SCSI Ultra-5 5120 Mbit/s 640 MB/s SCSI-3(2003)

发展至今,SCSI大的版本号发展到3.0。如今SAS是新一代的SCSI技术,未来也许会逐渐取代SCSI

SAS

全称Serial Attached SCSI,即串口式SCSI,是新一代的SCSI技术,可兼容SATA硬盘,同样支援热插拔,采用串行技术以获得更高的传输速度,可达到12Gb/s,碟片转速也较快。而较小的连接线,改善了系统内部空间空气流通。通常应用于服务器等企业级产品

版本名称原始频宽传输速度规范文件
SAS 1.1 2400Mbit/s 300MB/s T10/INCITS 417-2006
SAS 2.1 4800Mbit/s 600MB/s T10/INCITS 478-2011
SAS 3.0 9600Mbit/s 1200MB/s T10/INCITS 519
SAS 4.0 19200Mbit/s 2400MB/s T10/INCITS 534 (draft)

FC

全称Fibre Channel,即光纤通道接口,原本并不是为硬盘数据接口所设计,是一种网络数据传输技术。过去,FC大多用于超级计算机之间的数据互联,但目前也成为企业级存储SAN中的一种常见接口类型

FC可以理解为传统I/O接口与网络技术相结合趋势的一部分,可以一并满足网络(network)和传统接口(channel)两种不同的用户需求。同时在传输速度与传输距离上也有巨大提升:

FC有着GB级的传输速度,同时也支持公里级的传输距离(通过光纤交换机实现)

FC还提供兼容传统数据接口标准的的能力,将传统的接口作为上层协议,光纤通道接口的使用如下图所示:

连接和扩展是FC的另一个目标,通过将数千个设备共享数据并连接在一起来,FC支持交换光纤,一个光纤结构理论上可支持一千六百万地址

总结:

SCSI标准形成于1982年(当时还叫SASI),并于1986年正式标准化;ATA标准推出于1986年,这两者的底层设计是有较大区别的,可以粗浅理解为SCSI是为外接设备设计的。SCSI中的small computer只是因历史原因保留的名字,现在的SCSI也早已应用于大型系统当中了

SATA标准正式推出是在2003年,相当于串口式的ATA;SAS标准推出于2004年,相当于串口式的SCSI,两者都是通过串行技术获得更高的传输速率并改善内部空间等。此外,由于SAS硬盘可以与SATA硬盘共享同样的背板,因此在同一个SAS存储系统中,可以用SATA硬盘来取代部分昂贵的SAS硬盘,节省整体的存储成本。但SATA存储系统并不能连接SAS硬盘

目前的趋势是:SATA逐渐取代ATA(IDE),SAS逐渐取代SCSI

FC是为网络系统设计的(1988年),逐渐应用到大型硬盘系统当中,目前只使用于高端服务器领域。当前,一般的硬盘本身也是不具备FC接口的,插硬盘的机柜上带有FC接口,再连接到光纤交换机(机柜和硬盘之间使用的还是SCSI等接口)

M.2接口与NVMe的出现与发展

2009年,Intel开始着手寻找SATA/AHCI的替代方案:SSD(固态硬盘)在大众市场上逐渐流行,作为为HDD(机械硬盘)设计的SATA及相对应的驱动技术AHCI已经成为制约SSD速度的瓶颈

机械结构的HDD使用读取臂做读写,与直接操作固态晶体结构的SSD差异很大

于是出现了M.2和NVMe。M.2接口采用了全新的物理布局和连接器,原本叫 NGFF (Next Generation Form Factor),于2013年正式以M.2的名字推出;NVM Express(缩写NVMe),全称为Non-Volatile Memory Express,大致也是2013年正式推出。从M.2和NVMe命名上都可以看出其作为下一代硬盘接口及驱动协议的野心

M.2接口允许SSD直接连接到主板PCIe总线上,同时,相比HDD时代的AHCI,NVMe可以充分利用固态存储的并列化存储能力,提供更高的吞吐量和更低的延迟,目前M.2接口+NVMe协议的理论最高传输速度可达到20Gbps

M.2/NVMe与SATA/AHCI的主要不同:

也许有一天,SSD终将全面取代HDD,NVMe也终将全面取代现在的AHCI(M.2接口不一定,毕竟接口与硬件联系更紧密)。目前Windows 8.1\Solaris 11.2\Mac OS X 10.10.3\Linux 3.3等及它们的更新版本,都自带原生的NVMe驱动了。苹果从2016年的MacBook Pro开始,配置了使用NVMe的SSD来作为自身的主机硬盘

通过传统SATA、SATA Express、NVMe体系结构的概览可以看到它们之间的区别

其他类型的数据接口

这里其他类型的数据接口主要指三类:曾经的接口标准、少见的接口标准和非硬盘的接口标准

还有更多的接口类型,比如早期的多媒体接口 VGA、DVI,早期的打印机接口 Parallel Port 等等,这些都是在老机器上还能见到的。计算机技术在过去的几十年中迅猛发展,各种新技术新概念飞速更新,并不一定有清晰的界定:比如SATA既指接口规范(偏硬件),也指代其驱动协议(偏软件,AHCI);USB既表达一种汇流排标准(总线),也指代其对应的物理接口

不过总的趋势是趋向逐渐统一的: SAS与SATA共享同样背板、USB几乎取代了所有外接设备接口、FC统一了HIPPI和ESCON,Thunderbolt就更牛逼了,兼顾了数据传输和音视频信号传输——也许以后的电脑只需要一种接口也说不定

发展到目前的接口技术粗糙的梳理一下,大致如下:

硬盘传输速度

需要指出的一点是,数据接口参数中的最大传输速度并不代表实际硬盘的传输速度。许多因素都会影响硬盘传输的性能,包括连接、线缆、编码规范、设备类型乃至文件系统的工作模式

比如,某些支持 Thunderbolt 3 的计算机仅设计两个PCI通道。但是想达到 Thunderbolt 3 支持的40Gb/s,需要四个PCI通道。这意味着,如果计算机只有两条通道,则最大传输速度只能为20Gb/s

再比如,如果需要同时在Mac和Windows PC上使用同一块存储设备(比如移动硬盘),通常需要exFAT这一文件系统格式。但是由于这一格式并不是适合两种操作系统的最佳文件系统,因此可能无法获得最佳的传输率

总的来说,接口参数只决定速度上限,现实使用中常远远达不到那个速度。理论速度625M/s的USB3.0接口在8b/10b编码规范(USB3.0现行编码规范)下速度上限是500M/s,而在实际使用中一般能达到150M/s的传输速度就不错了

Linux系统中的硬盘盘符(设备文件)

操作系统通过不同的 数据接口(接口规范 + 驱动协议) 来识别连接在主机上的硬盘。对于Linux系统来说,就是 /dev/ 目录下的不同文件

设备类型装置在Linux内的文件名
软盘 /dev/fd[0-1]
IDE硬盘或光驱 /dev/hd[a-d][1-9]
SCSI硬盘(SATA/SCSI/USB) /dev/sd[a-p][1-9]
SCSI光驱 数据光驱:/dev/sr[0-1]
音频光驱:/dev/scd[0-1]
SCSI磁带 自动回卷磁带:/dev/st[0-1]
不自动回卷磁带:/dev/nst[0-1]
SCSI通用设备
(匹配非sd/st/sr等的其他SCSI设备)
/dev/sg[1-9]
NVMe硬盘 /dev/nvme[0-9]n[1-9]p[1-9]
打印机 25针: /dev/lp[0-2]
USB: /dev/usb/lp[0-15]
鼠标 PS2: /dev/psaux
USB: /dev/usb/mouse[0-15]

以上称之为Linxu系统中设备文件的命名约定

对于Windows系统,设备入口不以文件系统中的文件节点的形式呈现,而是由系统为设备赋予预留的设备名:比如CON表示键盘或屏幕,PRN表示打印机,AUX表示串口,使用PnP设备树统一管理。可参考 Windows I/O 管理

实际中Linux的设备文件系统要远比上表中复杂,除了现实的硬盘设备,还有软件模拟的伪设备。比如我们还会看到下面这些设备文件:

含义装置在Linux内的文件名
终端/伪终端 终端:/dev/tty[0-9]
串口:/dev/ttyS[0-9]
虚拟机硬盘 /dev/vd[a-p][1-9]
控制台
(其实是个特殊的伪终端)
/dev/console
PPP 设备 /dev/ppp[0-9]
Btrfs文件系统控制设备 /dev/btrfs-control
非易失性RAM /dev/nvram
伪终端(tty)的内容捕捉 /dev/vcs[0-9]
/dev/vcsa[0-9]
伪设备:Loop设备 /dev/loop[0-1]
伪设备:永远满状态的设备 /dev/full
伪设备:接受并丢弃所有输入 /dev/null
伪设备:产生连续的NUL字元 /dev/zero
伪设备:产生随机的字元流(Blocking) /dev/random
伪设备:产生随机的字元流(Non-Blocking) /dev/urandom
DeviceMapper 设备 /dev/mapper/[pool名]
DeviceMapper 设备的映射 /dev/dm-[0-9]
Unix98 PTY master 的复用器 /dev/ptmx
指向当前鼠标的符号链接 /dev/mouse
指向当前光驱的符号链接 /dev/cdrom

终端(Teletypewriter),最初是指电传打字机,后来泛指计算机的终端设备。发展到今天,现在真正的硬件终端基本上已经见不到了。现在所说的终端、伪终端都是软件仿真终端。通过 SSH 等方式建立的远程连接都相当于使用了伪终端

还有更多的设备文件无法一一枚举,而这些 命名约定 也并不是一成不变的。实际上,到底哪一设备文件对应什么样的命名方式取决于系统中 udev 的设置,其位于 /lib/udev/rules.d/ 文件夹下

一份真实的 udev 设置如下所示:

# do not edit this file, it will be overwritten on update
SUBSYSTEM=="virtio-ports", KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio-ports/$attr{name}"

# select "system RTC" or just use the first one
SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc"
SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb -- subsystem=usb"
SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"
ACTION!="add", GOTO="default_permissions_end"
SUBSYSTEM=="tty", KERNEL=="ptmx", GROUP="tty", MODE="0666"
SUBSYSTEM=="tty", KERNEL=="tty", GROUP="tty", MODE="0666"
SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", GROUP="tty", MODE="0620"
SUBSYSTEM=="tty", KERNEL=="sclp_line[0-9]*", GROUP="tty", MODE="0620"
SUBSYSTEM=="tty", KERNEL=="ttysclp[0-9]*", GROUP="tty", MODE="0620"
SUBSYSTEM=="tty", KERNEL=="3270/tty[0-9]*", GROUP="tty", MODE="0620"
SUBSYSTEM=="vc", KERNEL=="vcs*|vcsa*", GROUP="tty"
KERNEL=="tty[A-Z]*[0-9]|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout"
SUBSYSTEM=="mem", KERNEL=="mem|kmem|port", GROUP="kmem", MODE="0640"
SUBSYSTEM=="input", GROUP="input"
SUBSYSTEM=="input", KERNEL=="js[0-9]*", MODE="0664"
SUBSYSTEM=="video4linux", GROUP="video"
SUBSYSTEM=="misc", KERNEL=="agpgart", GROUP="video"
SUBSYSTEM=="graphics", GROUP="video"
SUBSYSTEM=="drm", GROUP="video"
SUBSYSTEM=="dvb", GROUP="video"
SUBSYSTEM=="block", GROUP="disk"
SUBSYSTEM=="block", KERNEL=="sr[0-9]*", GROUP="cdrom"
SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", GROUP="cdrom"
KERNEL=="sch[0-9]*", GROUP="cdrom"
KERNEL=="pktcdvd[0-9]*", GROUP="cdrom"
KERNEL=="pktcdvd", GROUP="cdrom"

SUBSYSTEM=="scsi_generic|scsi_tape", SUBSYSTEMS=="scsi", ATTRS{type}=="1|8", GROUP="tape"
SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="0", GROUP="disk"
KERNEL=="qft[0-9]*|nqft[0-9]*|zqft[0-9]*|nzqft[0-9]*|rawqft[0-9]*|nrawqft[0-9]*", GROUP="disk"
KERNEL=="loop-control", GROUP="disk", OPTIONS+="static_node=loop-control"
KERNEL=="btrfs-control", GROUP="disk"
KERNEL=="rawctl", GROUP="disk"
SUBSYSTEM=="raw", KERNEL=="raw[0-9]*", GROUP="disk"
SUBSYSTEM=="aoe", GROUP="disk", MODE="0220"
SUBSYSTEM=="aoe", KERNEL=="err", MODE="0440"

KERNEL=="rfkill", MODE="0664"
KERNEL=="tun", MODE="0666", OPTIONS+="static_node=net/tun"
KERNEL=="fuse", MODE="0666", OPTIONS+="static_node=fuse"
LABEL="default_permissions_end"      

字符设备、块设备与网络设备

在Linux中,设备文件的类型还可以分为 字符设备、块设备和网络设备 三大类

字符设备

提供连续的数据流,应用程序可以顺序读取,通常不支持随机存取。此类设备支持按字节/字符来读写数据。键盘、串口、调制解调器都是典型的字符设备

块设备

提供稳定的数据存储,应用程序可以通过寻址随机的访问设备数据。此类设备的数据读写通常只能以块(一般为512B)的倍数进行。硬盘、软盘、光盘都是典型的块设备

网络设备

网络设备是特殊的设备文件,它负责接收和发送帧数据,可能是物理帧,也可能是ip数据包,这些特性都由网络驱动决定。它并不存在于 /dev/ 下面。网络设备是一个 net_device 结构,并通过 register_netdev 注册到系统里,最后通过 ifconfig -a 的命令可以看到

$ ifconfig -a
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
        inet 192.168.155.155 netmask 255.255.240.0 broadcast 192.168.159.255
        ether 00:16:3e:13:96:53 txqueuelen 1000 (Ethernet)
        RX packets 49156667 bytes 11335926436 (10.5 GiB)
        RX errors 0 dropped 0 overruns 0 frame 0
        TX packets 42596644 bytes 8077138984 (7.5 GiB)
        TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
        inet 127.0.0.1 netmask 255.0.0.0
        loop txqueuelen 1000 (Local Loopback)
        RX packets 287263 bytes 21775366 (20.7 MiB)
        RX errors 0 dropped 0 overruns 0 frame 0
        TX packets 287263 bytes 21775366 (20.7 MiB)
        TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

网卡插在计算机主板上,系统从PCI总线检测到设备,并启用它,但它只是一支硬件设备(网卡设备)。网卡驱动需要包装底层的设备细节,抽象为 net_device 数据结构并注册到系统里,这就是一个网络设备。网络设备实际上是一种逻辑设备(伪设备)

参考&扩展

《计算机体系结构基础》—— 第 5 章 计算机组成原理和结构
《计算机组成原理》—— 第 1 章 计算机系统结构
《深入理解计算机系统》—— 第 6 章 存储器层次结构
硬盘分类详解
《Linux Kernel核心中文手册》—— 第 8 章 设备驱动程序
IDE、SATA、SCSI、SAS、FC、SSD 硬盘区别——Dell
Lacie:为什么我的外置硬盘无法达到广告中的性能?
NOR闪存基础知识:工作原理及应用
金士顿 KC2500 SSD 产品说明书
西部数码:SSD与HDD产品比较
Intel:固态硬盘与机械硬盘
Sun 公用 SCSI 体系结构
AHCI 规范中文文档
Linux内核中的设备模型及SCSI示例解析
Solaris 10 发行版本驱动程序增强功能
Linux终端(TTY)——终端与伪终端
Linux TTY/PTS概述
USB-IF 官方网站
The Linux SCSI Generic (sg) Driver
The Linux 2.4 SCSI subsystem HOWTO —— Chapter 9
Debian GNU/Linux 安装手册
Linux SCSI设备寻址
Linux Filesystem Hierarchy —— Chapter 1.5
A Comparison of the Linux and Windows Device Driver Architectures
Windows I/O 管理
Microsoft: PnP Components
Why does Linux list NVMe drives as /dev/nvme0 instead of /dev/sda?
How To Find If The Disk Is SSD Or HDD In Linux
RAID磁盘阵列是什么
再谈linux中为何没有网卡设备文件