# 20.4.USB 存储设备

许多外部存储解决方案，如硬盘、USB 闪存驱动器、光盘和 DVD 刻录机，都使用通用串行总线（USB）。FreeBSD 支持 USB 1.x、2.0 和 3.0 设备。

> **注意**
>
> USB 3.0 支持与某些硬件不兼容，包括 Haswell（Lynx point）芯片组。如果 FreeBSD 启动时出现 `failed with error 19` 消息，请在系统 BIOS 中禁用 xHCI/USB3。

USB 存储设备的支持已经内建在 **GENERIC** 内核中。对于自定义内核，请确保在内核配置文件中包含以下行：

```sh
device scbus	# SCSI 总线（ATA/SCSI 必需）
device da	# 直接访问（磁盘）
device pass	# 透传设备（直接 ATA/SCSI 访问）
device uhci	# 提供 USB 1.x 支持
device ohci	# 提供 USB 1.x 支持
device ehci	# 提供 USB 2.0 支持
device xhci	# 提供 USB 3.0 支持
device usb	# USB 总线（必需）
device umass	# 磁盘/大容量存储 - 需要 scbus 和 da
device cd	# 需要用于 CD 和 DVD 刻录机
```

FreeBSD 使用 [umass(4)](https://man.freebsd.org/cgi/man.cgi?query=umass\&sektion=4\&format=html) 驱动程序，通过 SCSI 子系统访问 USB 存储设备。由于任何 USB 设备都会被系统视为 SCSI 设备，因此如果 USB 设备是 CD 或 DVD 刻录机，*不要* 在自定义内核配置文件中包含 `device atapicam`。

本节的其余部分演示了如何验证 USB 存储设备是否被 FreeBSD 识别，并如何配置该设备以便使用。

## 20.4.1. 设备配置

要测试 USB 配置，插入 USB 设备。使用 `dmesg` 确认驱动器是否出现在系统消息缓冲区中。它应类似如下所示：

```sh
umass0: <STECH Simple Drive, class 0/0, rev 2.00/1.04, addr 3> on usbus0
umass0:  SCSI over Bulk-Only; quirks = 0x0100
umass0:4:0:-1: Attached to scbus4
da0 at umass-sim0 bus 0 scbus4 target 0 lun 0
da0: <STECH Simple Drive 1.04> Fixed Direct Access SCSI-4 device
da0: Serial Number WD-WXE508CAN263
da0: 40.000MB/s transfers
da0: 152627MB (312581808 512 byte sectors: 255H 63S/T 19457C)
da0: quirks=0x2<NO_6_BYTE>
```

品牌、设备节点（**da0**）、速度和大小会根据设备不同而有所不同。

由于 USB 设备被视为 SCSI 设备，因此可以使用 `camcontrol` 列出连接到系统的 USB 存储设备：

```sh
# camcontrol devlist
<STECH Simple Drive 1.04>          at scbus4 target 0 lun 0 (pass3,da0)
```

或者，可以使用 `usbconfig` 列出设备。有关此命令的更多信息，请参考 [usbconfig(8)](https://man.freebsd.org/cgi/man.cgi?query=usbconfig\&sektion=8\&format=html)。

```sh
# usbconfig
ugen0.3: <Simple Drive STECH> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (2mA)
```

如果设备尚未格式化，请参考 [添加磁盘](https://docs.freebsd.org/en/books/handbook/disks/#disks-adding) 了解如何格式化并创建 USB 驱动器上的分区。如果驱动器已包含文件系统，可以按照 [“挂载和卸载文件系统”](https://docs.freebsd.org/en/books/handbook/basics/#mount-unmount) 中的说明进行挂载。

> **警告**
>
> 让不可信的用户挂载任意媒体（如下面所述启用 `vfs.usermount`）从安全角度来看是不安全的。大多数文件系统并未为防范恶意设备而构建。

为了使设备能够作为普通用户挂载，一种解决方案是将所有使用该设备的用户添加到 `operator` 组中，使用 [pw(8)](https://man.freebsd.org/cgi/man.cgi?query=pw\&sektion=8\&format=html)。接下来，确保 `operator` 组能够读写设备，可以在 **/etc/devfs.rules** 中添加以下行：

```sh
[localrules=5]
add path 'da*' mode 0660 group operator
```

> **注意**
>
> 如果系统中还安装了内置 SCSI 磁盘，请将第二行修改如下：
>
> ```sh
> add path 'da[3-9]*' mode 0660 group operator
> ```
>
> 这将把前三个 SCSI 磁盘（**da0** 到 **da2**）排除出 `operator` 组。请将 *3* 替换为内置 SCSI 磁盘的数量。有关此文件的更多信息，请参考 [devfs.rules(5)](https://man.freebsd.org/cgi/man.cgi?query=devfs.rules\&sektion=5\&format=html)。

接下来，在 **/etc/rc.conf** 中启用规则集：

```sh
devfs_system_ruleset="localrules"
```

然后，通过在 **/etc/sysctl.conf** 中添加以下行，指示系统允许普通用户挂载文件系统：

```sh
vfs.usermount=1
```

由于此设置只在下次重启后生效，可以立即使用 `sysctl` 设置此变量：

```sh
# sysctl vfs.usermount=1
vfs.usermount: 0 -> 1
```

最后一步是创建一个目录，在该目录下挂载文件系统。此目录需要由将要挂载文件系统的用户拥有。可以通过 `root` 创建一个由该用户拥有的子目录，如 **/mnt/username**。在以下示例中，将 *username* 替换为用户的登录名，将 *usergroup* 替换为用户的主组：

```sh
# mkdir /mnt/username
# chown username:usergroup /mnt/username
```

假设插入了一根 USB 闪存驱动器，出现了设备 **/dev/da0s1**。如果该设备格式化为 FAT 文件系统，用户可以使用以下命令进行挂载：

```sh
% mount -t msdosfs -o -m=644,-M=755 /dev/da0s1 /mnt/username
```

在设备被拔出之前，必须首先卸载它：

```sh
% umount /mnt/username
```

拔出设备后，系统消息缓冲区将显示类似以下内容的消息：

```sh
umass0: at uhub3, port 2, addr 3 (disconnected)
da0 at umass-sim0 bus 0 scbus4 target 0 lun 0
da0: <STECH Simple Drive 1.04> s/n WD-WXE508CAN263          detached
(da0:umass-sim0:0:0:0): Periph destroyed
```

## 20.4.2. 自动挂载可移动媒体

USB 设备可以通过取消注释 **/etc/auto\_master** 中的这一行来自动挂载：

```sh
/media		-media		-nosuid
```

然后，将以下内容添加到 **/etc/devd.conf** 文件中：

```
notify 100 {
	match "system" "GEOM";
	match "subsystem" "DEV";
	action "/usr/sbin/automount -c";
};
```

如果 [autofs(5)](https://man.freebsd.org/cgi/man.cgi?query=autofs\&sektion=4\&format=html) 和 [devd(8)](https://man.freebsd.org/cgi/man.cgi?query=devd\&sektion=8\&format=html) 已经在运行，则重新加载配置：

```sh
# service automount restart
# service devd restart
```

通过将以下行添加到 **/etc/rc.conf** 文件中，可以设置 [autofs(5)](https://man.freebsd.org/cgi/man.cgi?query=autofs\&sektion=4\&format=html) 在启动时启动：

```sh
autofs_enable="YES"
```

[autofs(5)](https://man.freebsd.org/cgi/man.cgi?query=autofs\&sektion=4\&format=html) 需要启用 [devd(8)](https://man.freebsd.org/cgi/man.cgi?query=devd\&sektion=8\&format=html)，默认情况下已启用。

立即启动服务：

```sh
# service automount start
# service automountd start
# service autounmountd start
# service devd start
```

每个可以自动挂载的文件系统都会作为 **/media/** 下的一个目录出现。该目录的名称是文件系统标签。如果标签缺失，目录名称将以设备节点命名。

文件系统会在首次访问时自动挂载，并在一段时间的非活动后自动卸载。自动挂载的驱动器也可以手动卸载：

```sh
# automount -fu
```

该机制通常用于内存卡和 USB 闪存驱动器。它也可以用于任何块设备，包括光驱或 iSCSILUN。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/hanbook/di-20-zhang-cun-chu/20.4.-usb-cun-chu-she-bei.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
