固态硬盘

来自 ArchWiki
(重定向自 固态硬盘

本文涵盖了操作固态硬盘 (SSD) 和其他基于闪存的存储设备的特殊主题。

如果您想为特定用途分区 SSD,则考虑针对闪存优化的文件系统列表可能会很有用。

对于一般用途,只需选择您偏好的文件系统并启用#TRIM

用法

TRIM

与硬盘驱动器相比,删除文件仅在文件系统级别处理[1],而 SSD 受益于在内存块空闲可重复使用时通知磁盘控制器。由于构成它们的闪存单元在每次写入操作时都会磨损一点,因此磁盘控制器使用算法来共享所有单元上的写入操作:此过程称为磨损均衡。如果没有 NVMe DEALLOCATE、SAS UNMAPATA_TRIM 命令(大多数 SSD 支持),一旦没有空内存块,磁盘控制器就需要更多时间来执行写入操作,因为它必须重新排列数据以在写入单元之前擦除单元(请参阅维基百科:写入放大):TechSpot 基准测试显示了用数据填充 SSD 前后的性能影响。

注意: 如果您想使用 TRIM,请使用定期 TRIM 或连续 TRIM 之一。 连续 TRIM 不是 Linux 社区中最推荐的发出 TRIM 命令的方式。 例如,Ubuntu 默认启用定期 TRIM [2],Debian 不建议使用连续 TRIM,Red Hat 建议在可行的情况下使用定期 TRIM 而不是连续 TRIM [3]

自 Linux 内核版本 3.8 起,不同的文件系统不断添加了对 TRIM 的支持。 请参阅下表以获得指示性概述

文件系统 连续 TRIM
discard 选项)
定期 TRIM
fstrim
参考
和注释
Bcachefs
Btrfs 自内核 6.2 起,异步 discard 默认启用
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]
Swap 从技术上讲不是“文件系统”,但 TRIM 仍然相关。“once”选项提供启动时计划的 trim。请参阅 swapon(8)
警告: 用户需要确定他们的 SSD 支持 TRIM,然后再尝试使用它。 否则可能会发生数据丢失!

要验证 TRIM 支持,请运行

$ lsblk --discard

并检查 DISC-GRAN(丢弃粒度)和 DISC-MAX(丢弃最大字节数)列的值。 非零值表示支持 TRIM。

对于仅 SATA SSD,hdparm 软件包可以检测 TRIM 支持,方法是作为root 用户运行 hdparm -I /dev/sda | grep TRIM。 但是 hdparm 不支持 NVMe SSD。

定期 TRIM

util-linux 软件包提供了 fstrim.servicefstrim.timer systemd 单元文件。 启用计时器将每周激活该服务。 该服务在支持 discard 操作的设备上对所有已挂载的文件系统执行 fstrim(8)

计时器依赖于 /var/lib/systemd/timers/stamp-fstrim.timer 的时间戳(它将在首次调用时创建)来了解自上次运行以来是否已过去一周。 因此,无需担心像 anacron 一样过于频繁的调用。

要查询单元的活动和状态,请参阅 journalctl。 要更改计时器的周期或运行的命令,请编辑提供的单元文件。

连续 TRIM

除了偶尔发出 TRIM 命令(如果使用 fstrim.timer,则默认为每周一次)之外,还可以选择在每次删除文件时发出 TRIM 命令。 后者称为连续 TRIM。

警告:SATA 3.1 之前,所有 TRIM 命令都是非队列的,因此连续 trim 会导致频繁的系统冻结。 在这种情况下,较少应用的#定期 TRIM是更好的选择。 许多设备也存在类似的问题,请参阅 Linux 源代码中带有 ATA_QUIRK_NO_NCQ_TRIM__ata_dev_quirks 条目,由于严重的数据损坏,队列 TRIM 命令执行已被列入黑名单。 在这种情况下,根据设备的不同,系统可能会被迫向 SSD 发送非队列 TRIM 命令,而不是队列 TRIM。 有关详细信息,请参阅 维基百科:Trim_(computing)#缺点

