固态硬盘
本文涵盖了操作固态硬盘(SSD)和其他基于闪存存储设备的特殊主题。
如果您想为特定目的分区 SSD,则考虑针对闪存优化的文件系统列表可能会很有用。
用法
TRIM
与硬盘驱动器相比,在硬盘驱动器中,删除文件仅在文件系统级别处理[1],SSD 受益于在内存块空闲可重用时通知磁盘控制器。由于构成它们的闪存单元在每次写入操作时都会磨损一点,因此磁盘控制器使用算法来共享所有单元上的写入操作:此过程称为磨损均衡。如果没有 NVMe DEALLOCATE、SAS UNMAP 或 ATA_TRIM 命令(大多数 SSD 支持),一旦没有空内存块,磁盘控制器就需要花费更多时间来执行写入操作,因为它必须洗牌数据以在写入单元之前擦除单元(请参阅Wikipedia:写入放大):TechSpot 基准测试显示了用数据填充 SSD 前后的性能影响。
从 Linux 内核版本 3.8 开始,不断为不同的文件系统添加了对 TRIM 的支持。请参阅下表以获得指示性概述
文件系统 | 持续 TRIM ( discard 选项) |
定期 TRIM (fstrim) |
参考 和注释 |
---|---|---|---|
Bcachefs | 是 | 否 | |
Btrfs | 是 | 是 | 自内核 6.2 起,默认启用异步丢弃。 |
exFAT | 是 | 是 | 自内核 5.13 起支持 fstrim,[4] |
ext3 | 是 | 是 | |
ext4 | 是 | 是 | [5]中的 "discard, nodiscard(*)" |
F2FS | 是 | 是 | |
JFS | 是 | 是 | [6] |
NILFS2 | 是 | 是 | |
NTFS | 是 | 否 | ntfs3 内核驱动程序仅支持持续 TRIM。 |
否 | 是 | NTFS-3G 驱动程序仅支持定期 TRIM。 | |
VFAT | 是 | 是 | 自内核 4.19 起支持 fstrim,[7] |
XFS | 是 | 是 | [8] |
交换空间 | 是 | 否 | 从技术上讲,不是“文件系统”,但 TRIM 仍然相关。“once”选项提供启动时计划的修剪。请参阅 swapon(8)。 |
要验证 TRIM 支持,请运行
$ lsblk --discard
并检查 DISC-GRAN(丢弃粒度)和 DISC-MAX(丢弃最大字节数)列的值。非零值表示支持 TRIM。
仅对于 SATA SSD,hdparm 软件包可以通过 hdparm -I /dev/sda | grep TRIM
以root 用户身份检测 TRIM 支持。但是,hdparm
不支持 NVMe SSD。
定期 TRIM
util-linux 软件包提供 fstrim.service
和 fstrim.timer
systemd 单元文件。启用 timer 将每周激活该服务。该服务在支持 discard 操作的设备上对所有已挂载的文件系统执行 fstrim(8)。
timer 依赖于 /var/lib/systemd/timers/stamp-fstrim.timer
的时间戳(首次调用时会创建),以了解自上次运行以来是否已过去一周。因此,无需担心以类似于 anacron 的方式调用过于频繁。
要查询单元的活动和状态,请参阅 journalctl。要更改 timer 的周期或运行的命令,请编辑提供的单元文件。
持续 TRIM
除了每隔一段时间(如果使用 fstrim.timer
,则默认为每周一次)发出 TRIM 命令外,还可以选择在每次删除文件时发出 TRIM 命令。后者称为持续 TRIM。
ATA_QUIRK_NO_NCQ_TRIM
的 __ata_dev_quirks
条目,由于严重的数据损坏,队列 TRIM 命令执行已被列入黑名单。在这种情况下,根据设备的不同,系统可能会被迫向 SSD 发送非队列 TRIM 命令,而不是队列 TRIM。有关详细信息,请参阅 Wikipedia:Trim_(computing)#缺点。在 /etc/fstab
中为挂载使用 discard
选项可在设备操作中启用持续 TRIM
/dev/sda1 / ext4 defaults,discard 0 1
在 ext4 文件系统上,也可以使用 tune2fs 将 discard
标志设置为默认挂载选项
# tune2fs -o discard /dev/sdXY
使用默认挂载选项而不是 /etc/fstab
中的条目对于外部驱动器尤其有用,因为此类分区在其他机器上也会以默认选项挂载。这样,无需在每台机器上都编辑 /etc/fstab
。
/proc/mounts
中列出。Trim 整个设备
如果您想一次性 trim 整个 SSD,例如,对于新的安装或者您想出售驱动器,则可以使用 blkdiscard 命令。
LVM
从文件系统传递到逻辑卷的 TRIM 请求会自动传递到物理卷。无需额外的配置。
默认情况下,没有 LVM 操作(lvremove、lvreduce 和所有其他操作)向物理卷发出 TRIM 请求。这样做是为了允许使用 vgcfgrestore(8) 恢复以前的卷组配置。/etc/lvm/lvm.conf
中的设置 issue_discards
控制是否在逻辑卷不再使用物理卷空间时向逻辑卷的底层物理卷发送丢弃。
issue_discards
设置之前,请仔细阅读 /etc/lvm/lvm.conf
中的注释。它不会以任何方式影响从文件系统传递到磁盘的 TRIM 请求(例如,文件系统内部的文件删除),也不会影响精简池内的空间管理。issue_discards
将阻止使用 vgcfgrestore 恢复卷组元数据。如果错误地发出 LVM 命令,将没有恢复选项。dm-crypt
按照 dm-crypt/Specialties#固态硬盘 (SSD) 的丢弃/TRIM 支持 中的说明,为 LUKS 和纯 dm-crypt 设备启用丢弃支持。
交换空间
要为交换空间启用丢弃,请将 discard
选项添加到 fstab 中交换设备的条目,或者在调用 swapon
时传递 --discard
。
使用 Systemd#GPT 分区自动挂载 时,不会自动为交换分区启用丢弃。
有关何时丢弃交换空间的讨论,请参阅 swapon(8):discard=once
或 discard=pages
。如果指定了 discard
但未指定特定模式,则默认情况下启用两者。
最大化性能
按照提升性能#存储设备中的提示来最大化驱动器的性能。
SSD 内存单元清除
有时,用户可能希望将 SSD 的单元完全重置为设备安装时的原始状态,从而将其恢复到出厂默认写入性能。已知即使在使用本机 TRIM 支持的 SSD 上,写入性能也会随着时间的推移而降低:TRIM 仅防止文件删除,而不是替换(例如增量保存)。
可以通过遵循 固态硬盘/内存单元清除 中指示的相应程序来完成重置,无论是对于 SATA 还是 NVMe SSD。
安全
冻结模式
某些主板固件在初始化时向 SATA 设备发出 ATA SECURITY FREEZE LOCK 命令,将驱动器设置为冻结模式,这将驱动器转换为 SEC2 状态(安全禁用、未锁定、冻结)。同样,某些 SSD(和 HDD)在出厂时已设置为此状态。这可以在 hdparm 和 smartctl 输出中看到
# hdparm -I /dev/sda
Security: Master password revision code = 65534 supported not enabled not locked frozen not expired: security count supported: enhanced erase 4min for SECURITY ERASE UNIT. 2min for ENHANCED SECURITY ERASE UNIT.
# smartctl -g security /dev/sda
ATA Security is: Disabled, frozen [SEC2]
格式化设备或安装操作系统等操作不受冻结模式的影响。
上面的 hdparm 输出显示设备在启动时未被锁定 HDD 密码,并且冻结状态保护设备免受可能尝试通过在运行时设置密码来锁定它的恶意软件的侵害。
如果您打算自己为“冻结”设备设置密码,则需要支持它的主板 BIOS。许多笔记本电脑都支持,因为这是硬件加密所必需的,但对于台式机/服务器主板来说,支持可能并非易事。例如,对于 Intel DH67CL/BL 主板,必须通过物理跳线将主板设置为“维护模式”才能访问设置。[10]
如果您打算擦除 SSD,请参阅 安全擦除磁盘#hdparm 和 /内存单元清除。
从睡眠状态唤醒后将 SATA SSD 状态设置为冻结模式
从 S3 睡眠状态唤醒时,SATA SSD 很可能已恢复为 SEC1 状态(安全禁用、未锁定、未冻结),使其容易受到 ATA SECURITY ERASE UNIT 命令的攻击,例如 /内存单元清除 中描述的命令。
为了防止此问题,可以在从睡眠状态唤醒后运行脚本
/usr/lib/systemd/system-sleep/ssd-freeze.sh
#!/bin/sh if [ "$1" = 'post' ]; then sleep 1 if hdparm --security-freeze /dev/disk/by-id/ata-name-of-disk; then logger "$0: SSD freeze command executed successfully" else logger "$0: SSD freeze command failed" fi fi
如果系统有多个存储设备和/或便携式 USB 驱动器,另一种选择是调整 Hdparm#使用 udev 规则持久配置 以对所有驱动器(包括 HDD)发出 --security-freeze
。
硬件加密
如#冻结模式中所述,在 BIOS 中为存储设备(SSD/HDD)设置密码也可能会初始化支持它的设备的硬件加密。如果设备也符合 OPAL 标准,则即使没有相应的 BIOS 功能来设置密码,也可以实现此目的。请参阅 自加密驱动器。
故障排除
您遇到的问题可能是非 Linux 特定的固件错误,因此在尝试对影响 SSD 设备的问题进行故障排除之前,您应首先检查是否有以下更新可用
即使是固件错误,也可能可以避免它,因此如果没有固件更新或者您对更新固件犹豫不决,则以下方法可能会有所帮助。
解决 NCQ 错误
某些 SSD 和 SATA 芯片组无法与 Linux 本地命令队列 (NCQ) 正常工作。日志中的明显错误如下所示
ata9: exception Emask 0x0 SAct 0xf SErr 0x0 action 0x10 frozen ata9.00: failed command: READ FPDMA QUEUED ata9.00: cmd 60/04:00:d4:82:85/00:00:1f:00:00/40 tag 0 ncq 2048 in res 40/00:18:d3:82:85/00:00:1f:00:00/40 Emask 0x4 (timeout)
要在启动时禁用 NCQ,请将 libata.force=noncq
添加到 引导加载程序 配置文件中的内核命令行。要仅对端口 9 上的磁盘 0 禁用 NCQ,请使用:libata.force=9.00:noncq
或者,您也可以通过 sysfs 为特定驱动器禁用 NCQ,而无需重启
# echo 1 > /sys/block/sdX/device/queue_depth
如果这(以及更新固件)无法解决问题或导致其他问题,请提交错误报告。
当启用 SATA 主动链路电源管理 (ALPM) 时,某些 SSD(例如 Transcend MTS400 或 Crucial M550 SSD)在使用某些 SATA 控制器时会发生故障。
ALPM 自 linux-4.16 起默认启用,或者可以通过省电守护程序(例如 TLP、Laptop Mode Tools)在运行时启用。有关更多信息,请参阅 电源管理#SATA 主动链路电源管理。
支持 TRIM 的外部 SSD
几个 USB 到 SATA 桥接芯片(例如 VL715、VL716 等)以及 USB 到 PCIe 桥接芯片(例如 JMicron JMS583,用于外部 NVMe 外壳,例如 IB-1817M-C31)支持可以通过 USB 连接 SCSI 驱动程序(在 Linux 下名为“uas”)发送的类似 TRIM 的命令。
但是内核可能无法自动检测到此功能,因此可能不会使用它。假设您有问题的块设备是 /dev/sdX,您可以使用 sg3_utils 中的命令来找出是否是这种情况
# sg_readcap -l /dev/sdX
如果在其输出中找到一行说明“Logical block provisioning: lbpme=0”,那么您就知道内核假定设备不支持“逻辑块配置管理”,因为未设置 (LBPME) 位。
如果是这种情况,那么您接下来应该找出设备的 “重要产品数据”(VPD) 页面上的“逻辑块配置” 是否说明了用于取消映射数据的支持机制。您可以使用以下命令执行此操作
# sg_vpd -a /dev/sdX
在输出中查找如下所示的行
Unmap command supported (LBPU): 1 Write same (16) with unmap bit supported (LBPWS): 0 Write same (10) with unmap bit supported (LBPWS10): 0
此示例将告诉您设备支持“UNMAP”命令。
查看以下输出
$ cat /sys/block/sdX/device/scsi_disk/*/provisioning_mode
如果内核未检测到您的设备取消映射数据的功能,则这很可能会返回“full”。除了“full”之外,内核 SCSI 存储驱动程序当前知道 provisioning_mode 的以下值
unmap writesame_16 writesame_10 writesame_zero disabled
对于上面的示例,您现在可以写入“unmap”到“provisioning_mode”,以请求内核使用它
# echo "unmap" >/sys/block/sdX/device/scsi_disk/*/provisioning_mode
这应立即使您能够在 /dev/sdX 上使用诸如“blkdiscard”之类的工具或在挂载在 /dev/sdX 上的文件系统上使用“fstrim”。
如果您想在连接特定供应商/产品的外部设备时自动启用“provisioning_mode”,则可以通过“udev”机制实现自动化。首先找到 USB 供应商和产品 ID
$ cat /sys/block/sdX/../../../../../../idVendor $ cat /sys/block/sdX/../../../../../../idProduct
然后创建或附加到 udev 规则文件(此处示例使用 idVendor 152d 和 idProduct 0583)
# echo 'ACTION=="add|change", ATTRS{idVendor}=="152d", ATTRS{idProduct}=="0583", SUBSYSTEM=="scsi_disk", ATTR{provisioning_mode}="unmap"' >>/etc/udev/rules.d/10-uas-discard.rules
(您也可以使用 lsusb
命令查找相关的 idVendor/idProduct。)
固件
如果设备供应商支持,建议使用 fwupd 实用程序更新固件。
要检查您当前的固件版本
# smartctl -i /dev/ssd_device
ADATA
ADATA 不支持在 Linux 下更新 SSD 固件。ADATA 通过其 支持页面 和 ADATA XPG 支持页面 提供了一个名为 SSD ToolBox 的 Windows 专用实用程序,用于监视、TRIM、基准测试和更新 ADATA SSD 固件。
Crucial
Crucial 提供了一个使用 ISO 映像更新固件的选项。在他们的 SSD 支持页面 上选择产品并下载“手动启动文件”后,可以找到这些映像。
dd
命令将映像复制到某些设备,则 MBR 将不存在,从而使此类设备无法启动。安装 syslinux 并运行 isohybrid path/to/image.iso
。M4 Crucial 型号的所有者可以使用 smartctl
检查是否需要固件升级。
$ smartctl --all /dev/sdX
==> WARNING: This drive may hang after 5184 hours of power-on time: https://www.tomshardware.com/news/Crucial-m4-Firmware-BSOD,14544.html See the following web page for firmware updates: https://www.crucial.com/usa/en/support-ssd
建议看到此警告的用户备份所有敏感数据并考虑立即升级。查看 此说明,以使用 ISO 映像和 Grub 更新 Crucial MX100 固件。
Intel
Intel 具有基于 Linux 实时系统的 固件更新工具,适用于与其 Windows Intel® 内存和存储工具 (GUI) 软件不兼容的操作系统。
还有一个较新的 Linux 命令行实用程序可以重新刷新固件,称为 Intel 内存和存储 (MAS) 工具,可作为 intel-mas-cli-toolAUR 提供。有一个 PDF 用户指南 可用。
检查固件状态的一个示例是
# intelmas show -intelssd 0
DevicePath : /dev/nvme0n1 DeviceStatus : Healthy Firmware : 002C FirmwareUpdateAvailable : The selected Intel SSD contains current firmware as of this tool release.
如果系统中只有一个 Intel SSD,则可以省略 -intelssd 0
,或者为第二个 SSD 传递 1
,依此类推。
如果有更新可用,则通过运行 intelmas load -intelssd 0
来执行更新。PDF 用户指南建议此过程需要在 Linux 中执行两次,中间进行一次断电重启。所有设备的最新固件都作为 MAS 工具本身的一部分分发,因此无需单独下载。
Kingston
KFU 工具适用于基于 Sandforce 的驱动器,kingston_fw_updaterAUR。
Mushkin
鲜为人知的 Mushkin 品牌固态硬盘也使用 Sandforce 控制器,并具有一个 Linux 实用程序(与 Kingston 的几乎相同)来更新固件。
OCZ
OCZ 有一个适用于 Linux 的 命令行在线更新工具 (CLOUT)。现有的软件包是 ocz-ssd-utilityAUR、ocztoolboxAUR 和 oczcloutAUR。
Samsung
尽管 Samsung 认为在其 Magician 软件之外的固件更新方法“不受支持”,但它们仍然可以工作。Magician 软件可以创建包含固件更新的可启动 USB 驱动器,但是 Samsung 不再为消费级 SSD 提供该软件。Samsung 还提供了预制的可启动 ISO 映像,可用于更新固件。另一种选择是使用 samsung_magician-consumer-ssdAUR 提供的 Samsung magician 实用程序。Magician 仅支持 Samsung 品牌的 SSD;Samsung 为 OEM(例如 Lenovo)制造的 SSD 不受支持。
喜欢从 Linux 下创建的实时 USB(不使用 Microsoft Windows 下的 Samsung Magician 软件)运行固件更新的用户可以参考 [11] 以获取更多详细信息。请注意,此博客文章详细介绍了创建带有主启动记录 (MBR) 的可启动 USB 驱动器,某些较新的主板(例如 Intel NUC)不再支持。
在 Linux 下更新
SSD 固件可以本地更新(无需制作可启动 USB 驱动器),如下所示。首先访问 Samsung 下载页面,转到“Samsung SSD Firmware”部分,然后下载适用于您的 SSD 的最新固件——它应该是 ISO 映像。
initrd
Linux 映像。请改为参阅#较旧的 SSD。从 ISO 映像中提取 initrd
Linux 映像
$ bsdtar xf samsung_ssd_firmware.iso initrd
提取 root/fumagician/
。此目录包含固件更新文件
$ bsdtar xf initrd root/fumagician
最后,以 root 权限运行 root/fumagician/fumagician
并重启您的系统(如果固件已成功更新)。
如果在重启后固件版本未更改,请运行 root/fumagician/fumagician 2> log
并在日志文件中搜索错误。例如,如果日志显示“unzip is not available”,请安装 unzip 或从 initrd 中提取它。
较旧的 SSD
某些 SSD 固件 ISO 映像包含 FreeDOS 映像而不是 initrd
Linux 映像,因此更新 SSD 固件所需的步骤与上述步骤不同。下表列出了这些 SSD(和相关路径)
SSD 型号 | FreeDOS 映像路径 | 固件包路径 |
---|---|---|
470, 830 | BTDSK.IMG |
SSR/
|
840 | isolinux/btdsk.img |
samsung/DSRD/
|
840 EVO (mSATA), Pro | ISOLINUX/BTDSK.IMG
|
首先,从 ISO 映像中提取 FreeDOS 映像
$ bsdtar xf samsung_ssd_firmware.iso freedos_image_path
将 FreeDOS 映像挂载到 /mnt/
# mount freedos_image_path /mnt
从 Magician SSD 管理实用程序的磁盘编号下获取 SSD 的磁盘号
# magician --list
通过提供固件包路径,更新指定磁盘的 SSD 固件
# magician --disk disk_num --firmware-update --fwpackage-path /mnt/firmware_package_path
最后,通过检查 magician --list
(使用 root 权限)输出中的固件下的版本,验证固件是否成功更新。如果已成功更新,请重启系统。
SanDisk
SanDisk 制作 ISO 固件镜像,以便在 SanDisk SSD Toolkit 不支持的操作系统上更新 SSD 固件。
必须为正确的SSD 型号和正确的容量(例如 60GB或 256GB)选择固件。刻录 ISO 固件镜像后,只需重启电脑以使用新创建的 CD/DVD 启动盘启动(可能也可以从 USB 闪存盘启动)。
iso 镜像仅包含 linux 内核和 initrd。将它们解压到 /boot
分区,并使用 GRUB 或 Syslinux 启动它们以更新固件。
另请参阅
- SanDisk Extreme SSD 手动固件更新版本 R211
- SanDisk Ultra SSD 手动固件更新版本 365A13F0
- SanDisk Ultra+ SSD 手动固件更新版本 X2316RL - 使用
smartctl -i dev/disk/by-id/*SanDisk!(*part*)
以 root 权限确定是否使用了 "H2" 或 "HP" 型号。