/etc/fstab 中为挂载使用 discard 选项可在设备操作中启用连续 TRIM

/dev/sda1  /           ext4  defaults,discard   0  1
注意:/etc/fstab 中指定 discard 挂载选项不适用于 XFS / 分区。 根据此主题,必须使用 rootflags=discard 内核参数进行设置。

在 ext4 文件系统上,也可以使用 tune2fsdiscard 标志设置为默认挂载选项

# tune2fs -o discard /dev/sdXY

使用默认挂载选项而不是 /etc/fstab 中的条目对于外部驱动器尤其有用,因为这样的分区也将在其他机器上使用默认选项挂载。 这样,无需在每台机器上编辑 /etc/fstab

注意: 默认挂载选项未在 /proc/mounts 中列出。

Trim 整个设备

如果您想一次性 trim 整个 SSD,例如 用于全新安装,或者如果您想出售驱动器,则可以使用 blkdiscard 命令。

LVM

从文件系统传递到逻辑卷的 TRIM 请求会自动传递到物理卷。 无需额外的配置。

默认情况下,没有 LVM 操作(lvremovelvreduce 和所有其他操作)向物理卷发出 TRIM 请求。 这样做是为了允许使用 vgcfgrestore(8) 恢复以前的卷组配置。 /etc/lvm/lvm.conf 中的设置 issue_discards 控制在逻辑卷不再使用物理卷空间时,是否将 discard 发送到逻辑卷的底层物理卷。

注意: 在更改 issue_discards 设置之前,请仔细阅读 /etc/lvm/lvm.conf 中的注释。 它不会以任何方式影响从文件系统传递到磁盘的 TRIM 请求(例如,文件系统内部的文件删除),也不会影响精简池内的空间管理。
警告: 启用 issue_discards 将阻止使用 vgcfgrestore 恢复卷组元数据。 如果错误地发出 LVM 命令,将没有恢复选项。

dm-crypt

警告: dm-crypt 支持将 discard 请求传递到底层块设备。 这可能会也可能不会提高 SSD 存储的性能[9],但具有安全隐患,因此默认情况下未启用。

按照 dm-crypt/Specialties#固态硬盘 (SSD) 的 Discard/TRIM 支持 中的说明为 LUKS 和纯 dm-crypt 设备启用 discard 支持。

swap

要为交换空间启用 discard,请将 discard 选项添加到 fstab 中交换设备的条目,或者在调用 swapon 时传递 --discard

当使用 Systemd#GPT 分区自动挂载时,不会自动为交换分区启用 Discard。

有关何时丢弃交换的讨论,请参阅 swapon(8)discard=oncediscard=pages。 如果指定了 discard 但没有特定模式,则默认情况下启用两者。

警告: 如果使用 swapon,在 RAID 设置上使用 mdadm 启用 discard 将导致系统在启动和运行时锁定。

最大化性能

按照提高性能#存储设备中的提示来最大化驱动器的性能。

SSD 内存单元清除

有时,用户可能希望将 SSD 的单元完全重置为设备安装时的原始状态,从而将其恢复到出厂默认写入性能。 即使在使用原生 TRIM 支持的 SSD 上,写入性能也会随着时间的推移而降低:TRIM 仅防止文件删除,而不是替换,例如增量保存。

可以通过遵循 固态硬盘/内存单元清除 中指示的相应过程来完成重置,无论是针对 SATA 还是 NVMe SSD。

注意: 如果重置的原因是为了擦除数据,您可能不想依赖 SSD 控制器来安全地执行此操作,例如,如果您不信任制造商或担心潜在的错误。 在这种情况下,请参阅 安全擦除磁盘#闪存 以获取更多信息和执行手动擦除的示例。

安全

冻结模式

某些主板固件在初始化时向 SATA 设备发出 ATA SECURITY FREEZE LOCK 命令,将驱动器设置为冻结模式,这会将其转换为 SEC2 状态(安全已禁用,未锁定,已冻结)。 同样,某些 SSD(和 HDD)在出厂时已设置为此状态。 这可以在 hdparmsmartctl 输出中看到

# 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]

警告: 除非您确切知道自己在做什么,否则不要尝试使用 hdparm 更改上述锁定安全设置。

如果您打算擦除 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 电源管理相关错误

某些 SSD(例如 Transcend MTS400 或 Crucial M550 SSD)在使用某些 SATA 控制器时会发生故障,当SATA 主动链路电源管理 (ALPM) 启用时。

ALPM 自 linux-4.16 起默认启用,或者可以通过省电守护程序(例如 TLPLaptop Mode Tools)在运行时启用。 有关更多信息,请参阅 电源管理#SATA 主动链路电源管理

支持 TRIM 的外部 SSD

本文或章节需要语言、wiki 语法或样式改进。 请参阅 Help:Style 以供参考。

原因: 多个样式和格式问题,特别是显式命令过多 - 请参阅 Help:Style#文件编辑请求。 (在 Talk:Solid state drive 中讨论)

几个 USB-to-SATA 桥接芯片(如 VL715、VL716 等)以及 USB-to-PCIe 桥接芯片(如 JMicron JMS583,用于外部 NVMe enclosures 中,如 IB-1817M-C31)支持 TRIM 类命令,这些命令可以通过 USB Attached SCSI 驱动程序(在 Linux 下名为 "uas")发送。

但是内核可能无法自动检测到此功能,因此可能不会使用它。 假设您有问题的块设备是 /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 固件。

警告: 不建议尝试通过 Wine 更新固件,因为它并非设计用于处理硬件接口,并且不完整的固件更新可能会损坏您的设备。

Crucial

Crucial 提供了一个使用 ISO 镜像更新固件的选项。 这些镜像可以在他们的 SSD 支持页面上选择产品并下载“Manual Boot File”后找到。

注意: Crucial 提供的 ISO 镜像似乎不是混合镜像。 如果您仅使用 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 Live 系统的固件更新工具,适用于与其 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 提供了一个 命令行在线更新工具 (CLOUT),可用于 Linux。现有的软件包包括 ocz-ssd-utilityAURocztoolboxAURoczcloutAUR

三星 (Samsung)

尽管三星认为在其 Magician 软件之外的固件更新方法是“不受支持的”,但它们仍然可以工作。Magician 软件可以创建包含固件更新的可启动 USB 驱动器,但三星已不再为消费级 SSD 提供该软件。三星还提供了预制的 可启动 ISO 镜像,可用于更新固件。另一种选择是使用 samsung_magician-consumer-ssdAUR 提供的三星 magician 实用程序。Magician 仅支持三星品牌的 SSD;三星为 OEM(例如联想)制造的 SSD 不受支持。

注意: 三星并没有明确说明他们实际上提供了这些工具。他们似乎有 4 个不同的固件更新页面,每个页面都提到了不同的操作方法。

喜欢从 Linux 下创建的 Live USB(不使用 Microsoft Windows 下的三星 Magician 软件)运行固件更新的用户可以参考 [11] 获取更多详细信息。请注意,这篇博文详细介绍了使用主引导记录 (MBR) 创建可启动 USB 驱动器,但一些较新的主板,例如 Intel NUC 已不再支持 MBR。

在 Linux 下更新

SSD 固件可以在本地更新(无需制作可启动 USB 驱动器),如下所示。首先访问 三星下载页面,转到“Samsung SSD Firmware”部分,下载适用于您 SSD 的最新固件——它应该是一个 ISO 镜像。

注意: 某些 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)

闪迪制作 ISO 固件镜像,以允许在其 SanDisk SSD Toolkit 不支持的操作系统上更新 SSD 固件。

必须为正确的 SSD 型号正确的容量(例如 60GB, 256GB)选择固件。刻录 ISO 固件镜像后,只需重启 PC 以使用新创建的 CD/DVD 启动盘(可能从 USB 闪存盘启动)启动。

ISO 镜像仅包含 Linux 内核和 initrd。将它们提取到 /boot 分区,并使用 GRUBSyslinux 引导它们以更新固件。

另请参阅

另请参阅